ember-source 1.0.0.rc6.2 → 1.0.0.rc6.4

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.

Potentially problematic release.


This version of ember-source might be problematic. Click here for more details.

@@ -1,7 +1,7 @@
1
1
  (function() {
2
2
  var Ember = { assert: function() {} };
3
- // Version: v1.0.0-rc.6-56-g19271bc
4
- // Last commit: 19271bc (2013-06-30 23:18:40 -0700)
3
+ // Version: v1.0.0-rc.6-221-g9d051c2
4
+ // Last commit: 9d051c2 (2013-07-28 23:13:59 -0700)
5
5
 
6
6
 
7
7
  (function() {
@@ -1,5 +1,5 @@
1
- // Version: v1.0.0-rc.6-56-g19271bc
2
- // Last commit: 19271bc (2013-06-30 23:18:40 -0700)
1
+ // Version: v1.0.0-rc.6-221-g9d051c2
2
+ // Last commit: 9d051c2 (2013-07-28 23:13:59 -0700)
3
3
 
4
4
 
5
5
  (function() {
@@ -156,8 +156,8 @@ Ember.deprecateFunc = function(message, func) {
156
156
 
157
157
  })();
158
158
 
159
- // Version: v1.0.0-rc.6-56-g19271bc
160
- // Last commit: 19271bc (2013-06-30 23:18:40 -0700)
159
+ // Version: v1.0.0-rc.6-221-g9d051c2
160
+ // Last commit: 9d051c2 (2013-07-28 23:13:59 -0700)
161
161
 
162
162
 
163
163
  (function() {
@@ -251,10 +251,10 @@ Ember.toString = function() { return "Ember"; };
251
251
  /**
252
252
  @property VERSION
253
253
  @type String
254
- @default '1.0.0-rc.6'
254
+ @default '1.0.0-rc.6.1'
255
255
  @final
256
256
  */
257
- Ember.VERSION = '1.0.0-rc.6';
257
+ Ember.VERSION = '1.0.0-rc.6.1';
258
258
 
259
259
  /**
260
260
  Standard environmental variables. You can define these in a global `ENV`
@@ -354,16 +354,19 @@ Ember.uuid = 0;
354
354
  //
355
355
 
356
356
  function consoleMethod(name) {
357
- if (imports.console && imports.console[name]) {
357
+ var console = imports.console,
358
+ method = typeof console === 'object' ? console[name] : null;
359
+
360
+ if (method) {
358
361
  // Older IE doesn't support apply, but Chrome needs it
359
- if (imports.console[name].apply) {
362
+ if (method.apply) {
360
363
  return function() {
361
- imports.console[name].apply(imports.console, arguments);
364
+ method.apply(console, arguments);
362
365
  };
363
366
  } else {
364
367
  return function() {
365
368
  var message = Array.prototype.join.call(arguments, ', ');
366
- imports.console[name](message);
369
+ method(message);
367
370
  };
368
371
  }
369
372
  }
@@ -375,7 +378,7 @@ function assertPolyfill(test, message) {
375
378
  // attempt to preserve the stack
376
379
  throw new Error("assertion failed: " + message);
377
380
  } catch(error) {
378
- setTimeout(function(){
381
+ setTimeout(function() {
379
382
  throw error;
380
383
  }, 0);
381
384
  }
@@ -457,7 +460,7 @@ Ember.merge = function(original, updates) {
457
460
  Ember.isNone(undefined); // true
458
461
  Ember.isNone(''); // false
459
462
  Ember.isNone([]); // false
460
- Ember.isNone(function(){}); // false
463
+ Ember.isNone(function() {}); // false
461
464
  ```
462
465
 
463
466
  @method isNone
@@ -562,7 +565,7 @@ var canRedefineProperties, canDefinePropertyOnDOM;
562
565
  // Catch IE8 where Object.defineProperty exists but only works on DOM elements
563
566
  if (defineProperty) {
564
567
  try {
565
- defineProperty({}, 'a',{get:function(){}});
568
+ defineProperty({}, 'a',{get:function() {}});
566
569
  } catch (e) {
567
570
  defineProperty = null;
568
571
  }
@@ -593,7 +596,7 @@ if (defineProperty) {
593
596
 
594
597
  // This is for Safari 5.0, which supports Object.defineProperty, but not
595
598
  // on DOM nodes.
596
- canDefinePropertyOnDOM = (function(){
599
+ canDefinePropertyOnDOM = (function() {
597
600
  try {
598
601
  defineProperty(document.createElement('div'), 'definePropertyOnDOM', {});
599
602
  return true;
@@ -605,7 +608,7 @@ if (defineProperty) {
605
608
  if (!canRedefineProperties) {
606
609
  defineProperty = null;
607
610
  } else if (!canDefinePropertyOnDOM) {
608
- defineProperty = function(obj, keyName, desc){
611
+ defineProperty = function(obj, keyName, desc) {
609
612
  var isNode;
610
613
 
611
614
  if (typeof Node === "object") {
@@ -1215,7 +1218,7 @@ if (needsFinallyFix) {
1215
1218
  } finally {
1216
1219
  try {
1217
1220
  finalResult = finalizer.call(binding);
1218
- } catch (e){
1221
+ } catch (e) {
1219
1222
  finalError = e;
1220
1223
  }
1221
1224
  }
@@ -1267,7 +1270,7 @@ if (needsFinallyFix) {
1267
1270
  } finally {
1268
1271
  try {
1269
1272
  finalResult = finalizer.call(binding);
1270
- } catch (e){
1273
+ } catch (e) {
1271
1274
  finalError = e;
1272
1275
  }
1273
1276
  }
@@ -1466,7 +1469,7 @@ Ember.Instrumentation.instrument = function(name, payload, callback, binding) {
1466
1469
 
1467
1470
  var beforeValues = [], listener, i, l;
1468
1471
 
1469
- function tryable(){
1472
+ function tryable() {
1470
1473
  for (i=0, l=listeners.length; i<l; i++) {
1471
1474
  listener = listeners[i];
1472
1475
  beforeValues[i] = listener.before(name, time(), payload);
@@ -1475,7 +1478,7 @@ Ember.Instrumentation.instrument = function(name, payload, callback, binding) {
1475
1478
  return callback.call(binding);
1476
1479
  }
1477
1480
 
1478
- function catchable(e){
1481
+ function catchable(e) {
1479
1482
  payload = payload || {};
1480
1483
  payload.exception = e;
1481
1484
  }
@@ -1994,14 +1997,10 @@ function suspendListener(obj, eventName, target, method, callback) {
1994
1997
  /**
1995
1998
  @private
1996
1999
 
1997
- Suspend listener during callback.
1998
-
1999
- This should only be used by the target of the event listener
2000
- when it is taking an action that would cause the event, e.g.
2001
- an object might suspend its property change listener while it is
2002
- setting that property.
2000
+ Suspends multiple listeners during a callback.
2003
2001
 
2004
- @method suspendListener
2002
+
2003
+ @method suspendListeners
2005
2004
  @for Ember
2006
2005
  @param obj
2007
2006
  @param {Array} eventName Array of event names
@@ -2063,12 +2062,17 @@ function watchedEvents(obj) {
2063
2062
  }
2064
2063
 
2065
2064
  /**
2065
+ Send an event. The execution of suspended listeners
2066
+ is skipped, and once listeners are removed. A listener without
2067
+ a target is executed on the passed object. If an array of actions
2068
+ is not passed, the actions stored on the passed object are invoked.
2069
+
2066
2070
  @method sendEvent
2067
2071
  @for Ember
2068
2072
  @param obj
2069
2073
  @param {String} eventName
2070
- @param {Array} params
2071
- @param {Array} actions
2074
+ @param {Array} params Optional parameters for each listener.
2075
+ @param {Array} actions Optional array of actions (listeners).
2072
2076
  @return true
2073
2077
  */
2074
2078
  function sendEvent(obj, eventName, params, actions) {
@@ -2402,7 +2406,7 @@ var endPropertyChanges = Ember.endPropertyChanges = function() {
2402
2406
  @param {Function} callback
2403
2407
  @param [binding]
2404
2408
  */
2405
- Ember.changeProperties = function(cb, binding){
2409
+ Ember.changeProperties = function(cb, binding) {
2406
2410
  beginPropertyChanges();
2407
2411
  tryFinally(cb, endPropertyChanges, binding);
2408
2412
  };
@@ -2431,6 +2435,7 @@ var notifyObservers = function(obj, keyName) {
2431
2435
  sendEvent(obj, eventName, [obj, keyName]);
2432
2436
  }
2433
2437
  };
2438
+
2434
2439
  })();
2435
2440
 
2436
2441
 
@@ -2607,8 +2612,7 @@ Ember.trySetPath = Ember.deprecateFunc('trySetPath has been renamed to trySet',
2607
2612
  Map is mocked out to look like an Ember object, so you can do
2608
2613
  `Ember.Map.create()` for symmetry with other Ember classes.
2609
2614
  */
2610
- var get = Ember.get,
2611
- set = Ember.set,
2615
+ var set = Ember.set,
2612
2616
  guidFor = Ember.guidFor,
2613
2617
  indexOf = Ember.ArrayPolyfills.indexOf;
2614
2618
 
@@ -3134,13 +3138,14 @@ var changeProperties = Ember.changeProperties,
3134
3138
  @return self
3135
3139
  */
3136
3140
  Ember.setProperties = function(self, hash) {
3137
- changeProperties(function(){
3141
+ changeProperties(function() {
3138
3142
  for(var prop in hash) {
3139
3143
  if (hash.hasOwnProperty(prop)) { set(self, prop, hash[prop]); }
3140
3144
  }
3141
3145
  });
3142
3146
  return self;
3143
3147
  };
3148
+
3144
3149
  })();
3145
3150
 
3146
3151
 
@@ -3997,7 +4002,7 @@ ComputedPropertyPrototype.set = function(obj, keyName, value) {
3997
4002
  oldSuspended = this._suspended,
3998
4003
  hadCachedValue = false,
3999
4004
  cache = meta.cache,
4000
- cachedValue, ret;
4005
+ funcArgLength, cachedValue, ret;
4001
4006
 
4002
4007
  if (this._readOnly) {
4003
4008
  throw new Error('Cannot Set: ' + keyName + ' on: ' + obj.toString() );
@@ -4012,17 +4017,18 @@ ComputedPropertyPrototype.set = function(obj, keyName, value) {
4012
4017
  hadCachedValue = true;
4013
4018
  }
4014
4019
 
4015
- // Check if the CP has been wrapped
4016
- if (func.wrappedFunction) { func = func.wrappedFunction; }
4020
+ // Check if the CP has been wrapped. If if has, use the
4021
+ // length from the wrapped function.
4022
+ funcArgLength = (func.wrappedFunction ? func.wrappedFunction.length : func.length);
4017
4023
 
4018
4024
  // For backwards-compatibility with computed properties
4019
4025
  // that check for arguments.length === 2 to determine if
4020
4026
  // they are being get or set, only pass the old cached
4021
4027
  // value if the computed property opts into a third
4022
4028
  // argument.
4023
- if (func.length === 3) {
4029
+ if (funcArgLength === 3) {
4024
4030
  ret = func.call(obj, keyName, value, cachedValue);
4025
- } else if (func.length === 2) {
4031
+ } else if (funcArgLength === 2) {
4026
4032
  ret = func.call(obj, keyName, value);
4027
4033
  } else {
4028
4034
  Ember.defineProperty(obj, keyName, null, cachedValue);
@@ -4096,7 +4102,7 @@ Ember.computed = function(func) {
4096
4102
  func = a_slice.call(arguments, -1)[0];
4097
4103
  }
4098
4104
 
4099
- if ( typeof func !== "function" ) {
4105
+ if (typeof func !== "function") {
4100
4106
  throw new Error("Computed Property declared without a property function");
4101
4107
  }
4102
4108
 
@@ -4186,7 +4192,7 @@ registerComputed('notEmpty', function(dependentKey) {
4186
4192
  @for Ember
4187
4193
  @param {String} dependentKey
4188
4194
  @return {Ember.ComputedProperty} computed property which
4189
- rturns true if original value for property is null or undefined.
4195
+ returns true if original value for property is null or undefined.
4190
4196
  */
4191
4197
  registerComputed('none', function(dependentKey) {
4192
4198
  return Ember.isNone(get(this, dependentKey));
@@ -4357,6 +4363,23 @@ registerComputedWithProperties('map', function(properties) {
4357
4363
  });
4358
4364
 
4359
4365
  /**
4366
+ Creates a new property that is an alias for another property
4367
+ on an object. Calls to `get` or `set` this property behave as
4368
+ though they were called on the original property.
4369
+
4370
+ ```javascript
4371
+ Person = Ember.Object.extend({
4372
+ name: 'Alex Matchneer',
4373
+ nomen: Ember.computed.alias('name')
4374
+ });
4375
+
4376
+ alex = Person.create();
4377
+ alex.get('nomen'); // 'Alex Matchneer'
4378
+ alex.get('name'); // 'Alex Matchneer'
4379
+
4380
+ alex.set('nomen', '@machty');
4381
+ alex.get('name'); // '@machty'
4382
+ ```
4360
4383
  @method computed.alias
4361
4384
  @for Ember
4362
4385
  @param {String} dependentKey
@@ -4364,7 +4387,7 @@ registerComputedWithProperties('map', function(properties) {
4364
4387
  alias to the original value for property.
4365
4388
  */
4366
4389
  Ember.computed.alias = function(dependentKey) {
4367
- return Ember.computed(dependentKey, function(key, value){
4390
+ return Ember.computed(dependentKey, function(key, value) {
4368
4391
  if (arguments.length > 1) {
4369
4392
  set(this, dependentKey, value);
4370
4393
  return value;
@@ -4541,6 +4564,220 @@ Ember.removeBeforeObserver = function(obj, path, target, method) {
4541
4564
 
4542
4565
 
4543
4566
  (function() {
4567
+ define("backburner/queue",
4568
+ ["exports"],
4569
+ function(__exports__) {
4570
+ "use strict";
4571
+ function Queue(daq, name, options) {
4572
+ this.daq = daq;
4573
+ this.name = name;
4574
+ this.options = options;
4575
+ this._queue = [];
4576
+ }
4577
+
4578
+ Queue.prototype = {
4579
+ daq: null,
4580
+ name: null,
4581
+ options: null,
4582
+ _queue: null,
4583
+
4584
+ push: function(target, method, args, stack) {
4585
+ var queue = this._queue;
4586
+ queue.push(target, method, args, stack);
4587
+ return {queue: this, target: target, method: method};
4588
+ },
4589
+
4590
+ pushUnique: function(target, method, args, stack) {
4591
+ var queue = this._queue, currentTarget, currentMethod, i, l;
4592
+
4593
+ for (i = 0, l = queue.length; i < l; i += 4) {
4594
+ currentTarget = queue[i];
4595
+ currentMethod = queue[i+1];
4596
+
4597
+ if (currentTarget === target && currentMethod === method) {
4598
+ queue[i+2] = args; // replace args
4599
+ queue[i+3] = stack; // replace stack
4600
+ return {queue: this, target: target, method: method}; // TODO: test this code path
4601
+ }
4602
+ }
4603
+
4604
+ this._queue.push(target, method, args, stack);
4605
+ return {queue: this, target: target, method: method};
4606
+ },
4607
+
4608
+ // TODO: remove me, only being used for Ember.run.sync
4609
+ flush: function() {
4610
+ var queue = this._queue,
4611
+ options = this.options,
4612
+ before = options && options.before,
4613
+ after = options && options.after,
4614
+ target, method, args, stack, i, l = queue.length;
4615
+
4616
+ if (l && before) { before(); }
4617
+ for (i = 0; i < l; i += 4) {
4618
+ target = queue[i];
4619
+ method = queue[i+1];
4620
+ args = queue[i+2];
4621
+ stack = queue[i+3]; // Debugging assistance
4622
+
4623
+ // TODO: error handling
4624
+ if (args && args.length > 0) {
4625
+ method.apply(target, args);
4626
+ } else {
4627
+ method.call(target);
4628
+ }
4629
+ }
4630
+ if (l && after) { after(); }
4631
+
4632
+ // check if new items have been added
4633
+ if (queue.length > l) {
4634
+ this._queue = queue.slice(l);
4635
+ this.flush();
4636
+ } else {
4637
+ this._queue.length = 0;
4638
+ }
4639
+ },
4640
+
4641
+ cancel: function(actionToCancel) {
4642
+ var queue = this._queue, currentTarget, currentMethod, i, l;
4643
+
4644
+ for (i = 0, l = queue.length; i < l; i += 4) {
4645
+ currentTarget = queue[i];
4646
+ currentMethod = queue[i+1];
4647
+
4648
+ if (currentTarget === actionToCancel.target && currentMethod === actionToCancel.method) {
4649
+ queue.splice(i, 4);
4650
+ return true;
4651
+ }
4652
+ }
4653
+
4654
+ // if not found in current queue
4655
+ // could be in the queue that is being flushed
4656
+ queue = this._queueBeingFlushed;
4657
+ if (!queue) {
4658
+ return;
4659
+ }
4660
+ for (i = 0, l = queue.length; i < l; i += 4) {
4661
+ currentTarget = queue[i];
4662
+ currentMethod = queue[i+1];
4663
+
4664
+ if (currentTarget === actionToCancel.target && currentMethod === actionToCancel.method) {
4665
+ // don't mess with array during flush
4666
+ // just nullify the method
4667
+ queue[i+1] = null;
4668
+ return true;
4669
+ }
4670
+ }
4671
+ }
4672
+ };
4673
+
4674
+
4675
+ __exports__.Queue = Queue;
4676
+ });
4677
+
4678
+ define("backburner/deferred_action_queues",
4679
+ ["backburner/queue","exports"],
4680
+ function(__dependency1__, __exports__) {
4681
+ "use strict";
4682
+ var Queue = __dependency1__.Queue;
4683
+
4684
+ function DeferredActionQueues(queueNames, options) {
4685
+ var queues = this.queues = {};
4686
+ this.queueNames = queueNames = queueNames || [];
4687
+
4688
+ var queueName;
4689
+ for (var i = 0, l = queueNames.length; i < l; i++) {
4690
+ queueName = queueNames[i];
4691
+ queues[queueName] = new Queue(this, queueName, options[queueName]);
4692
+ }
4693
+ }
4694
+
4695
+ DeferredActionQueues.prototype = {
4696
+ queueNames: null,
4697
+ queues: null,
4698
+
4699
+ schedule: function(queueName, target, method, args, onceFlag, stack) {
4700
+ var queues = this.queues,
4701
+ queue = queues[queueName];
4702
+
4703
+ if (!queue) { throw new Error("You attempted to schedule an action in a queue (" + queueName + ") that doesn't exist"); }
4704
+
4705
+ if (onceFlag) {
4706
+ return queue.pushUnique(target, method, args, stack);
4707
+ } else {
4708
+ return queue.push(target, method, args, stack);
4709
+ }
4710
+ },
4711
+
4712
+ flush: function() {
4713
+ var queues = this.queues,
4714
+ queueNames = this.queueNames,
4715
+ queueName, queue, queueItems, priorQueueNameIndex,
4716
+ queueNameIndex = 0, numberOfQueues = queueNames.length;
4717
+
4718
+ outerloop:
4719
+ while (queueNameIndex < numberOfQueues) {
4720
+ queueName = queueNames[queueNameIndex];
4721
+ queue = queues[queueName];
4722
+ queueItems = queue._queueBeingFlushed = queue._queue.slice();
4723
+ queue._queue = [];
4724
+
4725
+ var options = queue.options,
4726
+ before = options && options.before,
4727
+ after = options && options.after,
4728
+ target, method, args, stack,
4729
+ queueIndex = 0, numberOfQueueItems = queueItems.length;
4730
+
4731
+ if (numberOfQueueItems && before) { before(); }
4732
+ while (queueIndex < numberOfQueueItems) {
4733
+ target = queueItems[queueIndex];
4734
+ method = queueItems[queueIndex+1];
4735
+ args = queueItems[queueIndex+2];
4736
+ stack = queueItems[queueIndex+3]; // Debugging assistance
4737
+
4738
+ if (typeof method === 'string') { method = target[method]; }
4739
+
4740
+ // method could have been nullified / canceled during flush
4741
+ if (method) {
4742
+ // TODO: error handling
4743
+ if (args && args.length > 0) {
4744
+ method.apply(target, args);
4745
+ } else {
4746
+ method.call(target);
4747
+ }
4748
+ }
4749
+
4750
+ queueIndex += 4;
4751
+ }
4752
+ queue._queueBeingFlushed = null;
4753
+ if (numberOfQueueItems && after) { after(); }
4754
+
4755
+ if ((priorQueueNameIndex = indexOfPriorQueueWithActions(this, queueNameIndex)) !== -1) {
4756
+ queueNameIndex = priorQueueNameIndex;
4757
+ continue outerloop;
4758
+ }
4759
+
4760
+ queueNameIndex++;
4761
+ }
4762
+ }
4763
+ };
4764
+
4765
+ function indexOfPriorQueueWithActions(daq, currentQueueIndex) {
4766
+ var queueName, queue;
4767
+
4768
+ for (var i = 0, l = currentQueueIndex; i <= l; i++) {
4769
+ queueName = daq.queueNames[i];
4770
+ queue = daq.queues[queueName];
4771
+ if (queue._queue.length) { return i; }
4772
+ }
4773
+
4774
+ return -1;
4775
+ }
4776
+
4777
+
4778
+ __exports__.DeferredActionQueues = DeferredActionQueues;
4779
+ });
4780
+
4544
4781
  define("backburner",
4545
4782
  ["backburner/deferred_action_queues","exports"],
4546
4783
  function(__dependency1__, __exports__) {
@@ -4549,9 +4786,11 @@ define("backburner",
4549
4786
 
4550
4787
  var slice = [].slice,
4551
4788
  pop = [].pop,
4789
+ throttlers = [],
4552
4790
  debouncees = [],
4553
4791
  timers = [],
4554
- autorun, laterTimer, laterTimerExpiresAt;
4792
+ autorun, laterTimer, laterTimerExpiresAt,
4793
+ global = this;
4555
4794
 
4556
4795
  function Backburner(queueNames, options) {
4557
4796
  this.queueNames = queueNames;
@@ -4708,7 +4947,7 @@ define("backburner",
4708
4947
  clearTimeout(laterTimer);
4709
4948
  laterTimer = null;
4710
4949
  }
4711
- laterTimer = window.setTimeout(function() {
4950
+ laterTimer = global.setTimeout(function() {
4712
4951
  executeTimers(self);
4713
4952
  laterTimer = null;
4714
4953
  laterTimerExpiresAt = null;
@@ -4718,53 +4957,101 @@ define("backburner",
4718
4957
  return fn;
4719
4958
  },
4720
4959
 
4721
- debounce: function(target, method /* , args, wait */) {
4960
+ throttle: function(target, method /* , args, wait */) {
4722
4961
  var self = this,
4723
4962
  args = arguments,
4724
4963
  wait = pop.call(args),
4725
- debouncee;
4964
+ throttler;
4726
4965
 
4727
- for (var i = 0, l = debouncees.length; i < l; i++) {
4728
- debouncee = debouncees[i];
4729
- if (debouncee[0] === target && debouncee[1] === method) { return; } // do nothing
4966
+ for (var i = 0, l = throttlers.length; i < l; i++) {
4967
+ throttler = throttlers[i];
4968
+ if (throttler[0] === target && throttler[1] === method) { return; } // do nothing
4730
4969
  }
4731
4970
 
4732
- var timer = window.setTimeout(function() {
4971
+ var timer = global.setTimeout(function() {
4733
4972
  self.run.apply(self, args);
4734
4973
 
4735
- // remove debouncee
4974
+ // remove throttler
4736
4975
  var index = -1;
4737
- for (var i = 0, l = debouncees.length; i < l; i++) {
4738
- debouncee = debouncees[i];
4739
- if (debouncee[0] === target && debouncee[1] === method) {
4976
+ for (var i = 0, l = throttlers.length; i < l; i++) {
4977
+ throttler = throttlers[i];
4978
+ if (throttler[0] === target && throttler[1] === method) {
4740
4979
  index = i;
4741
4980
  break;
4742
4981
  }
4743
4982
  }
4744
4983
 
4745
- if (index > -1) { debouncees.splice(index, 1); }
4984
+ if (index > -1) { throttlers.splice(index, 1); }
4746
4985
  }, wait);
4747
4986
 
4748
- debouncees.push([target, method, timer]);
4987
+ throttlers.push([target, method, timer]);
4749
4988
  },
4750
4989
 
4751
- cancelTimers: function() {
4752
- for (var i = 0, l = debouncees.length; i < l; i++) {
4753
- clearTimeout(debouncees[i][2]);
4754
- }
4755
- debouncees = [];
4990
+ debounce: function(target, method /* , args, wait, [immediate] */) {
4991
+ var self = this,
4992
+ args = arguments,
4993
+ immediate = pop.call(args),
4994
+ wait,
4995
+ index,
4996
+ debouncee;
4756
4997
 
4757
- if (laterTimer) {
4758
- clearTimeout(laterTimer);
4759
- laterTimer = null;
4998
+ if (typeof immediate === "number") {
4999
+ wait = immediate;
5000
+ immediate = false;
5001
+ } else {
5002
+ wait = pop.call(args);
4760
5003
  }
4761
- timers = [];
4762
5004
 
4763
- if (autorun) {
4764
- clearTimeout(autorun);
4765
- autorun = null;
5005
+ // Remove debouncee
5006
+ index = findDebouncee(target, method);
5007
+
5008
+ if (index !== -1) {
5009
+ debouncee = debouncees[index];
5010
+ debouncees.splice(index, 1);
5011
+ clearTimeout(debouncee[2]);
4766
5012
  }
4767
- },
5013
+
5014
+ var timer = window.setTimeout(function() {
5015
+ if (!immediate) {
5016
+ self.run.apply(self, args);
5017
+ }
5018
+ index = findDebouncee(target, method);
5019
+ if (index) {
5020
+ debouncees.splice(index, 1);
5021
+ }
5022
+ }, wait);
5023
+
5024
+ if (immediate && index === -1) {
5025
+ self.run.apply(self, args);
5026
+ }
5027
+
5028
+ debouncees.push([target, method, timer]);
5029
+ },
5030
+
5031
+ cancelTimers: function() {
5032
+ var i, len;
5033
+
5034
+ for (i = 0, len = throttlers.length; i < len; i++) {
5035
+ clearTimeout(throttlers[i][2]);
5036
+ }
5037
+ throttlers = [];
5038
+
5039
+ for (i = 0, len = debouncees.length; i < len; i++) {
5040
+ clearTimeout(debouncees[i][2]);
5041
+ }
5042
+ debouncees = [];
5043
+
5044
+ if (laterTimer) {
5045
+ clearTimeout(laterTimer);
5046
+ laterTimer = null;
5047
+ }
5048
+ timers = [];
5049
+
5050
+ if (autorun) {
5051
+ clearTimeout(autorun);
5052
+ autorun = null;
5053
+ }
5054
+ },
4768
5055
 
4769
5056
  hasTimers: function() {
4770
5057
  return !!timers.length || autorun;
@@ -4792,7 +5079,7 @@ define("backburner",
4792
5079
 
4793
5080
  function createAutorun(backburner) {
4794
5081
  backburner.begin();
4795
- autorun = window.setTimeout(function() {
5082
+ autorun = global.setTimeout(function() {
4796
5083
  backburner.end();
4797
5084
  autorun = null;
4798
5085
  });
@@ -4817,7 +5104,7 @@ define("backburner",
4817
5104
  });
4818
5105
 
4819
5106
  if (timers.length) {
4820
- laterTimer = window.setTimeout(function() {
5107
+ laterTimer = global.setTimeout(function() {
4821
5108
  executeTimers(self);
4822
5109
  laterTimer = null;
4823
5110
  laterTimerExpiresAt = null;
@@ -4826,222 +5113,23 @@ define("backburner",
4826
5113
  }
4827
5114
  }
4828
5115
 
5116
+ function findDebouncee(target, method) {
5117
+ var debouncee,
5118
+ index = -1;
4829
5119
 
4830
- __exports__.Backburner = Backburner;
4831
- });
4832
-
4833
- define("backburner/deferred_action_queues",
4834
- ["backburner/queue","exports"],
4835
- function(__dependency1__, __exports__) {
4836
- "use strict";
4837
- var Queue = __dependency1__.Queue;
4838
-
4839
- function DeferredActionQueues(queueNames, options) {
4840
- var queues = this.queues = {};
4841
- this.queueNames = queueNames = queueNames || [];
4842
-
4843
- var queueName;
4844
- for (var i = 0, l = queueNames.length; i < l; i++) {
4845
- queueName = queueNames[i];
4846
- queues[queueName] = new Queue(this, queueName, options[queueName]);
4847
- }
4848
- }
4849
-
4850
- DeferredActionQueues.prototype = {
4851
- queueNames: null,
4852
- queues: null,
4853
-
4854
- schedule: function(queueName, target, method, args, onceFlag, stack) {
4855
- var queues = this.queues,
4856
- queue = queues[queueName];
4857
-
4858
- if (!queue) { throw new Error("You attempted to schedule an action in a queue (" + queueName + ") that doesn't exist"); }
4859
-
4860
- if (onceFlag) {
4861
- return queue.pushUnique(target, method, args, stack);
4862
- } else {
4863
- return queue.push(target, method, args, stack);
4864
- }
4865
- },
4866
-
4867
- flush: function() {
4868
- var queues = this.queues,
4869
- queueNames = this.queueNames,
4870
- queueName, queue, queueItems, priorQueueNameIndex,
4871
- queueNameIndex = 0, numberOfQueues = queueNames.length;
4872
-
4873
- outerloop:
4874
- while (queueNameIndex < numberOfQueues) {
4875
- queueName = queueNames[queueNameIndex];
4876
- queue = queues[queueName];
4877
- queueItems = queue._queueBeingFlushed = queue._queue.slice();
4878
- queue._queue = [];
4879
-
4880
- var options = queue.options,
4881
- before = options && options.before,
4882
- after = options && options.after,
4883
- target, method, args, stack,
4884
- queueIndex = 0, numberOfQueueItems = queueItems.length;
4885
-
4886
- if (numberOfQueueItems && before) { before(); }
4887
- while (queueIndex < numberOfQueueItems) {
4888
- target = queueItems[queueIndex];
4889
- method = queueItems[queueIndex+1];
4890
- args = queueItems[queueIndex+2];
4891
- stack = queueItems[queueIndex+3]; // Debugging assistance
4892
-
4893
- if (typeof method === 'string') { method = target[method]; }
4894
-
4895
- // method could have been nullified / canceled during flush
4896
- if (method) {
4897
- // TODO: error handling
4898
- if (args && args.length > 0) {
4899
- method.apply(target, args);
4900
- } else {
4901
- method.call(target);
4902
- }
4903
- }
4904
-
4905
- queueIndex += 4;
4906
- }
4907
- queue._queueBeingFlushed = null;
4908
- if (numberOfQueueItems && after) { after(); }
4909
-
4910
- if ((priorQueueNameIndex = indexOfPriorQueueWithActions(this, queueNameIndex)) !== -1) {
4911
- queueNameIndex = priorQueueNameIndex;
4912
- continue outerloop;
4913
- }
4914
-
4915
- queueNameIndex++;
5120
+ for (var i = 0, l = debouncees.length; i < l; i++) {
5121
+ debouncee = debouncees[i];
5122
+ if (debouncee[0] === target && debouncee[1] === method) {
5123
+ index = i;
5124
+ break;
4916
5125
  }
4917
5126
  }
4918
- };
4919
-
4920
- function indexOfPriorQueueWithActions(daq, currentQueueIndex) {
4921
- var queueName, queue;
4922
5127
 
4923
- for (var i = 0, l = currentQueueIndex; i <= l; i++) {
4924
- queueName = daq.queueNames[i];
4925
- queue = daq.queues[queueName];
4926
- if (queue._queue.length) { return i; }
4927
- }
4928
-
4929
- return -1;
5128
+ return index;
4930
5129
  }
4931
5130
 
4932
5131
 
4933
- __exports__.DeferredActionQueues = DeferredActionQueues;
4934
- });
4935
-
4936
- define("backburner/queue",
4937
- ["exports"],
4938
- function(__exports__) {
4939
- "use strict";
4940
- function Queue(daq, name, options) {
4941
- this.daq = daq;
4942
- this.name = name;
4943
- this.options = options;
4944
- this._queue = [];
4945
- }
4946
-
4947
- Queue.prototype = {
4948
- daq: null,
4949
- name: null,
4950
- options: null,
4951
- _queue: null,
4952
-
4953
- push: function(target, method, args, stack) {
4954
- var queue = this._queue;
4955
- queue.push(target, method, args, stack);
4956
- return {queue: this, target: target, method: method};
4957
- },
4958
-
4959
- pushUnique: function(target, method, args, stack) {
4960
- var queue = this._queue, currentTarget, currentMethod, i, l;
4961
-
4962
- for (i = 0, l = queue.length; i < l; i += 4) {
4963
- currentTarget = queue[i];
4964
- currentMethod = queue[i+1];
4965
-
4966
- if (currentTarget === target && currentMethod === method) {
4967
- queue[i+2] = args; // replace args
4968
- queue[i+3] = stack; // replace stack
4969
- return {queue: this, target: target, method: method}; // TODO: test this code path
4970
- }
4971
- }
4972
-
4973
- this._queue.push(target, method, args, stack);
4974
- return {queue: this, target: target, method: method};
4975
- },
4976
-
4977
- // TODO: remove me, only being used for Ember.run.sync
4978
- flush: function() {
4979
- var queue = this._queue,
4980
- options = this.options,
4981
- before = options && options.before,
4982
- after = options && options.after,
4983
- target, method, args, stack, i, l = queue.length;
4984
-
4985
- if (l && before) { before(); }
4986
- for (i = 0; i < l; i += 4) {
4987
- target = queue[i];
4988
- method = queue[i+1];
4989
- args = queue[i+2];
4990
- stack = queue[i+3]; // Debugging assistance
4991
-
4992
- // TODO: error handling
4993
- if (args && args.length > 0) {
4994
- method.apply(target, args);
4995
- } else {
4996
- method.call(target);
4997
- }
4998
- }
4999
- if (l && after) { after(); }
5000
-
5001
- // check if new items have been added
5002
- if (queue.length > l) {
5003
- this._queue = queue.slice(l);
5004
- this.flush();
5005
- } else {
5006
- this._queue.length = 0;
5007
- }
5008
- },
5009
-
5010
- cancel: function(actionToCancel) {
5011
- var queue = this._queue, currentTarget, currentMethod, i, l;
5012
-
5013
- for (i = 0, l = queue.length; i < l; i += 4) {
5014
- currentTarget = queue[i];
5015
- currentMethod = queue[i+1];
5016
-
5017
- if (currentTarget === actionToCancel.target && currentMethod === actionToCancel.method) {
5018
- queue.splice(i, 4);
5019
- return true;
5020
- }
5021
- }
5022
-
5023
- // if not found in current queue
5024
- // could be in the queue that is being flushed
5025
- queue = this._queueBeingFlushed;
5026
- if (!queue) {
5027
- return;
5028
- }
5029
- for (i = 0, l = queue.length; i < l; i += 4) {
5030
- currentTarget = queue[i];
5031
- currentMethod = queue[i+1];
5032
-
5033
- if (currentTarget === actionToCancel.target && currentMethod === actionToCancel.method) {
5034
- // don't mess with array during flush
5035
- // just nullify the method
5036
- queue[i+1] = null;
5037
- return true;
5038
- }
5039
- }
5040
- }
5041
- };
5042
-
5043
-
5044
- __exports__.Queue = Queue;
5132
+ __exports__.Backburner = Backburner;
5045
5133
  });
5046
5134
  })();
5047
5135
 
@@ -5083,7 +5171,7 @@ var Backburner = requireModule('backburner').Backburner,
5083
5171
  call.
5084
5172
 
5085
5173
  ```javascript
5086
- Ember.run(function(){
5174
+ Ember.run(function() {
5087
5175
  // code to be execute within a RunLoop
5088
5176
  });
5089
5177
  ```
@@ -5126,7 +5214,7 @@ Ember.run = function(target, method) {
5126
5214
  If invoked when not within a run loop:
5127
5215
 
5128
5216
  ```javascript
5129
- Ember.run.join(function(){
5217
+ Ember.run.join(function() {
5130
5218
  // creates a new run-loop
5131
5219
  });
5132
5220
  ```
@@ -5134,9 +5222,9 @@ Ember.run = function(target, method) {
5134
5222
  Alternatively, if called within an existing run loop:
5135
5223
 
5136
5224
  ```javascript
5137
- Ember.run(function(){
5225
+ Ember.run(function() {
5138
5226
  // creates a new run-loop
5139
- Ember.run.join(function(){
5227
+ Ember.run.join(function() {
5140
5228
  // joins with the existing run-loop, and queues for invocation on
5141
5229
  // the existing run-loops action queue.
5142
5230
  });
@@ -5229,12 +5317,12 @@ Ember.run.end = function() {
5229
5317
  the `Ember.run.queues` property.
5230
5318
 
5231
5319
  ```javascript
5232
- Ember.run.schedule('sync', this, function(){
5320
+ Ember.run.schedule('sync', this, function() {
5233
5321
  // this will be executed in the first RunLoop queue, when bindings are synced
5234
5322
  console.log("scheduled on sync queue");
5235
5323
  });
5236
5324
 
5237
- Ember.run.schedule('actions', this, function(){
5325
+ Ember.run.schedule('actions', this, function() {
5238
5326
  // this will be executed in the 'actions' queue, after bindings have synced.
5239
5327
  console.log("scheduled on actions queue");
5240
5328
  });
@@ -5302,7 +5390,7 @@ Ember.run.sync = function() {
5302
5390
  together, which is often more efficient than using a real setTimeout.
5303
5391
 
5304
5392
  ```javascript
5305
- Ember.run.later(myContext, function(){
5393
+ Ember.run.later(myContext, function() {
5306
5394
  // code here will execute within a RunLoop in about 500ms with this == myContext
5307
5395
  }, 500);
5308
5396
  ```
@@ -5350,11 +5438,11 @@ Ember.run.once = function(target, method) {
5350
5438
  calls.
5351
5439
 
5352
5440
  ```javascript
5353
- Ember.run(function(){
5441
+ Ember.run(function() {
5354
5442
  var sayHi = function() { console.log('hi'); }
5355
5443
  Ember.run.scheduleOnce('afterRender', myContext, sayHi);
5356
5444
  Ember.run.scheduleOnce('afterRender', myContext, sayHi);
5357
- // doFoo will only be executed once, in the afterRender queue of the RunLoop
5445
+ // sayHi will only be executed once, in the afterRender queue of the RunLoop
5358
5446
  });
5359
5447
  ```
5360
5448
 
@@ -5395,7 +5483,7 @@ Ember.run.scheduleOnce = function(queue, target, method) {
5395
5483
  `Ember.run.later` with a wait time of 1ms.
5396
5484
 
5397
5485
  ```javascript
5398
- Ember.run.next(myContext, function(){
5486
+ Ember.run.next(myContext, function() {
5399
5487
  // code to be executed in the next run loop, which will be scheduled after the current one
5400
5488
  });
5401
5489
  ```
@@ -5457,17 +5545,17 @@ Ember.run.next = function() {
5457
5545
  `Ember.run.once()`, or `Ember.run.next()`.
5458
5546
 
5459
5547
  ```javascript
5460
- var runNext = Ember.run.next(myContext, function(){
5548
+ var runNext = Ember.run.next(myContext, function() {
5461
5549
  // will not be executed
5462
5550
  });
5463
5551
  Ember.run.cancel(runNext);
5464
5552
 
5465
- var runLater = Ember.run.later(myContext, function(){
5553
+ var runLater = Ember.run.later(myContext, function() {
5466
5554
  // will not be executed
5467
5555
  }, 500);
5468
5556
  Ember.run.cancel(runLater);
5469
5557
 
5470
- var runOnce = Ember.run.once(myContext, function(){
5558
+ var runOnce = Ember.run.once(myContext, function() {
5471
5559
  // will not be executed
5472
5560
  });
5473
5561
  Ember.run.cancel(runOnce);
@@ -5482,8 +5570,15 @@ Ember.run.cancel = function(timer) {
5482
5570
  };
5483
5571
 
5484
5572
  /**
5485
- Execute the passed method in a specified amount of time, reset timer
5486
- upon additional calls.
5573
+ Delay calling the target method until the debounce period has elapsed
5574
+ with no additional debounce calls. If `debounce` is called again before
5575
+ the specified time has elapsed, the timer is reset and the entire period
5576
+ must pass again before the target method is called.
5577
+
5578
+ This method should be used when an event may be called multiple times
5579
+ but the action should only be called once when the event is done firing.
5580
+ A common example is for scroll events where you only want updates to
5581
+ happen once scrolling has ceased.
5487
5582
 
5488
5583
  ```javascript
5489
5584
  var myFunc = function() { console.log(this.name + ' ran.'); };
@@ -5507,12 +5602,50 @@ Ember.run.cancel = function(timer) {
5507
5602
  then it will be looked up on the passed target.
5508
5603
  @param {Object} [args*] Optional arguments to pass to the timeout.
5509
5604
  @param {Number} wait Number of milliseconds to wait.
5605
+ @param {Boolean} immediate Trigger the function on the leading instead of the trailing edge of the wait interval.
5510
5606
  @return {void}
5511
5607
  */
5512
5608
  Ember.run.debounce = function() {
5513
5609
  return backburner.debounce.apply(backburner, arguments);
5514
5610
  };
5515
5611
 
5612
+ /**
5613
+ Ensure that the target method is never called more frequently than
5614
+ the specified spacing period.
5615
+
5616
+ ```javascript
5617
+ var myFunc = function() { console.log(this.name + ' ran.'); };
5618
+ var myContext = {name: 'throttle'};
5619
+
5620
+ Ember.run.throttle(myContext, myFunc, 150);
5621
+
5622
+ // 50ms passes
5623
+ Ember.run.throttle(myContext, myFunc, 150);
5624
+
5625
+ // 50ms passes
5626
+ Ember.run.throttle(myContext, myFunc, 150);
5627
+
5628
+ // 50ms passes
5629
+ Ember.run.throttle(myContext, myFunc, 150);
5630
+
5631
+ // 150ms passes
5632
+ // myFunc is invoked with context myContext
5633
+ // console logs 'throttle ran.' twice, 150ms apart.
5634
+ ```
5635
+
5636
+ @method throttle
5637
+ @param {Object} [target] target of method to invoke
5638
+ @param {Function|String} method The method to invoke.
5639
+ May be a function or a string. If you pass a string
5640
+ then it will be looked up on the passed target.
5641
+ @param {Object} [args*] Optional arguments to pass to the timeout.
5642
+ @param {Number} spacing Number of milliseconds to space out requests.
5643
+ @return {void}
5644
+ */
5645
+ Ember.run.throttle = function() {
5646
+ return backburner.throttle.apply(backburner, arguments);
5647
+ };
5648
+
5516
5649
  // Make sure it's not an autorun during testing
5517
5650
  function checkAutoRun() {
5518
5651
  if (!Ember.run.currentRunLoop) {
@@ -6003,7 +6136,8 @@ Ember.oneWay = function(obj, to, from) {
6003
6136
 
6004
6137
  (function() {
6005
6138
  /**
6006
- @module ember-metal
6139
+ @module ember
6140
+ @submodule ember-metal
6007
6141
  */
6008
6142
 
6009
6143
  var Mixin, REQUIRED, Alias,
@@ -6379,38 +6513,6 @@ Mixin.finishPartial = finishPartial;
6379
6513
  Ember.anyUnprocessedMixins = false;
6380
6514
 
6381
6515
  /**
6382
- Creates an instance of a class. Accepts either no arguments, or an object
6383
- containing values to initialize the newly instantiated object with.
6384
-
6385
- ```javascript
6386
- App.Person = Ember.Object.extend({
6387
- helloWorld: function() {
6388
- alert("Hi, my name is " + this.get('name'));
6389
- }
6390
- });
6391
-
6392
- var tom = App.Person.create({
6393
- name: 'Tom Dale'
6394
- });
6395
-
6396
- tom.helloWorld(); // alerts "Hi, my name is Tom Dale".
6397
- ```
6398
-
6399
- `create` will call the `init` function if defined during
6400
- `Ember.AnyObject.extend`
6401
-
6402
- If no arguments are passed to `create`, it will not set values to the new
6403
- instance during initialization:
6404
-
6405
- ```javascript
6406
- var noName = App.Person.create();
6407
- noName.helloWorld(); // alerts undefined
6408
- ```
6409
-
6410
- NOTE: For performance reasons, you cannot declare methods or computed
6411
- properties during `create`. You should instead declare methods and computed
6412
- properties when using `extend`.
6413
-
6414
6516
  @method create
6415
6517
  @static
6416
6518
  @param arguments*
@@ -6570,7 +6672,7 @@ Alias.prototype = new Ember.Descriptor();
6570
6672
  App.PaintSample = Ember.Object.extend({
6571
6673
  color: 'red',
6572
6674
  colour: Ember.alias('color'),
6573
- name: function(){
6675
+ name: function() {
6574
6676
  return "Zed";
6575
6677
  },
6576
6678
  moniker: Ember.alias("name")
@@ -6598,7 +6700,7 @@ Ember.alias = Ember.deprecateFunc("Ember.alias is deprecated. Please use Ember.a
6598
6700
 
6599
6701
  ```javascript
6600
6702
  App.Person = Ember.Object.extend({
6601
- name: function(){
6703
+ name: function() {
6602
6704
  return 'Tomhuda Katzdale';
6603
6705
  },
6604
6706
  moniker: Ember.aliasMethod('name')
@@ -6667,7 +6769,7 @@ Ember.immediateObserver = function() {
6667
6769
  }.observesBefore('content.value'),
6668
6770
  valueDidChange: function(obj, keyName, value) {
6669
6771
  // only run if updating a value already in the DOM
6670
- if(this.get('state') === 'inDOM') {
6772
+ if (this.get('state') === 'inDOM') {
6671
6773
  var color = value > this.changingFrom ? 'green' : 'red';
6672
6774
  // logic
6673
6775
  }
@@ -6703,65 +6805,82 @@ Ember Metal
6703
6805
 
6704
6806
  (function() {
6705
6807
  define("rsvp/all",
6706
- ["rsvp/defer","exports"],
6808
+ ["rsvp/promise","exports"],
6707
6809
  function(__dependency1__, __exports__) {
6708
6810
  "use strict";
6709
- var defer = __dependency1__.defer;
6811
+ var Promise = __dependency1__.Promise;
6812
+ /* global toString */
6710
6813
 
6711
- function all(promises) {
6712
- var results = [], deferred = defer(), remaining = promises.length;
6713
6814
 
6714
- if (remaining === 0) {
6715
- deferred.resolve([]);
6815
+ function all(promises) {
6816
+ if (Object.prototype.toString.call(promises) !== "[object Array]") {
6817
+ throw new TypeError('You must pass an array to all.');
6716
6818
  }
6717
6819
 
6718
- var resolver = function(index) {
6719
- return function(value) {
6720
- resolveAll(index, value);
6721
- };
6722
- };
6820
+ return new Promise(function(resolve, reject) {
6821
+ var results = [], remaining = promises.length,
6822
+ promise;
6723
6823
 
6724
- var resolveAll = function(index, value) {
6725
- results[index] = value;
6726
- if (--remaining === 0) {
6727
- deferred.resolve(results);
6824
+ if (remaining === 0) {
6825
+ resolve([]);
6728
6826
  }
6729
- };
6730
6827
 
6731
- var rejectAll = function(error) {
6732
- deferred.reject(error);
6733
- };
6828
+ function resolver(index) {
6829
+ return function(value) {
6830
+ resolveAll(index, value);
6831
+ };
6832
+ }
6734
6833
 
6735
- for (var i = 0; i < promises.length; i++) {
6736
- if (promises[i] && typeof promises[i].then === 'function') {
6737
- promises[i].then(resolver(i), rejectAll);
6738
- } else {
6739
- resolveAll(i, promises[i]);
6834
+ function resolveAll(index, value) {
6835
+ results[index] = value;
6836
+ if (--remaining === 0) {
6837
+ resolve(results);
6838
+ }
6740
6839
  }
6741
- }
6742
- return deferred.promise;
6840
+
6841
+ for (var i = 0; i < promises.length; i++) {
6842
+ promise = promises[i];
6843
+
6844
+ if (promise && typeof promise.then === 'function') {
6845
+ promise.then(resolver(i), reject);
6846
+ } else {
6847
+ resolveAll(i, promise);
6848
+ }
6849
+ }
6850
+ });
6743
6851
  }
6744
6852
 
6853
+
6745
6854
  __exports__.all = all;
6746
6855
  });
6747
-
6748
6856
  define("rsvp/async",
6749
6857
  ["exports"],
6750
6858
  function(__exports__) {
6751
6859
  "use strict";
6752
6860
  var browserGlobal = (typeof window !== 'undefined') ? window : {};
6753
-
6754
6861
  var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
6755
6862
  var async;
6756
6863
 
6757
- if (typeof process !== 'undefined' &&
6758
- {}.toString.call(process) === '[object process]') {
6759
- async = function(callback, binding) {
6864
+ // old node
6865
+ function useNextTick() {
6866
+ return function(callback, arg) {
6760
6867
  process.nextTick(function() {
6761
- callback.call(binding);
6868
+ callback(arg);
6762
6869
  });
6763
6870
  };
6764
- } else if (BrowserMutationObserver) {
6871
+ }
6872
+
6873
+ // node >= 0.10.x
6874
+ function useSetImmediate() {
6875
+ return function(callback, arg) {
6876
+ /* global setImmediate */
6877
+ setImmediate(function(){
6878
+ callback(arg);
6879
+ });
6880
+ };
6881
+ }
6882
+
6883
+ function useMutationObserver() {
6765
6884
  var queue = [];
6766
6885
 
6767
6886
  var observer = new BrowserMutationObserver(function() {
@@ -6769,8 +6888,8 @@ define("rsvp/async",
6769
6888
  queue = [];
6770
6889
 
6771
6890
  toProcess.forEach(function(tuple) {
6772
- var callback = tuple[0], binding = tuple[1];
6773
- callback.call(binding);
6891
+ var callback = tuple[0], arg= tuple[1];
6892
+ callback(arg);
6774
6893
  });
6775
6894
  });
6776
6895
 
@@ -6781,24 +6900,35 @@ define("rsvp/async",
6781
6900
  window.addEventListener('unload', function(){
6782
6901
  observer.disconnect();
6783
6902
  observer = null;
6784
- });
6903
+ }, false);
6785
6904
 
6786
- async = function(callback, binding) {
6787
- queue.push([callback, binding]);
6905
+ return function(callback, arg) {
6906
+ queue.push([callback, arg]);
6788
6907
  element.setAttribute('drainQueue', 'drainQueue');
6789
6908
  };
6790
- } else {
6791
- async = function(callback, binding) {
6909
+ }
6910
+
6911
+ function useSetTimeout() {
6912
+ return function(callback, arg) {
6792
6913
  setTimeout(function() {
6793
- callback.call(binding);
6914
+ callback(arg);
6794
6915
  }, 1);
6795
6916
  };
6796
6917
  }
6797
6918
 
6919
+ if (typeof setImmediate === 'function') {
6920
+ async = useSetImmediate();
6921
+ } else if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
6922
+ async = useNextTick();
6923
+ } else if (BrowserMutationObserver) {
6924
+ async = useMutationObserver();
6925
+ } else {
6926
+ async = useSetTimeout();
6927
+ }
6928
+
6798
6929
 
6799
6930
  __exports__.async = async;
6800
6931
  });
6801
-
6802
6932
  define("rsvp/config",
6803
6933
  ["rsvp/async","exports"],
6804
6934
  function(__dependency1__, __exports__) {
@@ -6808,9 +6938,9 @@ define("rsvp/config",
6808
6938
  var config = {};
6809
6939
  config.async = async;
6810
6940
 
6941
+
6811
6942
  __exports__.config = config;
6812
6943
  });
6813
-
6814
6944
  define("rsvp/defer",
6815
6945
  ["rsvp/promise","exports"],
6816
6946
  function(__dependency1__, __exports__) {
@@ -6818,20 +6948,24 @@ define("rsvp/defer",
6818
6948
  var Promise = __dependency1__.Promise;
6819
6949
 
6820
6950
  function defer() {
6821
- var deferred = {};
6951
+ var deferred = {
6952
+ // pre-allocate shape
6953
+ resolve: undefined,
6954
+ reject: undefined,
6955
+ promise: undefined
6956
+ };
6822
6957
 
6823
- var promise = new Promise(function(resolve, reject) {
6958
+ deferred.promise = new Promise(function(resolve, reject) {
6824
6959
  deferred.resolve = resolve;
6825
6960
  deferred.reject = reject;
6826
6961
  });
6827
6962
 
6828
- deferred.promise = promise;
6829
6963
  return deferred;
6830
6964
  }
6831
6965
 
6966
+
6832
6967
  __exports__.defer = defer;
6833
6968
  });
6834
-
6835
6969
  define("rsvp/events",
6836
6970
  ["exports"],
6837
6971
  function(__exports__) {
@@ -6933,7 +7067,6 @@ define("rsvp/events",
6933
7067
 
6934
7068
  __exports__.EventTarget = EventTarget;
6935
7069
  });
6936
-
6937
7070
  define("rsvp/hash",
6938
7071
  ["rsvp/defer","exports"],
6939
7072
  function(__dependency1__, __exports__) {
@@ -6941,13 +7074,13 @@ define("rsvp/hash",
6941
7074
  var defer = __dependency1__.defer;
6942
7075
 
6943
7076
  function size(object) {
6944
- var size = 0;
7077
+ var s = 0;
6945
7078
 
6946
7079
  for (var prop in object) {
6947
- size++;
7080
+ s++;
6948
7081
  }
6949
7082
 
6950
- return size;
7083
+ return s;
6951
7084
  }
6952
7085
 
6953
7086
  function hash(promises) {
@@ -6985,9 +7118,9 @@ define("rsvp/hash",
6985
7118
  return deferred.promise;
6986
7119
  }
6987
7120
 
7121
+
6988
7122
  __exports__.hash = hash;
6989
7123
  });
6990
-
6991
7124
  define("rsvp/node",
6992
7125
  ["rsvp/promise","rsvp/all","exports"],
6993
7126
  function(__dependency1__, __dependency2__, __exports__) {
@@ -7010,6 +7143,7 @@ define("rsvp/node",
7010
7143
  function denodeify(nodeFunc) {
7011
7144
  return function() {
7012
7145
  var nodeArgs = Array.prototype.slice.call(arguments), resolve, reject;
7146
+ var thisArg = this;
7013
7147
 
7014
7148
  var promise = new Promise(function(nodeResolve, nodeReject) {
7015
7149
  resolve = nodeResolve;
@@ -7020,7 +7154,7 @@ define("rsvp/node",
7020
7154
  nodeArgs.push(makeNodeCallbackFor(resolve, reject));
7021
7155
 
7022
7156
  try {
7023
- nodeFunc.apply(this, nodeArgs);
7157
+ nodeFunc.apply(thisArg, nodeArgs);
7024
7158
  } catch(e) {
7025
7159
  reject(e);
7026
7160
  }
@@ -7030,9 +7164,9 @@ define("rsvp/node",
7030
7164
  };
7031
7165
  }
7032
7166
 
7167
+
7033
7168
  __exports__.denodeify = denodeify;
7034
7169
  });
7035
-
7036
7170
  define("rsvp/promise",
7037
7171
  ["rsvp/config","rsvp/events","exports"],
7038
7172
  function(__dependency1__, __dependency2__, __exports__) {
@@ -7080,6 +7214,8 @@ define("rsvp/promise",
7080
7214
  this.trigger('error', { detail: event.detail });
7081
7215
  }, this);
7082
7216
 
7217
+ this.on('error', onerror);
7218
+
7083
7219
  try {
7084
7220
  resolver(resolvePromise, rejectPromise);
7085
7221
  } catch(e) {
@@ -7087,6 +7223,12 @@ define("rsvp/promise",
7087
7223
  }
7088
7224
  };
7089
7225
 
7226
+ function onerror(event) {
7227
+ if (config.onerror) {
7228
+ config.onerror(event.detail);
7229
+ }
7230
+ }
7231
+
7090
7232
  var invokeCallback = function(type, promise, callback, event) {
7091
7233
  var hasCallback = isFunction(callback),
7092
7234
  value, error, succeeded, failed;
@@ -7120,18 +7262,25 @@ define("rsvp/promise",
7120
7262
  Promise.prototype = {
7121
7263
  constructor: Promise,
7122
7264
 
7265
+ isRejected: undefined,
7266
+ isFulfilled: undefined,
7267
+ rejectedReason: undefined,
7268
+ fulfillmentValue: undefined,
7269
+
7123
7270
  then: function(done, fail) {
7124
- var thenPromise = new Promise(function() {});
7271
+ this.off('error', onerror);
7272
+
7273
+ var thenPromise = new this.constructor(function() {});
7125
7274
 
7126
7275
  if (this.isFulfilled) {
7127
- config.async(function() {
7128
- invokeCallback('resolve', thenPromise, done, { detail: this.fulfillmentValue });
7276
+ config.async(function(promise) {
7277
+ invokeCallback('resolve', thenPromise, done, { detail: promise.fulfillmentValue });
7129
7278
  }, this);
7130
7279
  }
7131
7280
 
7132
7281
  if (this.isRejected) {
7133
- config.async(function() {
7134
- invokeCallback('reject', thenPromise, fail, { detail: this.rejectedReason });
7282
+ config.async(function(promise) {
7283
+ invokeCallback('reject', thenPromise, fail, { detail: promise.rejectedReason });
7135
7284
  }, this);
7136
7285
  }
7137
7286
 
@@ -7158,32 +7307,40 @@ define("rsvp/promise",
7158
7307
  }
7159
7308
 
7160
7309
  function handleThenable(promise, value) {
7161
- var then = null;
7310
+ var then = null,
7311
+ resolved;
7162
7312
 
7163
- if (objectOrFunction(value)) {
7164
- try {
7165
- then = value.then;
7166
- } catch(e) {
7167
- reject(promise, e);
7168
- return true;
7313
+ try {
7314
+ if (promise === value) {
7315
+ throw new TypeError("A promises callback cannot return that same promise.");
7169
7316
  }
7170
7317
 
7171
- if (isFunction(then)) {
7172
- try {
7318
+ if (objectOrFunction(value)) {
7319
+ then = value.then;
7320
+
7321
+ if (isFunction(then)) {
7173
7322
  then.call(value, function(val) {
7323
+ if (resolved) { return true; }
7324
+ resolved = true;
7325
+
7174
7326
  if (value !== val) {
7175
7327
  resolve(promise, val);
7176
7328
  } else {
7177
7329
  fulfill(promise, val);
7178
7330
  }
7179
7331
  }, function(val) {
7332
+ if (resolved) { return true; }
7333
+ resolved = true;
7334
+
7180
7335
  reject(promise, val);
7181
7336
  });
7182
- } catch (e) {
7183
- reject(promise, e);
7337
+
7338
+ return true;
7184
7339
  }
7185
- return true;
7186
7340
  }
7341
+ } catch (error) {
7342
+ reject(promise, error);
7343
+ return true;
7187
7344
  }
7188
7345
 
7189
7346
  return false;
@@ -7208,19 +7365,12 @@ define("rsvp/promise",
7208
7365
 
7209
7366
  __exports__.Promise = Promise;
7210
7367
  });
7211
-
7212
7368
  define("rsvp/reject",
7213
7369
  ["rsvp/promise","exports"],
7214
7370
  function(__dependency1__, __exports__) {
7215
7371
  "use strict";
7216
7372
  var Promise = __dependency1__.Promise;
7217
7373
 
7218
-
7219
- function objectOrFunction(x) {
7220
- return typeof x === "function" || (typeof x === "object" && x !== null);
7221
- }
7222
-
7223
-
7224
7374
  function reject(reason) {
7225
7375
  return new Promise(function (resolve, reject) {
7226
7376
  reject(reason);
@@ -7230,48 +7380,21 @@ define("rsvp/reject",
7230
7380
 
7231
7381
  __exports__.reject = reject;
7232
7382
  });
7233
-
7234
7383
  define("rsvp/resolve",
7235
7384
  ["rsvp/promise","exports"],
7236
7385
  function(__dependency1__, __exports__) {
7237
7386
  "use strict";
7238
7387
  var Promise = __dependency1__.Promise;
7239
7388
 
7240
-
7241
- function objectOrFunction(x) {
7242
- return typeof x === "function" || (typeof x === "object" && x !== null);
7243
- }
7244
-
7245
- function resolve(thenable){
7246
- var promise = new Promise(function(resolve, reject){
7247
- var then;
7248
-
7249
- try {
7250
- if ( objectOrFunction(thenable) ) {
7251
- then = thenable.then;
7252
-
7253
- if (typeof then === "function") {
7254
- then.call(thenable, resolve, reject);
7255
- } else {
7256
- resolve(thenable);
7257
- }
7258
-
7259
- } else {
7260
- resolve(thenable);
7261
- }
7262
-
7263
- } catch(error) {
7264
- reject(error);
7265
- }
7389
+ function resolve(thenable) {
7390
+ return new Promise(function(resolve, reject) {
7391
+ resolve(thenable);
7266
7392
  });
7267
-
7268
- return promise;
7269
7393
  }
7270
7394
 
7271
7395
 
7272
7396
  __exports__.resolve = resolve;
7273
7397
  });
7274
-
7275
7398
  define("rsvp",
7276
7399
  ["rsvp/events","rsvp/promise","rsvp/node","rsvp/all","rsvp/hash","rsvp/defer","rsvp/config","rsvp/resolve","rsvp/reject","exports"],
7277
7400
  function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __exports__) {
@@ -7302,8 +7425,6 @@ define("rsvp",
7302
7425
  __exports__.reject = reject;
7303
7426
  });
7304
7427
 
7305
-
7306
-
7307
7428
  })();
7308
7429
 
7309
7430
  (function() {
@@ -7371,6 +7492,16 @@ define("container",
7371
7492
  this.dict[key] = value;
7372
7493
  },
7373
7494
 
7495
+ /**
7496
+ Delete the given key
7497
+
7498
+ @method remove
7499
+ @param {String} key
7500
+ */
7501
+ remove: function(key) {
7502
+ delete this.dict[key];
7503
+ },
7504
+
7374
7505
  /**
7375
7506
  Check for the existence of given a key, if the key is present at the current
7376
7507
  level return true, otherwise walk up the parent hierarchy and try again. If
@@ -7543,7 +7674,7 @@ define("container",
7543
7674
  register: function(type, name, factory, options) {
7544
7675
  var fullName;
7545
7676
 
7546
- if (type.indexOf(':') !== -1){
7677
+ if (type.indexOf(':') !== -1) {
7547
7678
  options = factory;
7548
7679
  factory = name;
7549
7680
  fullName = type;
@@ -7558,11 +7689,34 @@ define("container",
7558
7689
  this._options.set(normalizedName, options || {});
7559
7690
  },
7560
7691
 
7692
+ /**
7693
+ Unregister a fullName
7694
+
7695
+ ```javascript
7696
+ var container = new Container();
7697
+ container.register('model:user', User);
7698
+
7699
+ container.lookup('model:user') instanceof User //=> true
7700
+
7701
+ container.unregister('model:user')
7702
+ container.lookup('model:user') === undefined //=> true
7703
+
7704
+ @method unregister
7705
+ @param {String} fullName
7706
+ */
7707
+ unregister: function(fullName) {
7708
+ var normalizedName = this.normalize(fullName);
7709
+
7710
+ this.registry.remove(normalizedName);
7711
+ this.cache.remove(normalizedName);
7712
+ this._options.remove(normalizedName);
7713
+ },
7714
+
7561
7715
  /**
7562
7716
  Given a fullName return the corresponding factory.
7563
7717
 
7564
- By default `resolve` will retreive the factory from
7565
- it's containers registry.
7718
+ By default `resolve` will retrieve the factory from
7719
+ its container's registry.
7566
7720
 
7567
7721
  ```javascript
7568
7722
  var container = new Container();
@@ -7594,6 +7748,20 @@ define("container",
7594
7748
  return this.resolver(fullName) || this.registry.get(fullName);
7595
7749
  },
7596
7750
 
7751
+ /**
7752
+ A hook that can be used to describe how the resolver will
7753
+ attempt to find the factory.
7754
+
7755
+ For example, the default Ember `.describe` returns the full
7756
+ class name (including namespace) where Ember's resolver expects
7757
+ to find the `fullName`.
7758
+
7759
+ @method describe
7760
+ */
7761
+ describe: function(fullName) {
7762
+ return fullName;
7763
+ },
7764
+
7597
7765
  /**
7598
7766
  A hook to enable custom fullName normalization behaviour
7599
7767
 
@@ -8168,7 +8336,11 @@ Ember.copy = function(obj, deep) {
8168
8336
  @return {String} A description of the object
8169
8337
  */
8170
8338
  Ember.inspect = function(obj) {
8171
- if (typeof obj !== 'object' || obj === null) {
8339
+ var type = Ember.typeOf(obj);
8340
+ if (type === 'array') {
8341
+ return '[' + obj + ']';
8342
+ }
8343
+ if (type !== 'object') {
8172
8344
  return obj + '';
8173
8345
  }
8174
8346
 
@@ -8351,9 +8523,9 @@ Ember.String = {
8351
8523
  // first, replace any ORDERED replacements.
8352
8524
  var idx = 0; // the current index for non-numerical replacements
8353
8525
  return str.replace(/%@([0-9]+)?/g, function(s, argIndex) {
8354
- argIndex = (argIndex) ? parseInt(argIndex,0) - 1 : idx++ ;
8526
+ argIndex = (argIndex) ? parseInt(argIndex, 10) - 1 : idx++;
8355
8527
  s = formats[argIndex];
8356
- return ((s === null) ? '(null)' : (s === undefined) ? '' : s).toString();
8528
+ return (s === null) ? '(null)' : (s === undefined) ? '' : Ember.inspect(s);
8357
8529
  }) ;
8358
8530
  },
8359
8531
 
@@ -8871,14 +9043,10 @@ function iter(key, value) {
8871
9043
 
8872
9044
  @class Enumerable
8873
9045
  @namespace Ember
8874
- @extends Ember.Mixin
8875
9046
  @since Ember 0.9
8876
9047
  */
8877
9048
  Ember.Enumerable = Ember.Mixin.create({
8878
9049
 
8879
- // compatibility
8880
- isEnumerable: true,
8881
-
8882
9050
  /**
8883
9051
  Implement this method to make your class enumerable.
8884
9052
 
@@ -9350,7 +9518,7 @@ Ember.Enumerable = Ember.Mixin.create({
9350
9518
  @method some
9351
9519
  @param {Function} callback The callback to execute
9352
9520
  @param {Object} [target] The target object to use
9353
- @return {Array} A filtered array.
9521
+ @return {Boolean} `true` if the passed function returns `true` for any item
9354
9522
  */
9355
9523
  some: function(callback, target) {
9356
9524
  return !!this.find(function(x, idx, i) {
@@ -9365,7 +9533,7 @@ Ember.Enumerable = Ember.Mixin.create({
9365
9533
  @method someProperty
9366
9534
  @param {String} key the property to test
9367
9535
  @param {String} [value] optional value to test against.
9368
- @return {Boolean} `true`
9536
+ @return {Boolean} `true` if the passed function returns `true` for any item
9369
9537
  */
9370
9538
  someProperty: function(key, value) {
9371
9539
  return this.some(iter.apply(this, arguments));
@@ -9505,7 +9673,7 @@ Ember.Enumerable = Ember.Mixin.create({
9505
9673
  */
9506
9674
  uniq: function() {
9507
9675
  var ret = Ember.A();
9508
- this.forEach(function(k){
9676
+ this.forEach(function(k) {
9509
9677
  if (a_indexOf(ret, k)<0) ret.push(k);
9510
9678
  });
9511
9679
  return ret;
@@ -9709,7 +9877,6 @@ var get = Ember.get, set = Ember.set, isNone = Ember.isNone, map = Ember.Enumera
9709
9877
 
9710
9878
  @class Array
9711
9879
  @namespace Ember
9712
- @extends Ember.Mixin
9713
9880
  @uses Ember.Enumerable
9714
9881
  @since Ember 0.9.0
9715
9882
  */
@@ -9765,7 +9932,7 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
9765
9932
  */
9766
9933
  objectsAt: function(indexes) {
9767
9934
  var self = this;
9768
- return map(indexes, function(idx){ return self.objectAt(idx); });
9935
+ return map(indexes, function(idx) { return self.objectAt(idx); });
9769
9936
  },
9770
9937
 
9771
9938
  // overrides Ember.Enumerable version
@@ -9797,7 +9964,7 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
9797
9964
  }),
9798
9965
 
9799
9966
  // optimized version from Enumerable
9800
- contains: function(obj){
9967
+ contains: function(obj) {
9801
9968
  return this.indexOf(obj) >= 0;
9802
9969
  },
9803
9970
 
@@ -9862,7 +10029,7 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
9862
10029
  if (startAt < 0) startAt += len;
9863
10030
 
9864
10031
  for(idx=startAt;idx<len;idx++) {
9865
- if (this.objectAt(idx, true) === object) return idx ;
10032
+ if (this.objectAt(idx) === object) return idx ;
9866
10033
  }
9867
10034
  return -1;
9868
10035
  },
@@ -10107,20 +10274,10 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
10107
10274
 
10108
10275
  @class Comparable
10109
10276
  @namespace Ember
10110
- @extends Ember.Mixin
10111
10277
  @since Ember 0.9
10112
10278
  */
10113
10279
  Ember.Comparable = Ember.Mixin.create( /** @scope Ember.Comparable.prototype */{
10114
10280
 
10115
- /**
10116
- walk like a duck. Indicates that the object can be compared.
10117
-
10118
- @property isComparable
10119
- @type Boolean
10120
- @default true
10121
- */
10122
- isComparable: true,
10123
-
10124
10281
  /**
10125
10282
  Override to return the result of the comparison of the two parameters. The
10126
10283
  compare method should return:
@@ -10168,7 +10325,6 @@ var get = Ember.get, set = Ember.set;
10168
10325
 
10169
10326
  @class Copyable
10170
10327
  @namespace Ember
10171
- @extends Ember.Mixin
10172
10328
  @since Ember 0.9
10173
10329
  */
10174
10330
  Ember.Copyable = Ember.Mixin.create(/** @scope Ember.Copyable.prototype */ {
@@ -10273,7 +10429,6 @@ var get = Ember.get, set = Ember.set;
10273
10429
 
10274
10430
  @class Freezable
10275
10431
  @namespace Ember
10276
- @extends Ember.Mixin
10277
10432
  @since Ember 0.9
10278
10433
  */
10279
10434
  Ember.Freezable = Ember.Mixin.create(/** @scope Ember.Freezable.prototype */ {
@@ -10353,7 +10508,6 @@ var forEach = Ember.EnumerableUtils.forEach;
10353
10508
 
10354
10509
  @class MutableEnumerable
10355
10510
  @namespace Ember
10356
- @extends Ember.Mixin
10357
10511
  @uses Ember.Enumerable
10358
10512
  */
10359
10513
  Ember.MutableEnumerable = Ember.Mixin.create(Ember.Enumerable, {
@@ -10453,7 +10607,6 @@ var get = Ember.get, set = Ember.set;
10453
10607
 
10454
10608
  @class MutableArray
10455
10609
  @namespace Ember
10456
- @extends Ember.Mixin
10457
10610
  @uses Ember.Array
10458
10611
  @uses Ember.MutableEnumerable
10459
10612
  */
@@ -10523,7 +10676,7 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,/**
10523
10676
  method. You can pass either a single index, or a start and a length.
10524
10677
 
10525
10678
  If you pass a start and length that is beyond the
10526
- length this method will throw an `Ember.OUT_OF_RANGE_EXCEPTION`
10679
+ length this method will throw an `OUT_OF_RANGE_EXCEPTION`
10527
10680
 
10528
10681
  ```javascript
10529
10682
  var colors = ["red", "green", "blue", "yellow", "orange"];
@@ -10577,7 +10730,7 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,/**
10577
10730
 
10578
10731
  ```javascript
10579
10732
  var colors = ["red", "green", "blue"];
10580
- colors.pushObjects("black"); // ["red", "green", "blue", "black"]
10733
+ colors.pushObjects(["black"]); // ["red", "green", "blue", "black"]
10581
10734
  colors.pushObjects(["yellow", "orange"]); // ["red", "green", "blue", "black", "yellow", "orange"]
10582
10735
  ```
10583
10736
 
@@ -10586,6 +10739,9 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,/**
10586
10739
  @return {Ember.Array} receiver
10587
10740
  */
10588
10741
  pushObjects: function(objects) {
10742
+ if (!(Ember.Enumerable.detect(objects) || Ember.isArray(objects))) {
10743
+ throw new TypeError("Must pass Ember.Enumerable to Ember.MutableArray#pushObjects");
10744
+ }
10589
10745
  this.replace(get(this, 'length'), 0, objects);
10590
10746
  return this;
10591
10747
  },
@@ -10804,9 +10960,8 @@ var get = Ember.get, set = Ember.set;
10804
10960
 
10805
10961
  @class Observable
10806
10962
  @namespace Ember
10807
- @extends Ember.Mixin
10808
10963
  */
10809
- Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ {
10964
+ Ember.Observable = Ember.Mixin.create({
10810
10965
 
10811
10966
  /**
10812
10967
  Retrieves the value of a property from the object.
@@ -11004,7 +11159,7 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ {
11004
11159
  @param {String} keyName The property key that is about to change.
11005
11160
  @return {Ember.Observable}
11006
11161
  */
11007
- propertyWillChange: function(keyName){
11162
+ propertyWillChange: function(keyName) {
11008
11163
  Ember.propertyWillChange(this, keyName);
11009
11164
  return this;
11010
11165
  },
@@ -11310,7 +11465,7 @@ Ember.TargetActionSupport = Ember.Mixin.create({
11310
11465
  target: Ember.computed.alias('controller'),
11311
11466
  action: 'save',
11312
11467
  actionContext: Ember.computed.alias('context'),
11313
- click: function(){
11468
+ click: function() {
11314
11469
  this.triggerAction(); // Sends the `save` action, along with the current context
11315
11470
  // to the current controller
11316
11471
  }
@@ -11322,7 +11477,7 @@ Ember.TargetActionSupport = Ember.Mixin.create({
11322
11477
 
11323
11478
  ```javascript
11324
11479
  App.SaveButtonView = Ember.View.extend(Ember.TargetActionSupport, {
11325
- click: function(){
11480
+ click: function() {
11326
11481
  this.triggerAction({
11327
11482
  action: 'save',
11328
11483
  target: this.get('controller'),
@@ -11340,7 +11495,7 @@ Ember.TargetActionSupport = Ember.Mixin.create({
11340
11495
  ```javascript
11341
11496
  App.SaveButtonView = Ember.View.extend(Ember.TargetActionSupport, {
11342
11497
  target: Ember.computed.alias('controller'),
11343
- click: function(){
11498
+ click: function() {
11344
11499
  this.triggerAction({
11345
11500
  action: 'save'
11346
11501
  }); // Sends the `save` action, along with a reference to `this`,
@@ -11422,7 +11577,6 @@ Ember.TargetActionSupport = Ember.Mixin.create({
11422
11577
 
11423
11578
  @class Evented
11424
11579
  @namespace Ember
11425
- @extends Ember.Mixin
11426
11580
  */
11427
11581
  Ember.Evented = Ember.Mixin.create({
11428
11582
 
@@ -11540,8 +11694,8 @@ Ember.Evented = Ember.Mixin.create({
11540
11694
  (function() {
11541
11695
  var RSVP = requireModule("rsvp");
11542
11696
 
11543
- RSVP.configure('async', function(callback, binding) {
11544
- Ember.run.schedule('actions', binding, callback);
11697
+ RSVP.configure('async', function(callback, promise) {
11698
+ Ember.run.schedule('actions', promise, callback, promise);
11545
11699
  });
11546
11700
 
11547
11701
  /**
@@ -11554,7 +11708,6 @@ var get = Ember.get;
11554
11708
  /**
11555
11709
  @class Deferred
11556
11710
  @namespace Ember
11557
- @extends Ember.Mixin
11558
11711
  */
11559
11712
  Ember.DeferredMixin = Ember.Mixin.create({
11560
11713
  /**
@@ -11593,7 +11746,7 @@ Ember.DeferredMixin = Ember.Mixin.create({
11593
11746
  deferred = get(this, '_deferred');
11594
11747
  promise = deferred.promise;
11595
11748
 
11596
- if (value === this){
11749
+ if (value === this) {
11597
11750
  deferred.resolve(promise);
11598
11751
  } else {
11599
11752
  deferred.resolve(value);
@@ -11640,8 +11793,8 @@ Ember.Container.set = Ember.set;
11640
11793
  */
11641
11794
 
11642
11795
 
11643
- // NOTE: this object should never be included directly. Instead use Ember.
11644
- // Ember.Object. We only define this separately so that Ember.Set can depend on it
11796
+ // NOTE: this object should never be included directly. Instead use `Ember.Object`.
11797
+ // We only define this separately so that `Ember.Set` can depend on it.
11645
11798
 
11646
11799
 
11647
11800
  var set = Ember.set, get = Ember.get,
@@ -11786,6 +11939,10 @@ function makeCtor() {
11786
11939
 
11787
11940
  }
11788
11941
 
11942
+ /**
11943
+ @class CoreObject
11944
+ @namespace Ember
11945
+ */
11789
11946
  var CoreObject = makeCtor();
11790
11947
  CoreObject.toString = function() { return "Ember.CoreObject"; };
11791
11948
 
@@ -11982,7 +12139,7 @@ CoreObject.PrototypeMixin = Mixin.create({
11982
12139
  included in the output.
11983
12140
 
11984
12141
  App.Teacher = App.Person.extend({
11985
- toStringExtension: function(){
12142
+ toStringExtension: function() {
11986
12143
  return this.get('fullName');
11987
12144
  }
11988
12145
  });
@@ -12045,12 +12202,57 @@ var ClassMixin = Mixin.create({
12045
12202
  return Class;
12046
12203
  },
12047
12204
 
12205
+ /**
12206
+ Equivalent to doing `extend(arguments).create()`.
12207
+ If possible use the normal `create` method instead.
12208
+
12209
+ @method createWithMixins
12210
+ @static
12211
+ @param [arguments]*
12212
+ */
12048
12213
  createWithMixins: function() {
12049
12214
  var C = this;
12050
12215
  if (arguments.length>0) { this._initMixins(arguments); }
12051
12216
  return new C();
12052
12217
  },
12053
12218
 
12219
+ /**
12220
+ Creates an instance of a class. Accepts either no arguments, or an object
12221
+ containing values to initialize the newly instantiated object with.
12222
+
12223
+ ```javascript
12224
+ App.Person = Ember.Object.extend({
12225
+ helloWorld: function() {
12226
+ alert("Hi, my name is " + this.get('name'));
12227
+ }
12228
+ });
12229
+
12230
+ var tom = App.Person.create({
12231
+ name: 'Tom Dale'
12232
+ });
12233
+
12234
+ tom.helloWorld(); // alerts "Hi, my name is Tom Dale".
12235
+ ```
12236
+
12237
+ `create` will call the `init` function if defined during
12238
+ `Ember.AnyObject.extend`
12239
+
12240
+ If no arguments are passed to `create`, it will not set values to the new
12241
+ instance during initialization:
12242
+
12243
+ ```javascript
12244
+ var noName = App.Person.create();
12245
+ noName.helloWorld(); // alerts undefined
12246
+ ```
12247
+
12248
+ NOTE: For performance reasons, you cannot declare methods or computed
12249
+ properties during `create`. You should instead declare methods and computed
12250
+ properties when using `extend` or use the `createWithMixins` shorthand.
12251
+
12252
+ @method create
12253
+ @static
12254
+ @param [arguments]*
12255
+ */
12054
12256
  create: function() {
12055
12257
  var C = this;
12056
12258
  if (arguments.length>0) { this._initProperties(arguments); }
@@ -12150,10 +12352,6 @@ if (Ember.config.overrideClassMixin) {
12150
12352
  CoreObject.ClassMixin = ClassMixin;
12151
12353
  ClassMixin.apply(CoreObject);
12152
12354
 
12153
- /**
12154
- @class CoreObject
12155
- @namespace Ember
12156
- */
12157
12355
  Ember.CoreObject = CoreObject;
12158
12356
 
12159
12357
  })();
@@ -12673,6 +12871,9 @@ Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,/** @scope Ember.Array
12673
12871
  },
12674
12872
 
12675
12873
  pushObjects: function(objects) {
12874
+ if (!(Ember.Enumerable.detect(objects) || Ember.isArray(objects))) {
12875
+ throw new TypeError("Must pass Ember.Enumerable to Ember.MutableArray#pushObjects");
12876
+ }
12676
12877
  this._replace(get(this, 'length'), 0, objects);
12677
12878
  return this;
12678
12879
  },
@@ -12925,6 +13126,7 @@ function addObserverForContentKey(content, keyName, proxy, idx, loc) {
12925
13126
  while(--loc>=idx) {
12926
13127
  var item = content.objectAt(loc);
12927
13128
  if (item) {
13129
+ Ember.assert('When using @each to observe the array ' + content + ', the array must return an object', Ember.typeOf(item) === 'instance' || Ember.typeOf(item) === 'object');
12928
13130
  Ember.addBeforeObserver(item, keyName, proxy, 'contentKeyWillChange');
12929
13131
  Ember.addObserver(item, keyName, proxy, 'contentKeyDidChange');
12930
13132
 
@@ -13008,7 +13210,7 @@ Ember.EachProxy = Ember.Object.extend({
13008
13210
  for(key in keys) {
13009
13211
  if (!keys.hasOwnProperty(key)) { continue; }
13010
13212
 
13011
- if (lim>0) removeObserverForContentKey(content, key, this, idx, lim);
13213
+ if (lim>0) { removeObserverForContentKey(content, key, this, idx, lim); }
13012
13214
 
13013
13215
  Ember.propertyWillChange(this, key);
13014
13216
  }
@@ -13018,21 +13220,20 @@ Ember.EachProxy = Ember.Object.extend({
13018
13220
  },
13019
13221
 
13020
13222
  arrayDidChange: function(content, idx, removedCnt, addedCnt) {
13021
- var keys = this._keys, key, lim;
13223
+ var keys = this._keys, lim;
13022
13224
 
13023
13225
  lim = addedCnt>0 ? idx+addedCnt : -1;
13024
- Ember.beginPropertyChanges(this);
13025
-
13026
- for(key in keys) {
13027
- if (!keys.hasOwnProperty(key)) { continue; }
13226
+ Ember.changeProperties(function() {
13227
+ for(var key in keys) {
13228
+ if (!keys.hasOwnProperty(key)) { continue; }
13028
13229
 
13029
- if (lim>0) addObserverForContentKey(content, key, this, idx, lim);
13230
+ if (lim>0) { addObserverForContentKey(content, key, this, idx, lim); }
13030
13231
 
13031
- Ember.propertyDidChange(this, key);
13032
- }
13232
+ Ember.propertyDidChange(this, key);
13233
+ }
13033
13234
 
13034
- Ember.propertyDidChange(this._content, '@each');
13035
- Ember.endPropertyChanges(this);
13235
+ Ember.propertyDidChange(this._content, '@each');
13236
+ }, this);
13036
13237
  },
13037
13238
 
13038
13239
  // ..........................................................
@@ -13181,7 +13382,7 @@ var NativeArray = Ember.Mixin.create(Ember.MutableArray, Ember.Observable, Ember
13181
13382
 
13182
13383
  copy: function(deep) {
13183
13384
  if (deep) {
13184
- return this.map(function(item){ return Ember.copy(item, true); });
13385
+ return this.map(function(item) { return Ember.copy(item, true); });
13185
13386
  }
13186
13387
 
13187
13388
  return this.slice();
@@ -13207,7 +13408,6 @@ if (ignore.length>0) {
13207
13408
 
13208
13409
  @class NativeArray
13209
13410
  @namespace Ember
13210
- @extends Ember.Mixin
13211
13411
  @uses Ember.MutableArray
13212
13412
  @uses Ember.Observable
13213
13413
  @uses Ember.Copyable
@@ -13222,7 +13422,7 @@ Ember.NativeArray = NativeArray;
13222
13422
  @for Ember
13223
13423
  @return {Ember.NativeArray}
13224
13424
  */
13225
- Ember.A = function(arr){
13425
+ Ember.A = function(arr) {
13226
13426
  if (arr === undefined) { arr = []; }
13227
13427
  return Ember.Array.detect(arr) ? arr : Ember.NativeArray.apply(arr);
13228
13428
  };
@@ -13398,7 +13598,7 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
13398
13598
  Ember.propertyWillChange(this, 'firstObject');
13399
13599
  Ember.propertyWillChange(this, 'lastObject');
13400
13600
 
13401
- for (var i=0; i < len; i++){
13601
+ for (var i=0; i < len; i++) {
13402
13602
  guid = guidFor(this[i]);
13403
13603
  delete this[guid];
13404
13604
  delete this[i];
@@ -13818,7 +14018,6 @@ var get = Ember.get;
13818
14018
 
13819
14019
  @class ControllerMixin
13820
14020
  @namespace Ember
13821
- @extends Ember.Mixin
13822
14021
  */
13823
14022
  Ember.ControllerMixin = Ember.Mixin.create({
13824
14023
  /* ducktype as a controller */
@@ -13852,7 +14051,7 @@ Ember.ControllerMixin = Ember.Mixin.create({
13852
14051
  if (this[actionName]) {
13853
14052
  Ember.assert("The controller " + this + " does not have the action " + actionName, typeof this[actionName] === 'function');
13854
14053
  this[actionName].apply(this, args);
13855
- } else if(target = get(this, 'target')) {
14054
+ } else if (target = get(this, 'target')) {
13856
14055
  Ember.assert("The target for controller " + this + " (" + target + ") did not define a `send` method", typeof target.send === 'function');
13857
14056
  target.send.apply(target, arguments);
13858
14057
  }
@@ -13906,7 +14105,6 @@ var get = Ember.get, set = Ember.set, forEach = Ember.EnumerableUtils.forEach;
13906
14105
 
13907
14106
  @class SortableMixin
13908
14107
  @namespace Ember
13909
- @extends Ember.Mixin
13910
14108
  @uses Ember.MutableEnumerable
13911
14109
  */
13912
14110
  Ember.SortableMixin = Ember.Mixin.create(Ember.MutableEnumerable, {
@@ -13924,7 +14122,7 @@ Ember.SortableMixin = Ember.Mixin.create(Ember.MutableEnumerable, {
13924
14122
  @property {Boolean} sortAscending
13925
14123
  */
13926
14124
  sortAscending: true,
13927
-
14125
+
13928
14126
  /**
13929
14127
  The function used to compare two values. You can override this if you
13930
14128
  want to do custom comparisons.Functions must be of the type expected by
@@ -13934,8 +14132,8 @@ Ember.SortableMixin = Ember.Mixin.create(Ember.MutableEnumerable, {
13934
14132
  return a positive value otherwise:
13935
14133
 
13936
14134
  ```javascript
13937
- function(x,y){ // These are assumed to be integers
13938
- if(x === y)
14135
+ function(x,y) { // These are assumed to be integers
14136
+ if (x === y)
13939
14137
  return 0;
13940
14138
  return x < y ? -1 : 1;
13941
14139
  }
@@ -13946,7 +14144,7 @@ Ember.SortableMixin = Ember.Mixin.create(Ember.MutableEnumerable, {
13946
14144
  @default Ember.compare
13947
14145
  */
13948
14146
  sortFunction: Ember.compare,
13949
-
14147
+
13950
14148
  orderBy: function(item1, item2) {
13951
14149
  var result = 0,
13952
14150
  sortProperties = get(this, 'sortProperties'),
@@ -14441,7 +14639,7 @@ if (Ember.$) {
14441
14639
  // is a "zero-scope" element. This problem can be worked around by making
14442
14640
  // the first node an invisible text node. We, like Modernizr, use &shy;
14443
14641
 
14444
- var needsShy = this.document && (function(){
14642
+ var needsShy = this.document && (function() {
14445
14643
  var testEl = document.createElement('div');
14446
14644
  testEl.innerHTML = "<div></div>";
14447
14645
  testEl.firstChild.innerHTML = "<script></script>";
@@ -14597,6 +14795,45 @@ ClassSet.prototype = {
14597
14795
  }
14598
14796
  };
14599
14797
 
14798
+ var BAD_TAG_NAME_TEST_REGEXP = /[^a-zA-Z0-9\-]/;
14799
+ var BAD_TAG_NAME_REPLACE_REGEXP = /[^a-zA-Z0-9\-]/g;
14800
+
14801
+ function stripTagName(tagName) {
14802
+ if (!tagName) {
14803
+ return tagName;
14804
+ }
14805
+
14806
+ if (!BAD_TAG_NAME_TEST_REGEXP.test(tagName)) {
14807
+ return tagName;
14808
+ }
14809
+
14810
+ return tagName.replace(BAD_TAG_NAME_REPLACE_REGEXP, '');
14811
+ }
14812
+
14813
+ var BAD_CHARS_REGEXP = /&(?!\w+;)|[<>"'`]/g;
14814
+ var POSSIBLE_CHARS_REGEXP = /[&<>"'`]/;
14815
+
14816
+ function escapeAttribute(value) {
14817
+ // Stolen shamelessly from Handlebars
14818
+
14819
+ var escape = {
14820
+ "<": "&lt;",
14821
+ ">": "&gt;",
14822
+ '"': "&quot;",
14823
+ "'": "&#x27;",
14824
+ "`": "&#x60;"
14825
+ };
14826
+
14827
+ var escapeChar = function(chr) {
14828
+ return escape[chr] || "&amp;";
14829
+ };
14830
+
14831
+ var string = value.toString();
14832
+
14833
+ if(!POSSIBLE_CHARS_REGEXP.test(string)) { return string; }
14834
+ return string.replace(BAD_CHARS_REGEXP, escapeChar);
14835
+ }
14836
+
14600
14837
  /**
14601
14838
  `Ember.RenderBuffer` gathers information regarding the a view and generates the
14602
14839
  final representation. `Ember.RenderBuffer` will generate HTML which can be pushed
@@ -14884,14 +15121,14 @@ Ember._RenderBuffer.prototype =
14884
15121
  style = this.elementStyle,
14885
15122
  attr, prop;
14886
15123
 
14887
- buffer += '<' + tagName;
15124
+ buffer += '<' + stripTagName(tagName);
14888
15125
 
14889
15126
  if (id) {
14890
- buffer += ' id="' + this._escapeAttribute(id) + '"';
15127
+ buffer += ' id="' + escapeAttribute(id) + '"';
14891
15128
  this.elementId = null;
14892
15129
  }
14893
15130
  if (classes) {
14894
- buffer += ' class="' + this._escapeAttribute(classes.join(' ')) + '"';
15131
+ buffer += ' class="' + escapeAttribute(classes.join(' ')) + '"';
14895
15132
  this.classes = null;
14896
15133
  }
14897
15134
 
@@ -14900,7 +15137,7 @@ Ember._RenderBuffer.prototype =
14900
15137
 
14901
15138
  for (prop in style) {
14902
15139
  if (style.hasOwnProperty(prop)) {
14903
- buffer += prop + ':' + this._escapeAttribute(style[prop]) + ';';
15140
+ buffer += prop + ':' + escapeAttribute(style[prop]) + ';';
14904
15141
  }
14905
15142
  }
14906
15143
 
@@ -14912,7 +15149,7 @@ Ember._RenderBuffer.prototype =
14912
15149
  if (attrs) {
14913
15150
  for (attr in attrs) {
14914
15151
  if (attrs.hasOwnProperty(attr)) {
14915
- buffer += ' ' + attr + '="' + this._escapeAttribute(attrs[attr]) + '"';
15152
+ buffer += ' ' + attr + '="' + escapeAttribute(attrs[attr]) + '"';
14916
15153
  }
14917
15154
  }
14918
15155
 
@@ -14927,7 +15164,7 @@ Ember._RenderBuffer.prototype =
14927
15164
  if (value === true) {
14928
15165
  buffer += ' ' + prop + '="' + prop + '"';
14929
15166
  } else {
14930
- buffer += ' ' + prop + '="' + this._escapeAttribute(props[prop]) + '"';
15167
+ buffer += ' ' + prop + '="' + escapeAttribute(props[prop]) + '"';
14931
15168
  }
14932
15169
  }
14933
15170
  }
@@ -14942,7 +15179,7 @@ Ember._RenderBuffer.prototype =
14942
15179
 
14943
15180
  pushClosingTag: function() {
14944
15181
  var tagName = this.tagNames.pop();
14945
- if (tagName) { this.buffer += '</' + tagName + '>'; }
15182
+ if (tagName) { this.buffer += '</' + stripTagName(tagName) + '>'; }
14946
15183
  },
14947
15184
 
14948
15185
  currentTagName: function() {
@@ -15029,7 +15266,7 @@ Ember._RenderBuffer.prototype =
15029
15266
  if (this._hasElement && this._element) {
15030
15267
  // Firefox versions < 11 do not have support for element.outerHTML.
15031
15268
  var thisElement = this.element(), outerHTML = thisElement.outerHTML;
15032
- if (typeof outerHTML === 'undefined'){
15269
+ if (typeof outerHTML === 'undefined') {
15033
15270
  return Ember.$('<div/>').append(thisElement).html();
15034
15271
  }
15035
15272
  return outerHTML;
@@ -15040,32 +15277,7 @@ Ember._RenderBuffer.prototype =
15040
15277
 
15041
15278
  innerString: function() {
15042
15279
  return this.buffer;
15043
- },
15044
-
15045
- _escapeAttribute: function(value) {
15046
- // Stolen shamelessly from Handlebars
15047
-
15048
- var escape = {
15049
- "<": "&lt;",
15050
- ">": "&gt;",
15051
- '"': "&quot;",
15052
- "'": "&#x27;",
15053
- "`": "&#x60;"
15054
- };
15055
-
15056
- var badChars = /&(?!\w+;)|[<>"'`]/g;
15057
- var possible = /[&<>"'`]/;
15058
-
15059
- var escapeChar = function(chr) {
15060
- return escape[chr] || "&amp;";
15061
- };
15062
-
15063
- var string = value.toString();
15064
-
15065
- if(!possible.test(string)) { return string; }
15066
- return string.replace(badChars, escapeChar);
15067
15280
  }
15068
-
15069
15281
  };
15070
15282
 
15071
15283
  })();
@@ -15381,8 +15593,11 @@ var childViewsProperty = Ember.computed(function() {
15381
15593
  var childViews = this._childViews, ret = Ember.A(), view = this;
15382
15594
 
15383
15595
  a_forEach(childViews, function(view) {
15596
+ var currentChildViews;
15384
15597
  if (view.isVirtual) {
15385
- ret.pushObjects(get(view, 'childViews'));
15598
+ if (currentChildViews = get(view, 'childViews')) {
15599
+ ret.pushObjects(currentChildViews);
15600
+ }
15386
15601
  } else {
15387
15602
  ret.push(view);
15388
15603
  }
@@ -15677,8 +15892,8 @@ class:
15677
15892
  MyView = Ember.View.extend({
15678
15893
  classNameBindings: ['propertyA', 'propertyB'],
15679
15894
  propertyA: 'from-a',
15680
- propertyB: function(){
15681
- if(someLogic){ return 'from-b'; }
15895
+ propertyB: function() {
15896
+ if (someLogic) { return 'from-b'; }
15682
15897
  }.property()
15683
15898
  });
15684
15899
  ```
@@ -15859,7 +16074,7 @@ class:
15859
16074
  MyTextInput = Ember.View.extend({
15860
16075
  tagName: 'input',
15861
16076
  attributeBindings: ['disabled'],
15862
- disabled: function(){
16077
+ disabled: function() {
15863
16078
  if (someLogic) {
15864
16079
  return true;
15865
16080
  } else {
@@ -15968,7 +16183,7 @@ class:
15968
16183
 
15969
16184
  aController = Ember.Object.create({
15970
16185
  firstName: 'Barry',
15971
- excitedGreeting: function(){
16186
+ excitedGreeting: function() {
15972
16187
  return this.get("content.firstName") + "!!!"
15973
16188
  }.property()
15974
16189
  });
@@ -16039,7 +16254,7 @@ class:
16039
16254
 
16040
16255
  ```javascript
16041
16256
  AView = Ember.View.extend({
16042
- click: function(event){
16257
+ click: function(event) {
16043
16258
  // will be called when when an instance's
16044
16259
  // rendered element is clicked
16045
16260
  }
@@ -16060,7 +16275,7 @@ class:
16060
16275
  ```javascript
16061
16276
  AView = Ember.View.extend({
16062
16277
  eventManager: Ember.Object.create({
16063
- doubleClick: function(event, view){
16278
+ doubleClick: function(event, view) {
16064
16279
  // will be called when when an instance's
16065
16280
  // rendered element or any rendering
16066
16281
  // of this views's descendent
@@ -16075,11 +16290,11 @@ class:
16075
16290
 
16076
16291
  ```javascript
16077
16292
  AView = Ember.View.extend({
16078
- mouseEnter: function(event){
16293
+ mouseEnter: function(event) {
16079
16294
  // will never trigger.
16080
16295
  },
16081
16296
  eventManager: Ember.Object.create({
16082
- mouseEnter: function(event, view){
16297
+ mouseEnter: function(event, view) {
16083
16298
  // takes presedence over AView#mouseEnter
16084
16299
  }
16085
16300
  })
@@ -16097,7 +16312,7 @@ class:
16097
16312
  OuterView = Ember.View.extend({
16098
16313
  template: Ember.Handlebars.compile("outer {{#view InnerView}}inner{{/view}} outer"),
16099
16314
  eventManager: Ember.Object.create({
16100
- mouseEnter: function(event, view){
16315
+ mouseEnter: function(event, view) {
16101
16316
  // view might be instance of either
16102
16317
  // OuterView or InnerView depending on
16103
16318
  // where on the page the user interaction occured
@@ -16106,12 +16321,12 @@ class:
16106
16321
  });
16107
16322
 
16108
16323
  InnerView = Ember.View.extend({
16109
- click: function(event){
16324
+ click: function(event) {
16110
16325
  // will be called if rendered inside
16111
16326
  // an OuterView because OuterView's
16112
16327
  // eventManager doesn't handle click events
16113
16328
  },
16114
- mouseEnter: function(event){
16329
+ mouseEnter: function(event) {
16115
16330
  // will never be called if rendered inside
16116
16331
  // an OuterView.
16117
16332
  }
@@ -16321,6 +16536,14 @@ Ember.View = Ember.CoreView.extend(
16321
16536
  }
16322
16537
  }).volatile(),
16323
16538
 
16539
+ /**
16540
+ The parent context for this template.
16541
+ */
16542
+ parentContext: function() {
16543
+ var parentView = get(this, '_parentView');
16544
+ return parentView && get(parentView, '_context');
16545
+ },
16546
+
16324
16547
  /**
16325
16548
  @private
16326
16549
 
@@ -16422,7 +16645,7 @@ Ember.View = Ember.CoreView.extend(
16422
16645
  var view = get(this, 'parentView');
16423
16646
 
16424
16647
  while (view) {
16425
- if(view instanceof klass) { return view; }
16648
+ if (view instanceof klass) { return view; }
16426
16649
  view = get(view, 'parentView');
16427
16650
  }
16428
16651
  },
@@ -16443,7 +16666,7 @@ Ember.View = Ember.CoreView.extend(
16443
16666
  function(view) { return klass.detect(view.constructor); };
16444
16667
 
16445
16668
  while (view) {
16446
- if( isOfType(view) ) { return view; }
16669
+ if (isOfType(view)) { return view; }
16447
16670
  view = get(view, 'parentView');
16448
16671
  }
16449
16672
  },
@@ -16476,7 +16699,7 @@ Ember.View = Ember.CoreView.extend(
16476
16699
  var view = get(this, 'parentView');
16477
16700
 
16478
16701
  while (view) {
16479
- if(get(view, 'parentView') instanceof klass) { return view; }
16702
+ if (get(view, 'parentView') instanceof klass) { return view; }
16480
16703
  view = get(view, 'parentView');
16481
16704
  }
16482
16705
  },
@@ -16999,7 +17222,7 @@ Ember.View = Ember.CoreView.extend(
16999
17222
  */
17000
17223
  invokeRecursively: function(fn, includeSelf) {
17001
17224
  var childViews = (includeSelf === false) ? this._childViews : [this];
17002
- var currentViews, view;
17225
+ var currentViews, view, currentChildViews;
17003
17226
 
17004
17227
  while (childViews.length) {
17005
17228
  currentViews = childViews.slice();
@@ -17007,16 +17230,17 @@ Ember.View = Ember.CoreView.extend(
17007
17230
 
17008
17231
  for (var i=0, l=currentViews.length; i<l; i++) {
17009
17232
  view = currentViews[i];
17233
+ currentChildViews = view._childViews ? view._childViews.slice(0) : null;
17010
17234
  fn(view);
17011
- if (view._childViews) {
17012
- childViews.push.apply(childViews, view._childViews);
17235
+ if (currentChildViews) {
17236
+ childViews.push.apply(childViews, currentChildViews);
17013
17237
  }
17014
17238
  }
17015
17239
  }
17016
17240
  },
17017
17241
 
17018
17242
  triggerRecursively: function(eventName) {
17019
- var childViews = [this], currentViews, view;
17243
+ var childViews = [this], currentViews, view, currentChildViews;
17020
17244
 
17021
17245
  while (childViews.length) {
17022
17246
  currentViews = childViews.slice();
@@ -17024,10 +17248,12 @@ Ember.View = Ember.CoreView.extend(
17024
17248
 
17025
17249
  for (var i=0, l=currentViews.length; i<l; i++) {
17026
17250
  view = currentViews[i];
17251
+ currentChildViews = view._childViews ? view._childViews.slice(0) : null;
17027
17252
  if (view.trigger) { view.trigger(eventName); }
17028
- if (view._childViews) {
17029
- childViews.push.apply(childViews, view._childViews);
17253
+ if (currentChildViews) {
17254
+ childViews.push.apply(childViews, currentChildViews);
17030
17255
  }
17256
+
17031
17257
  }
17032
17258
  }
17033
17259
  },
@@ -17074,7 +17300,7 @@ Ember.View = Ember.CoreView.extend(
17074
17300
 
17075
17301
  @event willDestroyElement
17076
17302
  */
17077
- willDestroyElement: function() {},
17303
+ willDestroyElement: Ember.K,
17078
17304
 
17079
17305
  /**
17080
17306
  @private
@@ -17586,7 +17812,7 @@ Ember.View = Ember.CoreView.extend(
17586
17812
  }
17587
17813
 
17588
17814
  var view = this,
17589
- stateCheckedObserver = function(){
17815
+ stateCheckedObserver = function() {
17590
17816
  view.currentState.invokeObserver(this, observer);
17591
17817
  },
17592
17818
  scheduledObserver = function() {
@@ -18847,7 +19073,7 @@ Ember.CollectionView = Ember.ContainerView.extend(/** @scope Ember.CollectionVie
18847
19073
  var content = get(this, 'content');
18848
19074
 
18849
19075
  if (content) {
18850
- Ember.assert(fmt("an Ember.CollectionView's content must implement Ember.Array. You passed %@", [content]), Ember.Array.detect(content));
19076
+ this._assertArrayLike(content);
18851
19077
  content.addArrayObserver(this);
18852
19078
  }
18853
19079
 
@@ -18855,6 +19081,10 @@ Ember.CollectionView = Ember.ContainerView.extend(/** @scope Ember.CollectionVie
18855
19081
  this.arrayDidChange(content, 0, null, len);
18856
19082
  }, 'content'),
18857
19083
 
19084
+ _assertArrayLike: function(content) {
19085
+ Ember.assert(fmt("an Ember.CollectionView's content must implement Ember.Array. You passed %@", [content]), Ember.Array.detect(content));
19086
+ },
19087
+
18858
19088
  destroy: function() {
18859
19089
  if (!this._super()) { return; }
18860
19090
 
@@ -18987,6 +19217,8 @@ Ember.CollectionView.CONTAINER_MAP = {
18987
19217
 
18988
19218
 
18989
19219
  (function() {
19220
+ var get = Ember.get, set = Ember.set, isNone = Ember.isNone;
19221
+
18990
19222
  /**
18991
19223
  @module ember
18992
19224
  @submodule ember-views
@@ -19070,11 +19302,66 @@ Ember.CollectionView.CONTAINER_MAP = {
19070
19302
  @namespace Ember
19071
19303
  @extends Ember.View
19072
19304
  */
19073
- Ember.Component = Ember.View.extend({
19305
+ Ember.Component = Ember.View.extend(Ember.TargetActionSupport, {
19074
19306
  init: function() {
19075
19307
  this._super();
19076
- this.set('context', this);
19077
- this.set('controller', this);
19308
+ set(this, 'context', this);
19309
+ set(this, 'controller', this);
19310
+ set(this, 'templateData', {keywords: {}});
19311
+ },
19312
+
19313
+ targetObject: Ember.computed(function(key) {
19314
+ var parentView = get(this, '_parentView');
19315
+ return parentView ? get(parentView, 'controller') : null;
19316
+ }).property('_parentView'),
19317
+
19318
+ /**
19319
+ Sends an action to component's controller. A component inherits its
19320
+ controller from the context in which it is used.
19321
+
19322
+ By default, calling `sendAction()` will send an action with the name
19323
+ of the component's `action` property.
19324
+
19325
+ For example, if the component had a property `action` with the value
19326
+ `"addItem"`, calling `sendAction()` would send the `addItem` action
19327
+ to the component's controller.
19328
+
19329
+ If you provide an argument to `sendAction()`, that key will be used to look
19330
+ up the action name.
19331
+
19332
+ For example, if the component had a property `playing` with the value
19333
+ `didStartPlaying`, calling `sendAction('playing')` would send the
19334
+ `didStartPlaying` action to the component's controller.
19335
+
19336
+ Whether or not you are using the default action or a named action, if
19337
+ the action name is not defined on the component, calling `sendAction()`
19338
+ does not have any effect.
19339
+
19340
+ For example, if you call `sendAction()` on a component that does not have
19341
+ an `action` property defined, no action will be sent to the controller,
19342
+ nor will an exception be raised.
19343
+
19344
+ @param [action] {String} the action to trigger
19345
+ */
19346
+ sendAction: function(action) {
19347
+ var actionName;
19348
+
19349
+ // Send the default action
19350
+ if (action === undefined) {
19351
+ actionName = get(this, 'action');
19352
+ Ember.assert("The default action was triggered on the component " + this.toString() + ", but the action name (" + actionName + ") was not a string.", isNone(actionName) || typeof actionName === 'string');
19353
+ } else {
19354
+ actionName = get(this, action);
19355
+ Ember.assert("The " + action + " action was triggered on the component " + this.toString() + ", but the action name (" + actionName + ") was not a string.", isNone(actionName) || typeof actionName === 'string');
19356
+ }
19357
+
19358
+
19359
+ // If no action name for that action could be found, just abort.
19360
+ if (actionName === undefined) { return; }
19361
+
19362
+ this.triggerAction({
19363
+ action: actionName
19364
+ });
19078
19365
  }
19079
19366
  });
19080
19367
 
@@ -19105,7 +19392,7 @@ For example:
19105
19392
  ```javascript
19106
19393
  App.SaveButtonView = Ember.View.extend(Ember.ViewTargetActionSupport, {
19107
19394
  action: 'save',
19108
- click: function(){
19395
+ click: function() {
19109
19396
  this.triggerAction(); // Sends the `save` action, along with the current context
19110
19397
  // to the current controller
19111
19398
  }
@@ -19117,7 +19404,7 @@ to `triggerAction` as well.
19117
19404
 
19118
19405
  ```javascript
19119
19406
  App.SaveButtonView = Ember.View.extend(Ember.ViewTargetActionSupport, {
19120
- click: function(){
19407
+ click: function() {
19121
19408
  this.triggerAction({
19122
19409
  action: 'save'
19123
19410
  }); // Sends the `save` action, along with the current context
@@ -19386,7 +19673,7 @@ Ember.State.reopenClass({
19386
19673
 
19387
19674
  bManager = Ember.StateManager.create({
19388
19675
  stateOne: Ember.State.create({
19389
- changeToStateTwo: function(manager, context){
19676
+ changeToStateTwo: function(manager, context) {
19390
19677
  manager.transitionTo('stateTwo', context)
19391
19678
  }
19392
19679
  }),
@@ -19714,7 +20001,7 @@ var sendEvent = function(eventName, sendRecursiveArguments, isUnhandledPass) {
19714
20001
 
19715
20002
  ```javascript
19716
20003
  managerC = Ember.StateManager.create({
19717
- initialState: function(){
20004
+ initialState: function() {
19718
20005
  if (someLogic) {
19719
20006
  return 'active';
19720
20007
  } else {
@@ -19757,12 +20044,12 @@ var sendEvent = function(eventName, sendRecursiveArguments, isUnhandledPass) {
19757
20044
  robotManager = Ember.StateManager.create({
19758
20045
  initialState: 'poweredDown',
19759
20046
  poweredDown: Ember.State.create({
19760
- exit: function(stateManager){
20047
+ exit: function(stateManager) {
19761
20048
  console.log("exiting the poweredDown state")
19762
20049
  }
19763
20050
  }),
19764
20051
  poweredUp: Ember.State.create({
19765
- enter: function(stateManager){
20052
+ enter: function(stateManager) {
19766
20053
  console.log("entering the poweredUp state. Destroy all humans.")
19767
20054
  }
19768
20055
  })
@@ -19785,12 +20072,12 @@ var sendEvent = function(eventName, sendRecursiveArguments, isUnhandledPass) {
19785
20072
  robotManager = Ember.StateManager.create({
19786
20073
  initialState: 'poweredDown',
19787
20074
  poweredDown: Ember.State.create({
19788
- exit: function(stateManager){
20075
+ exit: function(stateManager) {
19789
20076
  console.log("exiting the poweredDown state")
19790
20077
  }
19791
20078
  }),
19792
20079
  poweredUp: Ember.State.create({
19793
- enter: function(stateManager){
20080
+ enter: function(stateManager) {
19794
20081
  console.log("entering the poweredUp state. Destroy all humans.")
19795
20082
  }
19796
20083
  })
@@ -19853,37 +20140,37 @@ var sendEvent = function(eventName, sendRecursiveArguments, isUnhandledPass) {
19853
20140
  robotManager = Ember.StateManager.create({
19854
20141
  initialState: 'poweredDown',
19855
20142
  poweredDown: Ember.State.create({
19856
- enter: function(){},
19857
- exit: function(){
20143
+ enter: function() {},
20144
+ exit: function() {
19858
20145
  console.log("exited poweredDown state")
19859
20146
  },
19860
20147
  charging: Ember.State.create({
19861
- enter: function(){},
19862
- exit: function(){}
20148
+ enter: function() {},
20149
+ exit: function() {}
19863
20150
  }),
19864
20151
  charged: Ember.State.create({
19865
- enter: function(){
20152
+ enter: function() {
19866
20153
  console.log("entered charged state")
19867
20154
  },
19868
- exit: function(){
20155
+ exit: function() {
19869
20156
  console.log("exited charged state")
19870
20157
  }
19871
20158
  })
19872
20159
  }),
19873
20160
  poweredUp: Ember.State.create({
19874
- enter: function(){
20161
+ enter: function() {
19875
20162
  console.log("entered poweredUp state")
19876
20163
  },
19877
- exit: function(){},
20164
+ exit: function() {},
19878
20165
  mobile: Ember.State.create({
19879
- enter: function(){
20166
+ enter: function() {
19880
20167
  console.log("entered mobile state")
19881
20168
  },
19882
- exit: function(){}
20169
+ exit: function() {}
19883
20170
  }),
19884
20171
  stationary: Ember.State.create({
19885
- enter: function(){},
19886
- exit: function(){}
20172
+ enter: function() {},
20173
+ exit: function() {}
19887
20174
  })
19888
20175
  })
19889
20176
  })
@@ -19931,7 +20218,7 @@ var sendEvent = function(eventName, sendRecursiveArguments, isUnhandledPass) {
19931
20218
  initialState: 'stateOne.substateOne.subsubstateOne',
19932
20219
  stateOne: Ember.State.create({
19933
20220
  substateOne: Ember.State.create({
19934
- anAction: function(manager, context){
20221
+ anAction: function(manager, context) {
19935
20222
  console.log("an action was called")
19936
20223
  },
19937
20224
  subsubstateOne: Ember.State.create({})
@@ -19994,7 +20281,7 @@ var sendEvent = function(eventName, sendRecursiveArguments, isUnhandledPass) {
19994
20281
  })
19995
20282
  }),
19996
20283
  stateTwo: Ember.State.create({
19997
- anAction: function(manager, context){
20284
+ anAction: function(manager, context) {
19998
20285
  // will not be called below because it is
19999
20286
  // not a parent of the current state
20000
20287
  }
@@ -20015,18 +20302,18 @@ var sendEvent = function(eventName, sendRecursiveArguments, isUnhandledPass) {
20015
20302
  initialState: 'poweredDown.charging',
20016
20303
  poweredDown: Ember.State.create({
20017
20304
  charging: Ember.State.create({
20018
- chargeComplete: function(manager, context){
20305
+ chargeComplete: function(manager, context) {
20019
20306
  manager.transitionTo('charged')
20020
20307
  }
20021
20308
  }),
20022
20309
  charged: Ember.State.create({
20023
- boot: function(manager, context){
20310
+ boot: function(manager, context) {
20024
20311
  manager.transitionTo('poweredUp')
20025
20312
  }
20026
20313
  })
20027
20314
  }),
20028
20315
  poweredUp: Ember.State.create({
20029
- beginExtermination: function(manager, context){
20316
+ beginExtermination: function(manager, context) {
20030
20317
  manager.transitionTo('rampaging')
20031
20318
  },
20032
20319
  rampaging: Ember.State.create()
@@ -20065,7 +20352,7 @@ var sendEvent = function(eventName, sendRecursiveArguments, isUnhandledPass) {
20065
20352
 
20066
20353
  bManager = Ember.StateManager.create({
20067
20354
  stateOne: Ember.State.create({
20068
- changeToStateTwo: function(manager, context){
20355
+ changeToStateTwo: function(manager, context) {
20069
20356
  manager.transitionTo('stateTwo', context)
20070
20357
  }
20071
20358
  }),
@@ -20438,7 +20725,7 @@ define("metamorph",
20438
20725
  // Copyright: ©2011 My Company Inc. All rights reserved.
20439
20726
  // ==========================================================================
20440
20727
 
20441
- var K = function(){},
20728
+ var K = function() {},
20442
20729
  guid = 0,
20443
20730
  document = this.document,
20444
20731
 
@@ -20448,7 +20735,7 @@ define("metamorph",
20448
20735
  // Internet Explorer prior to 9 does not allow setting innerHTML if the first element
20449
20736
  // is a "zero-scope" element. This problem can be worked around by making
20450
20737
  // the first node an invisible text node. We, like Modernizr, use &shy;
20451
- needsShy = document && (function(){
20738
+ needsShy = document && (function() {
20452
20739
  var testEl = document.createElement('div');
20453
20740
  testEl.innerHTML = "<div></div>";
20454
20741
  testEl.firstChild.innerHTML = "<script></script>";
@@ -20904,12 +21191,12 @@ var objectCreate = Object.create || function(parent) {
20904
21191
  };
20905
21192
 
20906
21193
  var Handlebars = this.Handlebars || (Ember.imports && Ember.imports.Handlebars);
20907
- if(!Handlebars && typeof require === 'function') {
21194
+ if (!Handlebars && typeof require === 'function') {
20908
21195
  Handlebars = require('handlebars');
20909
21196
  }
20910
21197
 
20911
- Ember.assert("Ember Handlebars requires Handlebars version 1.0.0. Include a SCRIPT tag in the HTML HEAD linking to the Handlebars file before you link to Ember.", Handlebars)
20912
- Ember.assert("Ember Handlebars requires Handlebars version 1.0.0, COMPILER_REVISION expected: 4, got: " + Handlebars.COMPILER_REVISION + " Please note: Builds of master may have other COMPILER_REVISION values.", Handlebars.COMPILER_REVISION === 4);
21198
+ Ember.assert("Ember Handlebars requires Handlebars version 1.0.0. Include a SCRIPT tag in the HTML HEAD linking to the Handlebars file before you link to Ember.", Handlebars);
21199
+ Ember.assert("Ember Handlebars requires Handlebars version 1.0.0, COMPILER_REVISION expected: 4, got: " + Handlebars.COMPILER_REVISION + " - Please note: Builds of master may have other COMPILER_REVISION values.", Handlebars.COMPILER_REVISION === 4);
20913
21200
 
20914
21201
  /**
20915
21202
  Prepares the Handlebars templating library for use inside Ember's view
@@ -21008,14 +21295,14 @@ Ember.Handlebars.helper = function(name, value) {
21008
21295
 
21009
21296
  if (Ember.View.detect(value)) {
21010
21297
  Ember.Handlebars.registerHelper(name, function(options) {
21011
- Ember.assert("You can only pass attributes as parameters (not values) to a application-defined helper", arguments.length < 2);
21298
+ Ember.assert("You can only pass attributes (such as name=value) not bare values to a helper for a View", arguments.length < 2);
21012
21299
  makeBindings(options);
21013
21300
  return Ember.Handlebars.helpers.view.call(this, value, options);
21014
21301
  });
21015
21302
  } else {
21016
21303
  Ember.Handlebars.registerBoundHelper.apply(null, arguments);
21017
21304
  }
21018
- }
21305
+ };
21019
21306
 
21020
21307
  /**
21021
21308
  @class helpers
@@ -21101,7 +21388,7 @@ Ember.Handlebars.Compiler.prototype.mustache = function(mustache) {
21101
21388
  // Update the mustache node to include a hash value indicating whether the original node
21102
21389
  // was escaped. This will allow us to properly escape values when the underlying value
21103
21390
  // changes and we need to re-render the value.
21104
- if(!mustache.escaped) {
21391
+ if (!mustache.escaped) {
21105
21392
  mustache.hash = mustache.hash || new Handlebars.AST.HashNode([]);
21106
21393
  mustache.hash.pairs.push(["unescaped", new Handlebars.AST.StringNode("true")]);
21107
21394
  }
@@ -21299,7 +21586,7 @@ Ember.Handlebars.registerHelper('helperMissing', function(path, options) {
21299
21586
  var error, view = "";
21300
21587
 
21301
21588
  error = "%@ Handlebars error: Could not find property '%@' on object %@.";
21302
- if (options.data){
21589
+ if (options.data) {
21303
21590
  view = options.data.view;
21304
21591
  }
21305
21592
  throw new Ember.Error(Ember.String.fmt(error, [view, path, this]));
@@ -21336,7 +21623,7 @@ Ember.Handlebars.registerHelper('helperMissing', function(path, options) {
21336
21623
  Ember.Handlebars.registerBoundHelper('repeat', function(value, options) {
21337
21624
  var count = options.hash.count;
21338
21625
  var a = [];
21339
- while(a.length < count){
21626
+ while(a.length < count) {
21340
21627
  a.push(value);
21341
21628
  }
21342
21629
  return a.join('');
@@ -21380,7 +21667,7 @@ Ember.Handlebars.registerHelper('helperMissing', function(path, options) {
21380
21667
 
21381
21668
  ```javascript
21382
21669
  Ember.Handlebars.registerBoundHelper('concatenate', function() {
21383
- var values = arguments[arguments.length - 1];
21670
+ var values = Array.prototype.slice.call(arguments, 0, -1);
21384
21671
  return values.join('||');
21385
21672
  });
21386
21673
  ```
@@ -21427,7 +21714,7 @@ Ember.Handlebars.registerBoundHelper = function(name, fn) {
21427
21714
  view = data.view,
21428
21715
  currentContext = (options.contexts && options.contexts[0]) || this,
21429
21716
  normalized,
21430
- pathRoot, path,
21717
+ pathRoot, path, prefixPathForDependentKeys = '',
21431
21718
  loc, hashOption;
21432
21719
 
21433
21720
  Ember.assert("registerBoundHelper-generated helpers do not support use with Handlebars blocks.", !options.fn);
@@ -21478,8 +21765,11 @@ Ember.Handlebars.registerBoundHelper = function(name, fn) {
21478
21765
 
21479
21766
  view.registerObserver(pathRoot, path, bindView, bindView.rerender);
21480
21767
 
21768
+ if(!Ember.isEmpty(path)) {
21769
+ prefixPathForDependentKeys = path + '.';
21770
+ }
21481
21771
  for (var i=0, l=dependentKeys.length; i<l; i++) {
21482
- view.registerObserver(pathRoot, path + '.' + dependentKeys[i], bindView, bindView.rerender);
21772
+ view.registerObserver(pathRoot, prefixPathForDependentKeys + dependentKeys[i], bindView, bindView.rerender);
21483
21773
  }
21484
21774
  }
21485
21775
 
@@ -21586,7 +21876,7 @@ function evaluateUnboundHelper(context, fn, normalizedProperties, options) {
21586
21876
  @for Ember.Handlebars
21587
21877
  @param {String} template spec
21588
21878
  */
21589
- Ember.Handlebars.template = function(spec){
21879
+ Ember.Handlebars.template = function(spec) {
21590
21880
  var t = Handlebars.template(spec);
21591
21881
  t.isTop = true;
21592
21882
  return t;
@@ -21598,10 +21888,19 @@ Ember.Handlebars.template = function(spec){
21598
21888
 
21599
21889
  (function() {
21600
21890
  /**
21601
- @method htmlSafe
21602
- @for Ember.String
21603
- @static
21604
- */
21891
+ * Mark a string as safe for unescaped output with Handlebars. If you
21892
+ * return HTML from a Handlebars helper, use this function to
21893
+ * ensure Handlebars does not escape the HTML.
21894
+ *
21895
+ * ```javascript
21896
+ * Ember.String.htmlSafe('<div>someString</div>')
21897
+ * ```
21898
+ *
21899
+ * @method htmlSafe
21900
+ * @for Ember.String
21901
+ * @static
21902
+ * @return {Handlebars.SafeString} a string that will not be html escaped by Handlebars
21903
+ */
21605
21904
  Ember.String.htmlSafe = function(str) {
21606
21905
  return new Handlebars.SafeString(str);
21607
21906
  };
@@ -21611,11 +21910,18 @@ var htmlSafe = Ember.String.htmlSafe;
21611
21910
  if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.String) {
21612
21911
 
21613
21912
  /**
21614
- See `Ember.String.htmlSafe`.
21615
-
21616
- @method htmlSafe
21617
- @for String
21618
- */
21913
+ * Mark a string as being safe for unescaped output with Handlebars.
21914
+ *
21915
+ * ```javascript
21916
+ * '<div>someString</div>'.htmlSafe()
21917
+ * ```
21918
+ *
21919
+ * See `Ember.String.htmlSafe`.
21920
+ *
21921
+ * @method htmlSafe
21922
+ * @for String
21923
+ * @return {Handlebars.SafeString} a string that will not be html escaped by Handlebars
21924
+ */
21619
21925
  String.prototype.htmlSafe = function() {
21620
21926
  return htmlSafe(this);
21621
21927
  };
@@ -21720,7 +22026,6 @@ var DOMManager = {
21720
22026
  /**
21721
22027
  @class _Metamorph
21722
22028
  @namespace Ember
21723
- @extends Ember.Mixin
21724
22029
  @private
21725
22030
  */
21726
22031
  Ember._Metamorph = Ember.Mixin.create({
@@ -22115,7 +22420,7 @@ var forEach = Ember.ArrayPolyfills.forEach;
22115
22420
 
22116
22421
  var EmberHandlebars = Ember.Handlebars, helpers = EmberHandlebars.helpers;
22117
22422
 
22118
- function exists(value){
22423
+ function exists(value) {
22119
22424
  return !Ember.isNone(value);
22120
22425
  }
22121
22426
 
@@ -22140,7 +22445,7 @@ function bind(property, options, preserveContext, shouldDisplay, valueNormalizer
22140
22445
 
22141
22446
  var template, context, result = handlebarsGet(currentContext, property, options);
22142
22447
 
22143
- result = valueNormalizer(result);
22448
+ result = valueNormalizer ? valueNormalizer(result) : result;
22144
22449
 
22145
22450
  context = preserveContext ? currentContext : result;
22146
22451
  if (shouldDisplay(result)) {
@@ -22465,7 +22770,7 @@ EmberHandlebars.registerHelper('unless', function(context, options) {
22465
22770
 
22466
22771
  ```javascript
22467
22772
  AView = Ember.View.extend({
22468
- someProperty: function(){
22773
+ someProperty: function() {
22469
22774
  return "aValue";
22470
22775
  }.property()
22471
22776
  })
@@ -22568,7 +22873,7 @@ EmberHandlebars.registerHelper('bindAttr', function(options) {
22568
22873
  var path = attrs[attr],
22569
22874
  normalized;
22570
22875
 
22571
- Ember.assert(fmt("You must provide a String for a bound attribute, not %@", [path]), typeof path === 'string');
22876
+ Ember.assert(fmt("You must provide an expression as the value of bound attribute. You specified: %@=%@", [attr, path]), typeof path === 'string');
22572
22877
 
22573
22878
  normalized = normalizePath(ctx, path, options.data);
22574
22879
 
@@ -22754,6 +23059,8 @@ EmberHandlebars.bindClasses = function(context, classBindings, view, bindAttrId,
22754
23059
 
22755
23060
  var get = Ember.get, set = Ember.set;
22756
23061
  var EmberHandlebars = Ember.Handlebars;
23062
+ var LOWERCASE_A_Z = /^[a-z]/;
23063
+ var VIEW_PREFIX = /^view\./;
22757
23064
 
22758
23065
  EmberHandlebars.ViewHelper = Ember.Object.create({
22759
23066
 
@@ -22865,7 +23172,18 @@ EmberHandlebars.ViewHelper = Ember.Object.create({
22865
23172
  newView;
22866
23173
 
22867
23174
  if ('string' === typeof path) {
22868
- newView = EmberHandlebars.get(thisContext, path, options);
23175
+
23176
+ // TODO: this is a lame conditional, this should likely change
23177
+ // but something along these lines will likely need to be added
23178
+ // as deprecation warnings
23179
+ //
23180
+ if (options.types[0] === 'STRING' && LOWERCASE_A_Z.test(path) && !VIEW_PREFIX.test(path)) {
23181
+ Ember.assert("View requires a container", !!data.view.container);
23182
+ newView = data.view.container.lookupFactory('view:' + path);
23183
+ } else {
23184
+ newView = EmberHandlebars.get(thisContext, path, options);
23185
+ }
23186
+
22869
23187
  Ember.assert("Unable to find view at path '" + path + "'", !!newView);
22870
23188
  } else {
22871
23189
  newView = path;
@@ -23234,11 +23552,25 @@ Ember.Handlebars.registerHelper('collection', function(path, options) {
23234
23552
  var hash = options.hash, itemHash = {}, match;
23235
23553
 
23236
23554
  // Extract item view class if provided else default to the standard class
23237
- var itemViewClass, itemViewPath = hash.itemViewClass;
23238
- var collectionPrototype = collectionClass.proto();
23555
+ var collectionPrototype = collectionClass.proto(),
23556
+ itemViewClass;
23557
+
23558
+ if (hash.itemView) {
23559
+ var controller = data.keywords.controller;
23560
+ Ember.assert('You specified an itemView, but the current context has no container to look the itemView up in. This probably means that you created a view manually, instead of through the container. Instead, use container.lookup("view:viewName"), which will properly instantiate your view.', controller && controller.container);
23561
+ var container = controller.container;
23562
+ itemViewClass = container.resolve('view:' + Ember.String.camelize(hash.itemView));
23563
+ Ember.assert('You specified the itemView ' + hash.itemView + ", but it was not found at " + container.describe("view:" + hash.itemView) + " (and it was not registered in the container)", !!itemViewClass);
23564
+ } else if (hash.itemViewClass) {
23565
+ itemViewClass = handlebarsGet(collectionPrototype, hash.itemViewClass, options);
23566
+ } else {
23567
+ itemViewClass = collectionPrototype.itemViewClass;
23568
+ }
23569
+
23570
+ Ember.assert(fmt("%@ #collection: Could not find itemViewClass %@", [data.view, itemViewClass]), !!itemViewClass);
23571
+
23239
23572
  delete hash.itemViewClass;
23240
- itemViewClass = itemViewPath ? handlebarsGet(collectionPrototype, itemViewPath, options) : collectionPrototype.itemViewClass;
23241
- Ember.assert(fmt("%@ #collection: Could not find itemViewClass %@", [data.view, itemViewPath]), !!itemViewClass);
23573
+ delete hash.itemView;
23242
23574
 
23243
23575
  // Go through options passed to the {{collection}} helper and extract options
23244
23576
  // that configure item views instead of the collection itself.
@@ -23246,7 +23578,7 @@ Ember.Handlebars.registerHelper('collection', function(path, options) {
23246
23578
  if (hash.hasOwnProperty(prop)) {
23247
23579
  match = prop.match(/^item(.)(.*)$/);
23248
23580
 
23249
- if(match && prop !== 'itemController') {
23581
+ if (match && prop !== 'itemController') {
23250
23582
  // Convert itemShouldFoo -> shouldFoo
23251
23583
  itemHash[match[1].toLowerCase() + match[2]] = hash[prop];
23252
23584
  // Delete from hash as this will end up getting passed to the
@@ -23273,7 +23605,7 @@ Ember.Handlebars.registerHelper('collection', function(path, options) {
23273
23605
  }
23274
23606
  if (emptyViewClass) { hash.emptyView = emptyViewClass; }
23275
23607
 
23276
- if(!hash.keyword){
23608
+ if (!hash.keyword) {
23277
23609
  itemHash._context = Ember.computed.alias('content');
23278
23610
  }
23279
23611
 
@@ -23320,7 +23652,7 @@ var handlebarsGet = Ember.Handlebars.get;
23320
23652
  Ember.Handlebars.registerHelper('unbound', function(property, fn) {
23321
23653
  var options = arguments[arguments.length - 1], helper, context, out;
23322
23654
 
23323
- if(arguments.length > 2) {
23655
+ if (arguments.length > 2) {
23324
23656
  // Unbound helper call.
23325
23657
  options.data.isUnbound = true;
23326
23658
  helper = Ember.Handlebars.helpers[arguments[0]] || Ember.Handlebars.helperMissing;
@@ -23378,7 +23710,7 @@ Ember.Handlebars.registerHelper('log', function(property, options) {
23378
23710
  @for Ember.Handlebars.helpers
23379
23711
  @param {String} property
23380
23712
  */
23381
- Ember.Handlebars.registerHelper('debugger', function() {
23713
+ Ember.Handlebars.registerHelper('debugger', function(options) {
23382
23714
  debugger;
23383
23715
  });
23384
23716
 
@@ -23424,6 +23756,11 @@ Ember.Handlebars.EachView = Ember.CollectionView.extend(Ember._Metamorph, {
23424
23756
  return this._super();
23425
23757
  },
23426
23758
 
23759
+ _assertArrayLike: function(content) {
23760
+ Ember.assert("The value that #each loops over must be an Array. You passed " + content.constructor + ", but it should have been an ArrayController", !Ember.ControllerMixin.detect(content) || (content && content.isGenerated) || content instanceof Ember.ArrayController);
23761
+ Ember.assert("The value that #each loops over must be an Array. You passed " + ((Ember.ControllerMixin.detect(content) && content.get('model') !== undefined) ? ("" + content.get('model') + " (wrapped in " + content + ")") : ("" + content)), Ember.Array.detect(content));
23762
+ },
23763
+
23427
23764
  disableContentObservers: function(callback) {
23428
23765
  Ember.removeBeforeObserver(this, 'content', null, '_contentWillChange');
23429
23766
  Ember.removeObserver(this, 'content', null, '_contentDidChange');
@@ -23654,6 +23991,12 @@ GroupedEach.prototype = {
23654
23991
  </div>
23655
23992
  ```
23656
23993
 
23994
+ If an `itemViewClass` is defined on the helper, and therefore the helper is not
23995
+ being used as a block, an `emptyViewClass` can also be provided optionally.
23996
+ The `emptyViewClass` will match the behavior of the `{{else}}` condition
23997
+ described above. That is, the `emptyViewClass` will render if the collection
23998
+ is empty.
23999
+
23657
24000
  ### Representing each item with a Controller.
23658
24001
  By default the controller lookup within an `{{#each}}` block will be
23659
24002
  the controller of the template where the `{{#each}}` was used. If each
@@ -23667,7 +24010,7 @@ GroupedEach.prototype = {
23667
24010
 
23668
24011
  ```javascript
23669
24012
  App.DeveloperController = Ember.ObjectController.extend({
23670
- isAvailableForHire: function(){
24013
+ isAvailableForHire: function() {
23671
24014
  return !this.get('content.isEmployed') && this.get('content.isSeekingWork');
23672
24015
  }.property('isEmployed', 'isSeekingWork')
23673
24016
  })
@@ -23767,18 +24110,15 @@ Ember.Handlebars.registerHelper('each', function(path, options) {
23767
24110
  Ember.TEMPLATES["my_cool_template"] = Ember.Handlebars.compile('<b>{{user}}</b>');
23768
24111
  ```
23769
24112
 
24113
+ @deprecated
23770
24114
  @method template
23771
24115
  @for Ember.Handlebars.helpers
23772
24116
  @param {String} templateName the template to render
23773
24117
  */
23774
24118
 
23775
24119
  Ember.Handlebars.registerHelper('template', function(name, options) {
23776
- var view = options.data.view,
23777
- template = view.templateForName(name);
23778
-
23779
- Ember.assert("Unable to find template with name '"+name+"'.", !!template);
23780
-
23781
- template(this, { data: options.data });
24120
+ Ember.deprecate("The `template` helper has been deprecated in favor of the `partial` helper. Please use `partial` instead, which will work the same way.");
24121
+ return Ember.Handlebars.helpers.partial.apply(this, arguments);
23782
24122
  });
23783
24123
 
23784
24124
  })();
@@ -23828,7 +24168,6 @@ Ember.Handlebars.registerHelper('partial', function(name, options) {
23828
24168
  template = view.templateForName(underscoredName),
23829
24169
  deprecatedTemplate = !template && view.templateForName(name);
23830
24170
 
23831
- Ember.deprecate("You tried to render the partial " + name + ", which should be at '" + underscoredName + "', but Ember found '" + name + "'. Please use a leading underscore in your partials", template);
23832
24171
  Ember.assert("Unable to find partial with name '"+name+"'.", template || deprecatedTemplate);
23833
24172
 
23834
24173
  template = template || deprecatedTemplate;
@@ -23900,7 +24239,7 @@ var get = Ember.get, set = Ember.set;
23900
24239
  @return {String} HTML string
23901
24240
  */
23902
24241
  Ember.Handlebars.registerHelper('yield', function(options) {
23903
- var view = options.data.view, template;
24242
+ var currentView = options.data.view, view = currentView, template;
23904
24243
 
23905
24244
  while (view && !get(view, 'layout')) {
23906
24245
  view = get(view, 'parentView');
@@ -23910,7 +24249,48 @@ Ember.Handlebars.registerHelper('yield', function(options) {
23910
24249
 
23911
24250
  template = get(view, 'template');
23912
24251
 
23913
- if (template) { template(this, options); }
24252
+ var keywords = view._parentView.cloneKeywords();
24253
+
24254
+ currentView.appendChild(Ember.View, {
24255
+ isVirtual: true,
24256
+ tagName: '',
24257
+ template: template,
24258
+ context: get(view._parentView, 'context'),
24259
+ controller: get(view._parentView, 'controller'),
24260
+ templateData: {keywords: keywords}
24261
+ });
24262
+ });
24263
+
24264
+ })();
24265
+
24266
+
24267
+
24268
+ (function() {
24269
+ /**
24270
+ @module ember
24271
+ @submodule ember-handlebars
24272
+ */
24273
+
24274
+ /**
24275
+ `loc` looks up the string in the localized strings hash.
24276
+ This is a convenient way to localize text. For example:
24277
+
24278
+ ```html
24279
+ <script type="text/x-handlebars" data-template-name="home">
24280
+ {{loc welcome}}
24281
+ </script>
24282
+ ```
24283
+
24284
+ Take note that `welcome` is a string and not an object
24285
+ reference.
24286
+
24287
+ @method loc
24288
+ @for Ember.Handlebars.helpers
24289
+ @param {String} str The string to format
24290
+ */
24291
+
24292
+ Ember.Handlebars.registerHelper('loc', function(str) {
24293
+ return Ember.String.loc(str);
23914
24294
  });
23915
24295
 
23916
24296
  })();
@@ -23980,17 +24360,23 @@ Ember.Checkbox = Ember.View.extend({
23980
24360
 
23981
24361
  tagName: 'input',
23982
24362
 
23983
- attributeBindings: ['type', 'checked', 'disabled', 'tabindex', 'name'],
24363
+ attributeBindings: ['type', 'checked', 'indeterminate', 'disabled', 'tabindex', 'name'],
23984
24364
 
23985
24365
  type: "checkbox",
23986
24366
  checked: false,
23987
24367
  disabled: false,
24368
+ indeterminate: false,
23988
24369
 
23989
24370
  init: function() {
23990
24371
  this._super();
23991
24372
  this.on("change", this, this._updateElementValue);
23992
24373
  },
23993
24374
 
24375
+ didInsertElement: function() {
24376
+ this._super();
24377
+ this.get('element').indeterminate = !!this.get('indeterminate');
24378
+ },
24379
+
23994
24380
  _updateElementValue: function() {
23995
24381
  set(this, 'checked', this.$().prop('checked'));
23996
24382
  }
@@ -24013,7 +24399,6 @@ var get = Ember.get, set = Ember.set;
24013
24399
 
24014
24400
  @class TextSupport
24015
24401
  @namespace Ember
24016
- @extends Ember.Mixin
24017
24402
  @private
24018
24403
  */
24019
24404
  Ember.TextSupport = Ember.Mixin.create({
@@ -25025,9 +25410,9 @@ function program7(depth0,data) {
25025
25410
  content = get(this, 'content'),
25026
25411
  selection = get(this, 'selection');
25027
25412
 
25028
- if (!content){ return; }
25413
+ if (!content) { return; }
25029
25414
  if (options) {
25030
- var selectedIndexes = options.map(function(){
25415
+ var selectedIndexes = options.map(function() {
25031
25416
  return this.index - offset;
25032
25417
  }).toArray();
25033
25418
  var newSelection = content.objectsAt(selectedIndexes);
@@ -25116,7 +25501,7 @@ Ember.Handlebars.registerHelper('input', function(options) {
25116
25501
  if (inputType === 'checkbox') {
25117
25502
  return Ember.Handlebars.helpers.view.call(this, Ember.Checkbox, options);
25118
25503
  } else {
25119
- hash.type = inputType;
25504
+ if (inputType) { hash.type = inputType; }
25120
25505
  hash.onEvent = onEvent || 'enter';
25121
25506
  return Ember.Handlebars.helpers.view.call(this, Ember.TextField, options);
25122
25507
  }
@@ -25962,7 +26347,7 @@ Ember.Application.registerInjection({
25962
26347
  var name = property.charAt(0).toLowerCase() + property.substr(1),
25963
26348
  controllerClass = app[property], controller;
25964
26349
 
25965
- if(!Ember.Object.detect(controllerClass)){ return; }
26350
+ if (!Ember.Object.detect(controllerClass)) { return; }
25966
26351
  controller = app[property].create();
25967
26352
 
25968
26353
  router.set(name, controller);
@@ -26083,7 +26468,6 @@ var merge = function(original, hash) {
26083
26468
  /**
26084
26469
  @class Routable
26085
26470
  @namespace Ember
26086
- @extends Ember.Mixin
26087
26471
  */
26088
26472
  Ember.Routable = Ember.Mixin.create({
26089
26473
  init: function() {
@@ -27015,7 +27399,7 @@ Ember.HistoryLocation = Ember.Object.extend({
27015
27399
  var guid = Ember.guidFor(this);
27016
27400
 
27017
27401
  Ember.$(window).on('popstate.ember-location-'+guid, function(e) {
27018
- if(!popstateReady) {
27402
+ if (!popstateReady) {
27019
27403
  return;
27020
27404
  }
27021
27405
  callback(location.pathname);
@@ -27847,7 +28231,7 @@ ActionHelper.registerAction = function(actionName, options) {
27847
28231
  ```javascript
27848
28232
  AView = Ember.View.extend({
27849
28233
  templateName: 'a-template',
27850
- anActionName: function(event){}
28234
+ anActionName: function(event) {}
27851
28235
  });
27852
28236
 
27853
28237
  aView = AView.create();
@@ -27973,7 +28357,7 @@ ActionHelper.registerAction = function(actionName, options) {
27973
28357
  AView = Ember.View.extend({
27974
28358
  templateName; 'a-template',
27975
28359
  // note: no method 'aMethodNameThatIsMissing'
27976
- anActionName: function(event){}
28360
+ anActionName: function(event) {}
27977
28361
  });
27978
28362
 
27979
28363
  aView = AView.create();