pyro 1.0.0.rc2 → 1.0.0.rc3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,4 @@
1
- // Version: v1.0.0
2
- // Last commit: e2ea0cf (2013-08-31 23:47:39 -0700)
3
-
1
+ // Version: 1.1.2
4
2
 
5
3
  (function() {
6
4
  /*global __fail__*/
@@ -55,7 +53,7 @@ Ember.assert = function(desc, test) {
55
53
 
56
54
  if (Ember.testing && !test) {
57
55
  // when testing, ensure test failures when assertions fail
58
- throw new Error("Assertion Failed: " + desc);
56
+ throw new Ember.Error("Assertion Failed: " + desc);
59
57
  }
60
58
  };
61
59
 
@@ -107,7 +105,7 @@ Ember.deprecate = function(message, test) {
107
105
  if (arguments.length === 1) { test = false; }
108
106
  if (test) { return; }
109
107
 
110
- if (Ember.ENV.RAISE_ON_DEPRECATION) { throw new Error(message); }
108
+ if (Ember.ENV.RAISE_ON_DEPRECATION) { throw new Ember.Error(message); }
111
109
 
112
110
  var error;
113
111
 
@@ -138,15 +136,21 @@ Ember.deprecate = function(message, test) {
138
136
 
139
137
 
140
138
  /**
139
+ Alias an old, deprecated method with its new counterpart.
140
+
141
141
  Display a deprecation warning with the provided message and a stack trace
142
- (Chrome and Firefox only) when the wrapped method is called.
142
+ (Chrome and Firefox only) when the assigned method is called.
143
143
 
144
144
  Ember build tools will not remove calls to `Ember.deprecateFunc()`, though
145
145
  no warnings will be shown in production.
146
146
 
147
+ ```javascript
148
+ Ember.oldMethod = Ember.deprecateFunc("Please use the new, updated method", Ember.newMethod);
149
+ ```
150
+
147
151
  @method deprecateFunc
148
152
  @param {String} message A description of the deprecation.
149
- @param {Function} func The function to be deprecated.
153
+ @param {Function} func The new function called to replace its deprecated counterpart.
150
154
  @return {Function} a new function that wrapped the original function with a deprecation warning
151
155
  */
152
156
  Ember.deprecateFunc = function(message, func) {
@@ -170,9 +174,7 @@ if (!Ember.testing) {
170
174
 
171
175
  })();
172
176
 
173
- // Version: v1.0.0
174
- // Last commit: e2ea0cf (2013-08-31 23:47:39 -0700)
175
-
177
+ // Version: 1.1.2
176
178
 
177
179
  (function() {
178
180
  var define, requireModule;
@@ -237,7 +239,7 @@ var define, requireModule;
237
239
 
238
240
  @class Ember
239
241
  @static
240
- @version 1.0.0
242
+ @version 1.1.2
241
243
  */
242
244
 
243
245
  if ('undefined' === typeof Ember) {
@@ -264,10 +266,10 @@ Ember.toString = function() { return "Ember"; };
264
266
  /**
265
267
  @property VERSION
266
268
  @type String
267
- @default '1.0.0'
269
+ @default '1.1.2'
268
270
  @final
269
271
  */
270
- Ember.VERSION = '1.0.0';
272
+ Ember.VERSION = '1.1.2';
271
273
 
272
274
  /**
273
275
  Standard environmental variables. You can define these in a global `ENV`
@@ -292,6 +294,27 @@ Ember.ENV = Ember.ENV || ENV;
292
294
 
293
295
  Ember.config = Ember.config || {};
294
296
 
297
+ /**
298
+ Hash of enabled Canary features. Add to before creating your application.
299
+
300
+ @property FEATURES
301
+ @type Hash
302
+ */
303
+
304
+ Ember.FEATURES = {};
305
+
306
+ /**
307
+ Test that a feature is enabled. Parsed by Ember's build tools to leave
308
+ experimental features out of beta/stable builds.
309
+
310
+ @method isEnabled
311
+ @param {string} feature
312
+ */
313
+
314
+ Ember.FEATURES.isEnabled = function(feature) {
315
+ return Ember.FEATURES[feature];
316
+ };
317
+
295
318
  // ..........................................................
296
319
  // BOOTSTRAP
297
320
  //
@@ -502,7 +525,7 @@ Ember.Logger = {
502
525
 
503
526
  @method assert
504
527
  @for Ember.Logger
505
- @param @param {Boolean} bool Value to test
528
+ @param {Boolean} bool Value to test
506
529
  */
507
530
  assert: consoleMethod('assert') || assertPolyfill
508
531
  };
@@ -2251,6 +2274,7 @@ function suspendListeners(obj, eventNames, target, method, callback) {
2251
2274
  }
2252
2275
 
2253
2276
  var suspendedActions = [],
2277
+ actionsList = [],
2254
2278
  eventName, actions, i, l;
2255
2279
 
2256
2280
  for (i=0, l=eventNames.length; i<l; i++) {
@@ -2261,6 +2285,7 @@ function suspendListeners(obj, eventNames, target, method, callback) {
2261
2285
  if (actionIndex !== -1) {
2262
2286
  actions[actionIndex+2] |= SUSPENDED;
2263
2287
  suspendedActions.push(actionIndex);
2288
+ actionsList.push(actions);
2264
2289
  }
2265
2290
  }
2266
2291
 
@@ -2269,7 +2294,7 @@ function suspendListeners(obj, eventNames, target, method, callback) {
2269
2294
  function finalizer() {
2270
2295
  for (var i = 0, l = suspendedActions.length; i < l; i++) {
2271
2296
  var actionIndex = suspendedActions[i];
2272
- actions[actionIndex+2] &= ~SUSPENDED;
2297
+ actionsList[i][actionIndex+2] &= ~SUSPENDED;
2273
2298
  }
2274
2299
  }
2275
2300
 
@@ -4609,18 +4634,18 @@ function registerComputedWithProperties(name, macro) {
4609
4634
  }
4610
4635
 
4611
4636
  /**
4612
- A computed property that returns true of the value of the dependent
4637
+ A computed property that returns true if the value of the dependent
4613
4638
  property is null, an empty string, empty array, or empty function.
4614
4639
 
4615
4640
  Note: When using `Ember.computed.empty` to watch an array make sure to
4616
- use the `array.length` syntax so the computed can subscribe to transitions
4641
+ use the `array.[]` syntax so the computed can subscribe to transitions
4617
4642
  from empty to non-empty states.
4618
4643
 
4619
4644
  Example
4620
4645
 
4621
4646
  ```javascript
4622
4647
  var ToDoList = Ember.Object.extend({
4623
- done: Ember.computed.empty('todos.length')
4648
+ done: Ember.computed.empty('todos.[]') // detect array changes
4624
4649
  });
4625
4650
  var todoList = ToDoList.create({todos: ['Unit Test', 'Documentation', 'Release']});
4626
4651
  todoList.get('done'); // false
@@ -4639,7 +4664,7 @@ registerComputed('empty', function(dependentKey) {
4639
4664
  });
4640
4665
 
4641
4666
  /**
4642
- A computed property that returns true of the value of the dependent
4667
+ A computed property that returns true if the value of the dependent
4643
4668
  property is NOT null, an empty string, empty array, or empty function.
4644
4669
 
4645
4670
  Example
@@ -4665,7 +4690,7 @@ registerComputed('notEmpty', function(dependentKey) {
4665
4690
  });
4666
4691
 
4667
4692
  /**
4668
- A computed property that returns true of the value of the dependent
4693
+ A computed property that returns true if the value of the dependent
4669
4694
  property is null or undefined. This avoids errors from JSLint complaining
4670
4695
  about use of ==, which can be technically confusing.
4671
4696
 
@@ -4704,9 +4729,9 @@ registerComputed('none', function(dependentKey) {
4704
4729
  isAnonymous: Ember.computed.not('loggedIn')
4705
4730
  });
4706
4731
  var user = User.create({loggedIn: false});
4707
- user.get('isAnonymous'); // false
4708
- user.set('loggedIn', true);
4709
4732
  user.get('isAnonymous'); // true
4733
+ user.set('loggedIn', true);
4734
+ user.get('isAnonymous'); // false
4710
4735
  ```
4711
4736
 
4712
4737
  @method computed.not
@@ -4740,7 +4765,7 @@ registerComputed('not', function(dependentKey) {
4740
4765
  @method computed.bool
4741
4766
  @for Ember
4742
4767
  @param {String} dependentKey
4743
- @return {Ember.ComputedProperty} computed property which convert
4768
+ @return {Ember.ComputedProperty} computed property which converts
4744
4769
  to boolean the original value for property
4745
4770
  */
4746
4771
  registerComputed('bool', function(dependentKey) {
@@ -4791,7 +4816,7 @@ registerComputed('match', function(dependentKey, regexp) {
4791
4816
  var hampster = Hampster.create();
4792
4817
  hampster.get('napTime'); // false
4793
4818
  hampster.set('state', 'sleepy');
4794
- hampster.get('napTime'); // false
4819
+ hampster.get('napTime'); // true
4795
4820
  hampster.set('state', 'hungry');
4796
4821
  hampster.get('napTime'); // false
4797
4822
  ```
@@ -4958,7 +4983,7 @@ registerComputedWithProperties('and', function(properties) {
4958
4983
  });
4959
4984
 
4960
4985
  /**
4961
- A computed property that which performs a logical `or` on the
4986
+ A computed property which performs a logical `or` on the
4962
4987
  original values for the provided dependent properties.
4963
4988
 
4964
4989
  Example
@@ -5125,7 +5150,7 @@ Ember.computed.alias = function(dependentKey) {
5125
5150
  @method computed.oneWay
5126
5151
  @for Ember
5127
5152
  @param {String} dependentKey
5128
- @return {Ember.ComputedProperty} computed property which creates an
5153
+ @return {Ember.ComputedProperty} computed property which creates a
5129
5154
  one way computed property to the original value for property.
5130
5155
  */
5131
5156
  Ember.computed.oneWay = function(dependentKey) {
@@ -5137,7 +5162,7 @@ Ember.computed.oneWay = function(dependentKey) {
5137
5162
 
5138
5163
  /**
5139
5164
  A computed property that acts like a standard getter and setter,
5140
- but retruns the value at the provided `defaultPath` if the
5165
+ but returns the value at the provided `defaultPath` if the
5141
5166
  property itself has not been set to a value
5142
5167
 
5143
5168
  Example
@@ -5505,7 +5530,12 @@ define("backburner",
5505
5530
  debouncees = [],
5506
5531
  timers = [],
5507
5532
  autorun, laterTimer, laterTimerExpiresAt,
5508
- global = this;
5533
+ global = this,
5534
+ NUMBER = /\d+/;
5535
+
5536
+ function isCoercableNumber(number) {
5537
+ return typeof number === 'number' || NUMBER.test(number);
5538
+ }
5509
5539
 
5510
5540
  function Backburner(queueNames, options) {
5511
5541
  this.queueNames = queueNames;
@@ -5620,32 +5650,60 @@ define("backburner",
5620
5650
  },
5621
5651
 
5622
5652
  setTimeout: function() {
5623
- var self = this,
5624
- wait = pop.call(arguments),
5625
- target = arguments[0],
5626
- method = arguments[1],
5627
- executeAt = (+new Date()) + wait;
5653
+ var args = slice.call(arguments);
5654
+ var length = args.length;
5655
+ var method, wait, target;
5656
+ var self = this;
5657
+ var methodOrTarget, methodOrWait, methodOrArgs;
5628
5658
 
5629
- if (!method) {
5630
- method = target;
5631
- target = null;
5659
+ if (length === 0) {
5660
+ return;
5661
+ } else if (length === 1) {
5662
+ method = args.shift();
5663
+ wait = 0;
5664
+ } else if (length === 2) {
5665
+ methodOrTarget = args[0];
5666
+ methodOrWait = args[1];
5667
+
5668
+ if (typeof methodOrWait === 'function' || typeof methodOrTarget[methodOrWait] === 'function') {
5669
+ target = args.shift();
5670
+ method = args.shift();
5671
+ wait = 0;
5672
+ } else if (isCoercableNumber(methodOrWait)) {
5673
+ method = args.shift();
5674
+ wait = args.shift();
5675
+ } else {
5676
+ method = args.shift();
5677
+ wait = 0;
5678
+ }
5679
+ } else {
5680
+ var last = args[args.length - 1];
5681
+
5682
+ if (isCoercableNumber(last)) {
5683
+ wait = args.pop();
5684
+ }
5685
+
5686
+ methodOrTarget = args[0];
5687
+ methodOrArgs = args[1];
5688
+
5689
+ if (typeof methodOrArgs === 'function' || (typeof methodOrArgs === 'string' &&
5690
+ methodOrTarget !== null &&
5691
+ methodOrArgs in methodOrTarget)) {
5692
+ target = args.shift();
5693
+ method = args.shift();
5694
+ } else {
5695
+ method = args.shift();
5696
+ }
5632
5697
  }
5633
5698
 
5699
+ var executeAt = (+new Date()) + parseInt(wait, 10);
5700
+
5634
5701
  if (typeof method === 'string') {
5635
5702
  method = target[method];
5636
5703
  }
5637
5704
 
5638
- var fn, args;
5639
- if (arguments.length > 2) {
5640
- args = slice.call(arguments, 2);
5641
-
5642
- fn = function() {
5643
- method.apply(target, args);
5644
- };
5645
- } else {
5646
- fn = function() {
5647
- method.call(target);
5648
- };
5705
+ function fn() {
5706
+ method.apply(target, args);
5649
5707
  }
5650
5708
 
5651
5709
  // find position to insert - TODO: binary search
@@ -5846,6 +5904,7 @@ define("backburner",
5846
5904
 
5847
5905
  __exports__.Backburner = Backburner;
5848
5906
  });
5907
+
5849
5908
  })();
5850
5909
 
5851
5910
 
@@ -7019,15 +7078,14 @@ function addNormalizedProperty(base, key, value, meta, descs, values, concats, m
7019
7078
  descs[key] = value;
7020
7079
  values[key] = undefined;
7021
7080
  } else {
7022
- // impl super if needed...
7023
- if (isMethod(value)) {
7024
- value = giveMethodSuper(base, key, value, values, descs);
7025
- } else if ((concats && a_indexOf.call(concats, key) >= 0) ||
7081
+ if ((concats && a_indexOf.call(concats, key) >= 0) ||
7026
7082
  key === 'concatenatedProperties' ||
7027
7083
  key === 'mergedProperties') {
7028
7084
  value = applyConcatenatedProperties(base, key, value, values);
7029
7085
  } else if ((mergings && a_indexOf.call(mergings, key) >= 0)) {
7030
7086
  value = applyMergedProperties(base, key, value, values);
7087
+ } else if (isMethod(value)) {
7088
+ value = giveMethodSuper(base, key, value, values, descs);
7031
7089
  }
7032
7090
 
7033
7091
  descs[key] = undefined;
@@ -7463,11 +7521,10 @@ Alias.prototype = new Ember.Descriptor();
7463
7521
  @deprecated Use `Ember.aliasMethod` or `Ember.computed.alias` instead
7464
7522
  */
7465
7523
  Ember.alias = function(methodName) {
7524
+ Ember.deprecate("Ember.alias is deprecated. Please use Ember.aliasMethod or Ember.computed.alias instead.");
7466
7525
  return new Alias(methodName);
7467
7526
  };
7468
7527
 
7469
- Ember.alias = Ember.deprecateFunc("Ember.alias is deprecated. Please use Ember.aliasMethod or Ember.computed.alias instead.", Ember.alias);
7470
-
7471
7528
  /**
7472
7529
  Makes a method available via an additional name.
7473
7530
 
@@ -7609,6 +7666,55 @@ Ember.beforeObserver = function(func) {
7609
7666
 
7610
7667
 
7611
7668
 
7669
+ (function() {
7670
+ // Provides a way to register library versions with ember.
7671
+ var forEach = Ember.EnumerableUtils.forEach,
7672
+ indexOf = Ember.EnumerableUtils.indexOf;
7673
+
7674
+ Ember.libraries = function() {
7675
+ var libraries = [];
7676
+ var coreLibIndex = 0;
7677
+
7678
+ var getLibrary = function(name) {
7679
+ for (var i = 0; i < libraries.length; i++) {
7680
+ if (libraries[i].name === name) {
7681
+ return libraries[i];
7682
+ }
7683
+ }
7684
+ };
7685
+
7686
+ libraries.register = function(name, version) {
7687
+ if (!getLibrary(name)) {
7688
+ libraries.push({name: name, version: version});
7689
+ }
7690
+ };
7691
+
7692
+ libraries.registerCoreLibrary = function(name, version) {
7693
+ if (!getLibrary(name)) {
7694
+ libraries.splice(coreLibIndex++, 0, {name: name, version: version});
7695
+ }
7696
+ };
7697
+
7698
+ libraries.deRegister = function(name) {
7699
+ var lib = getLibrary(name);
7700
+ if (lib) libraries.splice(indexOf(libraries, lib), 1);
7701
+ };
7702
+
7703
+ libraries.each = function (callback) {
7704
+ forEach(libraries, function(lib) {
7705
+ callback(lib.name, lib.version);
7706
+ });
7707
+ };
7708
+
7709
+ return libraries;
7710
+ }();
7711
+
7712
+ Ember.libraries.registerCoreLibrary('Ember', Ember.VERSION);
7713
+
7714
+ })();
7715
+
7716
+
7717
+
7612
7718
  (function() {
7613
7719
  /**
7614
7720
  Ember Metal
@@ -8267,6 +8373,13 @@ define("rsvp",
8267
8373
 
8268
8374
  (function() {
8269
8375
  /**
8376
+ @private
8377
+ Public api for the container is still in flux.
8378
+ The public api, specified on the application namespace should be considered the stable api.
8379
+ // @module container
8380
+ */
8381
+
8382
+ /*
8270
8383
  Flag to enable/disable model factory injections (disabled by default)
8271
8384
  If model factory injections are enabled, models should not be
8272
8385
  accessed globally (only through `container.lookupFactory('model:modelName'))`);
@@ -8277,11 +8390,7 @@ define("container",
8277
8390
  [],
8278
8391
  function() {
8279
8392
 
8280
- /**
8281
- A safe and simple inheriting object.
8282
-
8283
- @class InheritingDict
8284
- */
8393
+ // A safe and simple inheriting object.
8285
8394
  function InheritingDict(parent) {
8286
8395
  this.parent = parent;
8287
8396
  this.dict = {};
@@ -8354,7 +8463,7 @@ define("container",
8354
8463
 
8355
8464
  @method has
8356
8465
  @param {String} key
8357
- @returns {Boolean}
8466
+ @return {Boolean}
8358
8467
  */
8359
8468
  has: function(key) {
8360
8469
  var dict = this.dict;
@@ -8388,11 +8497,10 @@ define("container",
8388
8497
  }
8389
8498
  };
8390
8499
 
8391
- /**
8392
- A lightweight container that helps to assemble and decouple components.
8393
8500
 
8394
- @class Container
8395
- */
8501
+ // A lightweight container that helps to assemble and decouple components.
8502
+ // Public api for the container is still in flux.
8503
+ // The public api, specified on the application namespace should be considered the stable api.
8396
8504
  function Container(parent) {
8397
8505
  this.parent = parent;
8398
8506
  this.children = [];
@@ -8481,7 +8589,7 @@ define("container",
8481
8589
  to correctly inherit from the current container.
8482
8590
 
8483
8591
  @method child
8484
- @returns {Container}
8592
+ @return {Container}
8485
8593
  */
8486
8594
  child: function() {
8487
8595
  var container = new Container(this);
@@ -8517,25 +8625,25 @@ define("container",
8517
8625
  ```
8518
8626
 
8519
8627
  @method register
8520
- @param {String} type
8521
- @param {String} name
8628
+ @param {String} fullName
8522
8629
  @param {Function} factory
8523
8630
  @param {Object} options
8524
8631
  */
8525
- register: function(type, name, factory, options) {
8526
- var fullName;
8632
+ register: function(fullName, factory, options) {
8633
+ if (fullName.indexOf(':') === -1) {
8634
+ throw new TypeError("malformed fullName, expected: `type:name` got: " + fullName + "");
8635
+ }
8527
8636
 
8528
- if (type.indexOf(':') !== -1) {
8529
- options = factory;
8530
- factory = name;
8531
- fullName = type;
8532
- } else {
8533
- Ember.deprecate('register("'+type +'", "'+ name+'") is now deprecated in-favour of register("'+type+':'+name+'");', false);
8534
- fullName = type + ":" + name;
8637
+ if (factory === undefined) {
8638
+ throw new TypeError('Attempting to register an unknown factory: `' + fullName + '`');
8535
8639
  }
8536
8640
 
8537
8641
  var normalizedName = this.normalize(fullName);
8538
8642
 
8643
+ if (this.cache.has(normalizedName)) {
8644
+ throw new Error('Cannot re-register: `' + fullName +'`, as it has already been looked up.');
8645
+ }
8646
+
8539
8647
  this.registry.set(normalizedName, factory);
8540
8648
  this._options.set(normalizedName, options || {});
8541
8649
  },
@@ -8595,7 +8703,7 @@ define("container",
8595
8703
 
8596
8704
  @method resolve
8597
8705
  @param {String} fullName
8598
- @returns {Function} fullName's factory
8706
+ @return {Function} fullName's factory
8599
8707
  */
8600
8708
  resolve: function(fullName) {
8601
8709
  return this.resolver(fullName) || this.registry.get(fullName);
@@ -8630,7 +8738,7 @@ define("container",
8630
8738
  @method makeToString
8631
8739
 
8632
8740
  @param {any} factory
8633
- @param {string} fullNae
8741
+ @param {string} fullName
8634
8742
  @return {function} toString function
8635
8743
  */
8636
8744
  makeToString: function(factory, fullName) {
@@ -8687,7 +8795,7 @@ define("container",
8687
8795
 
8688
8796
  var value = instantiate(this, fullName);
8689
8797
 
8690
- if (!value) { return; }
8798
+ if (value === undefined) { return; }
8691
8799
 
8692
8800
  if (isSingleton(this, fullName) && options.singleton !== false) {
8693
8801
  this.cache.set(fullName, value);
@@ -8765,7 +8873,7 @@ define("container",
8765
8873
  this.optionsForType(type, options);
8766
8874
  },
8767
8875
 
8768
- /*
8876
+ /**
8769
8877
  @private
8770
8878
 
8771
8879
  Used only via `injection`.
@@ -8807,7 +8915,7 @@ define("container",
8807
8915
  addTypeInjection(this.typeInjections, type, property, fullName);
8808
8916
  },
8809
8917
 
8810
- /*
8918
+ /**
8811
8919
  Defines injection rules.
8812
8920
 
8813
8921
  These rules are used to inject dependencies onto objects when they
@@ -8815,8 +8923,8 @@ define("container",
8815
8923
 
8816
8924
  Two forms of injections are possible:
8817
8925
 
8818
- * Injecting one fullName on another fullName
8819
- * Injecting one fullName on a type
8926
+ * Injecting one fullName on another fullName
8927
+ * Injecting one fullName on a type
8820
8928
 
8821
8929
  Example:
8822
8930
 
@@ -8862,7 +8970,7 @@ define("container",
8862
8970
  },
8863
8971
 
8864
8972
 
8865
- /*
8973
+ /**
8866
8974
  @private
8867
8975
 
8868
8976
  Used only via `factoryInjection`.
@@ -8899,7 +9007,7 @@ define("container",
8899
9007
  addTypeInjection(this.factoryTypeInjections, type, property, fullName);
8900
9008
  },
8901
9009
 
8902
- /*
9010
+ /**
8903
9011
  Defines factory injection rules.
8904
9012
 
8905
9013
  Similar to regular injection rules, but are run against factories, via
@@ -8910,8 +9018,8 @@ define("container",
8910
9018
 
8911
9019
  Two forms of injections are possible:
8912
9020
 
8913
- * Injecting one fullName on another fullName
8914
- * Injecting one fullName on a type
9021
+ * Injecting one fullName on another fullName
9022
+ * Injecting one fullName on a type
8915
9023
 
8916
9024
  Example:
8917
9025
 
@@ -9013,7 +9121,7 @@ define("container",
9013
9121
  injection = injections[i];
9014
9122
  lookup = container.lookup(injection.fullName);
9015
9123
 
9016
- if (lookup) {
9124
+ if (lookup !== undefined) {
9017
9125
  hash[injection.property] = lookup;
9018
9126
  } else {
9019
9127
  throw new Error('Attempting to inject an unknown injection: `' + injection.fullName + '`');
@@ -9045,13 +9153,13 @@ define("container",
9045
9153
  var cache = container.factoryCache;
9046
9154
  var type = fullName.split(":")[0];
9047
9155
 
9048
- if (!factory) { return; }
9156
+ if (factory === undefined) { return; }
9049
9157
 
9050
9158
  if (cache.has(fullName)) {
9051
9159
  return cache.get(fullName);
9052
9160
  }
9053
9161
 
9054
- if (typeof factory.extend !== 'function' || (!Ember.MODEL_FACTORY_INJECTIONS && type === 'model')) {
9162
+ if (!factory || typeof factory.extend !== 'function' || (!Ember.MODEL_FACTORY_INJECTIONS && type === 'model')) {
9055
9163
  // TODO: think about a 'safe' merge style extension
9056
9164
  // for now just fallback to create time injection
9057
9165
  return factory;
@@ -9427,16 +9535,39 @@ Ember.ORDER_DEFINITION = Ember.ENV.ORDER_DEFINITION || [
9427
9535
  Ember.keys = Object.keys;
9428
9536
 
9429
9537
  if (!Ember.keys || Ember.create.isSimulated) {
9538
+ var prototypeProperties = [
9539
+ 'constructor',
9540
+ 'hasOwnProperty',
9541
+ 'isPrototypeOf',
9542
+ 'propertyIsEnumerable',
9543
+ 'valueOf',
9544
+ 'toLocaleString',
9545
+ 'toString'
9546
+ ],
9547
+ pushPropertyName = function(obj, array, key) {
9548
+ // Prevents browsers that don't respect non-enumerability from
9549
+ // copying internal Ember properties
9550
+ if (key.substring(0,2) === '__') return;
9551
+ if (key === '_super') return;
9552
+ if (indexOf(array, key) >= 0) return;
9553
+ if (!obj.hasOwnProperty(key)) return;
9554
+
9555
+ array.push(key);
9556
+ };
9557
+
9430
9558
  Ember.keys = function(obj) {
9431
- var ret = [];
9432
- for(var key in obj) {
9433
- // Prevents browsers that don't respect non-enumerability from
9434
- // copying internal Ember properties
9435
- if (key.substring(0,2) === '__') continue;
9436
- if (key === '_super') continue;
9559
+ var ret = [], key;
9560
+ for (key in obj) {
9561
+ pushPropertyName(obj, ret, key);
9562
+ }
9563
+
9564
+ // IE8 doesn't enumerate property that named the same as prototype properties.
9565
+ for (var i = 0, l = prototypeProperties.length; i < l; i++) {
9566
+ key = prototypeProperties[i];
9437
9567
 
9438
- if (obj.hasOwnProperty(key)) { ret.push(key); }
9568
+ pushPropertyName(obj, ret, key);
9439
9569
  }
9570
+
9440
9571
  return ret;
9441
9572
  };
9442
9573
  }
@@ -10876,6 +11007,8 @@ var get = Ember.get,
10876
11007
  set = Ember.set,
10877
11008
  guidFor = Ember.guidFor,
10878
11009
  metaFor = Ember.meta,
11010
+ propertyWillChange = Ember.propertyWillChange,
11011
+ propertyDidChange = Ember.propertyDidChange,
10879
11012
  addBeforeObserver = Ember.addBeforeObserver,
10880
11013
  removeBeforeObserver = Ember.removeBeforeObserver,
10881
11014
  addObserver = Ember.addObserver,
@@ -10930,11 +11063,13 @@ function ItemPropertyObserverContext (dependentArray, index, trackedArray) {
10930
11063
  this.trackedArray = trackedArray;
10931
11064
  this.beforeObserver = null;
10932
11065
  this.observer = null;
11066
+
11067
+ this.destroyed = false;
10933
11068
  }
10934
11069
 
10935
11070
  DependentArraysObserver.prototype = {
10936
11071
  setValue: function (newValue) {
10937
- this.instanceMeta.setValue(newValue);
11072
+ this.instanceMeta.setValue(newValue, true);
10938
11073
  },
10939
11074
  getValue: function () {
10940
11075
  return this.instanceMeta.getValue();
@@ -10999,6 +11134,7 @@ DependentArraysObserver.prototype = {
10999
11134
  if (operation === Ember.TrackedArray.DELETE) { return; }
11000
11135
 
11001
11136
  forEach(observerContexts, function (observerContext) {
11137
+ observerContext.destroyed = true;
11002
11138
  beforeObserver = observerContext.beforeObserver;
11003
11139
  observer = observerContext.observer;
11004
11140
  item = observerContext.item;
@@ -11023,11 +11159,10 @@ DependentArraysObserver.prototype = {
11023
11159
  var dependentArrayObserver = this;
11024
11160
 
11025
11161
  observerContext.beforeObserver = function (obj, keyName) {
11026
- dependentArrayObserver.updateIndexes(observerContext.trackedArray, observerContext.dependentArray);
11027
- return dependentArrayObserver.itemPropertyWillChange(obj, keyName, observerContext.dependentArray, observerContext.index);
11162
+ return dependentArrayObserver.itemPropertyWillChange(obj, keyName, observerContext.dependentArray, observerContext);
11028
11163
  };
11029
11164
  observerContext.observer = function (obj, keyName) {
11030
- return dependentArrayObserver.itemPropertyDidChange(obj, keyName, observerContext.dependentArray, observerContext.index);
11165
+ return dependentArrayObserver.itemPropertyDidChange(obj, keyName, observerContext.dependentArray, observerContext);
11031
11166
  };
11032
11167
  },
11033
11168
 
@@ -11035,14 +11170,14 @@ DependentArraysObserver.prototype = {
11035
11170
  this.trackedArraysByGuid[dependentKey] = new Ember.TrackedArray(observerContexts);
11036
11171
  },
11037
11172
 
11038
- addTransformation: function (dependentKey, index, newItems) {
11173
+ trackAdd: function (dependentKey, index, newItems) {
11039
11174
  var trackedArray = this.trackedArraysByGuid[dependentKey];
11040
11175
  if (trackedArray) {
11041
11176
  trackedArray.addItems(index, newItems);
11042
11177
  }
11043
11178
  },
11044
11179
 
11045
- removeTransformation: function (dependentKey, index, removedCount) {
11180
+ trackRemove: function (dependentKey, index, removedCount) {
11046
11181
  var trackedArray = this.trackedArraysByGuid[dependentKey];
11047
11182
 
11048
11183
  if (trackedArray) {
@@ -11083,10 +11218,10 @@ DependentArraysObserver.prototype = {
11083
11218
  sliceIndex,
11084
11219
  observerContexts;
11085
11220
 
11086
- observerContexts = this.removeTransformation(dependentKey, index, removedCount);
11087
-
11221
+ observerContexts = this.trackRemove(dependentKey, index, removedCount);
11088
11222
 
11089
11223
  function removeObservers(propertyKey) {
11224
+ observerContexts[sliceIndex].destroyed = true;
11090
11225
  removeBeforeObserver(item, propertyKey, this, observerContexts[sliceIndex].beforeObserver);
11091
11226
  removeObserver(item, propertyKey, this, observerContexts[sliceIndex].observer);
11092
11227
  }
@@ -11128,33 +11263,38 @@ DependentArraysObserver.prototype = {
11128
11263
  this.instanceMeta.context, this.getValue(), item, changeMeta, this.instanceMeta.sugarMeta));
11129
11264
  }, this);
11130
11265
 
11131
- this.addTransformation(dependentKey, index, observerContexts);
11266
+ this.trackAdd(dependentKey, index, observerContexts);
11132
11267
  },
11133
11268
 
11134
- itemPropertyWillChange: function (obj, keyName, array, index) {
11269
+ itemPropertyWillChange: function (obj, keyName, array, observerContext) {
11135
11270
  var guid = guidFor(obj);
11136
11271
 
11137
11272
  if (!this.changedItems[guid]) {
11138
11273
  this.changedItems[guid] = {
11139
- array: array,
11140
- index: index,
11141
- obj: obj,
11142
- previousValues: {}
11274
+ array: array,
11275
+ observerContext: observerContext,
11276
+ obj: obj,
11277
+ previousValues: {}
11143
11278
  };
11144
11279
  }
11145
11280
 
11146
11281
  this.changedItems[guid].previousValues[keyName] = get(obj, keyName);
11147
11282
  },
11148
11283
 
11149
- itemPropertyDidChange: function(obj, keyName, array, index) {
11150
- Ember.run.once(this, 'flushChanges');
11284
+ itemPropertyDidChange: function(obj, keyName, array, observerContext) {
11285
+ this.flushChanges();
11151
11286
  },
11152
11287
 
11153
11288
  flushChanges: function() {
11154
11289
  var changedItems = this.changedItems, key, c, changeMeta;
11290
+
11155
11291
  for (key in changedItems) {
11156
11292
  c = changedItems[key];
11157
- changeMeta = createChangeMeta(c.array, c.obj, c.index, this.instanceMeta.propertyName, this.cp, c.previousValues);
11293
+ if (c.observerContext.destroyed) { continue; }
11294
+
11295
+ this.updateIndexes(c.observerContext.trackedArray, c.observerContext.dependentArray);
11296
+
11297
+ changeMeta = createChangeMeta(c.array, c.obj, c.observerContext.index, this.instanceMeta.propertyName, this.cp, c.previousValues);
11158
11298
  this.setValue(
11159
11299
  this.callbacks.removedItem.call(this.instanceMeta.context, this.getValue(), c.obj, changeMeta, this.instanceMeta.sugarMeta));
11160
11300
  this.setValue(
@@ -11224,11 +11364,21 @@ ReduceComputedPropertyInstanceMeta.prototype = {
11224
11364
  }
11225
11365
  },
11226
11366
 
11227
- setValue: function(newValue) {
11367
+ setValue: function(newValue, triggerObservers) {
11228
11368
  // This lets sugars force a recomputation, handy for very simple
11229
11369
  // implementations of eg max.
11230
11370
  if (newValue !== undefined) {
11371
+ var fireObservers = triggerObservers && (newValue !== this.cache[this.propertyName]);
11372
+
11373
+ if (fireObservers) {
11374
+ propertyWillChange(this.context, this.propertyName);
11375
+ }
11376
+
11231
11377
  this.cache[this.propertyName] = newValue;
11378
+
11379
+ if (fireObservers) {
11380
+ propertyDidChange(this.context, this.propertyName);
11381
+ }
11232
11382
  } else {
11233
11383
  delete this.cache[this.propertyName];
11234
11384
  }
@@ -11354,13 +11504,11 @@ ReduceComputedProperty.prototype._instanceMeta = function (context, propertyName
11354
11504
  };
11355
11505
 
11356
11506
  ReduceComputedProperty.prototype.initialValue = function () {
11357
- switch (typeof this.options.initialValue) {
11358
- case 'undefined':
11359
- throw new Error("reduce computed properties require an initial value: did you forget to pass one to Ember.reduceComputed?");
11360
- case 'function':
11361
- return this.options.initialValue();
11362
- default:
11363
- return this.options.initialValue;
11507
+ if (typeof this.options.initialValue === 'function') {
11508
+ return this.options.initialValue();
11509
+ }
11510
+ else {
11511
+ return this.options.initialValue;
11364
11512
  }
11365
11513
  };
11366
11514
 
@@ -11383,25 +11531,25 @@ ReduceComputedProperty.prototype.clearItemPropertyKeys = function (dependentArra
11383
11531
  ReduceComputedProperty.prototype.property = function () {
11384
11532
  var cp = this,
11385
11533
  args = a_slice.call(arguments),
11386
- propertyArgs = [],
11534
+ propertyArgs = new Ember.Set(),
11387
11535
  match,
11388
11536
  dependentArrayKey,
11389
11537
  itemPropertyKey;
11390
11538
 
11391
11539
  forEach(a_slice.call(arguments), function (dependentKey) {
11392
11540
  if (doubleEachPropertyPattern.test(dependentKey)) {
11393
- throw new Error("Nested @each properties not supported: " + dependentKey);
11541
+ throw new Ember.Error("Nested @each properties not supported: " + dependentKey);
11394
11542
  } else if (match = eachPropertyPattern.exec(dependentKey)) {
11395
11543
  dependentArrayKey = match[1];
11396
11544
  itemPropertyKey = match[2];
11397
11545
  cp.itemPropertyKey(dependentArrayKey, itemPropertyKey);
11398
- propertyArgs.push(dependentArrayKey);
11546
+ propertyArgs.add(dependentArrayKey);
11399
11547
  } else {
11400
- propertyArgs.push(dependentKey);
11548
+ propertyArgs.add(dependentKey);
11401
11549
  }
11402
11550
  });
11403
11551
 
11404
- return ComputedProperty.prototype.property.apply(this, propertyArgs);
11552
+ return ComputedProperty.prototype.property.apply(this, propertyArgs.toArray());
11405
11553
  };
11406
11554
 
11407
11555
  /**
@@ -11413,7 +11561,7 @@ ReduceComputedProperty.prototype.property = function () {
11413
11561
  If there are more than one arguments the first arguments are
11414
11562
  considered to be dependent property keys. The last argument is
11415
11563
  required to be an options object. The options object can have the
11416
- following four properties.
11564
+ following four properties:
11417
11565
 
11418
11566
  `initialValue` - A value or function that will be used as the initial
11419
11567
  value for the computed. If this property is a function the result of calling
@@ -11494,6 +11642,12 @@ ReduceComputedProperty.prototype.property = function () {
11494
11642
  to invalidate the computation. This is generally not a good idea for
11495
11643
  arrayComputed but it's used in eg max and min.
11496
11644
 
11645
+ Note that observers will be fired if either of these functions return a value
11646
+ that differs from the accumulated value. When returning an object that
11647
+ mutates in response to array changes, for example an array that maps
11648
+ everything from some other array (see `Ember.computed.map`), it is usually
11649
+ important that the *same* array be returned to avoid accidentally triggering observers.
11650
+
11497
11651
  Example
11498
11652
 
11499
11653
  ```javascript
@@ -11518,7 +11672,7 @@ ReduceComputedProperty.prototype.property = function () {
11518
11672
  @for Ember
11519
11673
  @param {String} [dependentKeys*]
11520
11674
  @param {Object} options
11521
- @returns {Ember.ComputedProperty}
11675
+ @return {Ember.ComputedProperty}
11522
11676
  */
11523
11677
  Ember.reduceComputed = function (options) {
11524
11678
  var args;
@@ -11529,11 +11683,11 @@ Ember.reduceComputed = function (options) {
11529
11683
  }
11530
11684
 
11531
11685
  if (typeof options !== "object") {
11532
- throw new Error("Reduce Computed Property declared without an options hash");
11686
+ throw new Ember.Error("Reduce Computed Property declared without an options hash");
11533
11687
  }
11534
11688
 
11535
- if (!options.initialValue) {
11536
- throw new Error("Reduce Computed Property declared without an initial value");
11689
+ if (!('initialValue' in options)) {
11690
+ throw new Ember.Error("Reduce Computed Property declared without an initial value");
11537
11691
  }
11538
11692
 
11539
11693
  var cp = new ReduceComputedProperty(options);
@@ -11701,7 +11855,7 @@ ArrayComputedProperty.prototype.resetValue = function (array) {
11701
11855
  @for Ember
11702
11856
  @param {String} [dependentKeys*]
11703
11857
  @param {Object} options
11704
- @returns {Ember.ComputedProperty}
11858
+ @return {Ember.ComputedProperty}
11705
11859
  */
11706
11860
  Ember.arrayComputed = function (options) {
11707
11861
  var args;
@@ -11712,7 +11866,7 @@ Ember.arrayComputed = function (options) {
11712
11866
  }
11713
11867
 
11714
11868
  if (typeof options !== "object") {
11715
- throw new Error("Array Computed Property declared without an options hash");
11869
+ throw new Ember.Error("Array Computed Property declared without an options hash");
11716
11870
  }
11717
11871
 
11718
11872
  var cp = new ArrayComputedProperty(options);
@@ -11859,7 +12013,7 @@ Ember.computed.min = function (dependentKey) {
11859
12013
  Ember.computed.map = function(dependentKey, callback) {
11860
12014
  var options = {
11861
12015
  addedItem: function(array, item, changeMeta, instanceMeta) {
11862
- var mapped = callback(item);
12016
+ var mapped = callback.call(this, item);
11863
12017
  array.insertAt(changeMeta.index, mapped);
11864
12018
  return array;
11865
12019
  },
@@ -11879,16 +12033,15 @@ Ember.computed.map = function(dependentKey, callback) {
11879
12033
 
11880
12034
  ```javascript
11881
12035
  App.Person = Ember.Object.extend({
11882
- childAges: Ember.computed.mapBy('children', 'age'),
11883
- minChildAge: Ember.computed.min('childAges')
12036
+ childAges: Ember.computed.mapBy('children', 'age')
11884
12037
  });
11885
12038
 
11886
12039
  var lordByron = App.Person.create({children: []});
11887
- lordByron.get('childAge'); // []
12040
+ lordByron.get('childAges'); // []
11888
12041
  lordByron.get('children').pushObject({name: 'Augusta Ada Byron', age: 7});
11889
- lordByron.get('childAge'); // [7]
12042
+ lordByron.get('childAges'); // [7]
11890
12043
  lordByron.get('children').pushObjects([{name: 'Allegra Byron', age: 5}, {name: 'Elizabeth Medora Leigh', age: 8}]);
11891
- lordByron.get('childAge'); // [7, 5, 8]
12044
+ lordByron.get('childAges'); // [7, 5, 8]
11892
12045
  ```
11893
12046
 
11894
12047
  @method computed.mapBy
@@ -11952,7 +12105,7 @@ Ember.computed.filter = function(dependentKey, callback) {
11952
12105
  },
11953
12106
 
11954
12107
  addedItem: function(array, item, changeMeta, instanceMeta) {
11955
- var match = !!callback(item),
12108
+ var match = !!callback.call(this, item),
11956
12109
  filterIndex = instanceMeta.filteredArrayIndexes.addItem(changeMeta.index, match);
11957
12110
 
11958
12111
  if (match) {
@@ -12201,7 +12354,7 @@ Ember.computed.intersect = function () {
12201
12354
  */
12202
12355
  Ember.computed.setDiff = function (setAProperty, setBProperty) {
12203
12356
  if (arguments.length !== 2) {
12204
- throw new Error("setDiff requires exactly two dependent arrays.");
12357
+ throw new Ember.Error("setDiff requires exactly two dependent arrays.");
12205
12358
  }
12206
12359
  return Ember.arrayComputed.call(null, setAProperty, setBProperty, {
12207
12360
  addedItem: function (array, item, changeMeta, instanceMeta) {
@@ -12316,7 +12469,7 @@ function binarySearch(array, item, low, high) {
12316
12469
  ]});
12317
12470
 
12318
12471
  todoList.get('sortedTodos'); // [{name:'Documentation', priority:3}, {name:'Release', priority:1}, {name:'Unit Test', priority:2}]
12319
- todoList.get('priroityTodos'); // [{name:'Release', priority:1}, {name:'Unit Test', priority:2}, {name:'Documentation', priority:3}]
12472
+ todoList.get('priorityTodos'); // [{name:'Release', priority:1}, {name:'Unit Test', priority:2}, {name:'Documentation', priority:3}]
12320
12473
  ```
12321
12474
 
12322
12475
  @method computed.sort
@@ -12457,7 +12610,7 @@ Ember.RSVP = requireModule('rsvp');
12457
12610
 
12458
12611
  var STRING_DASHERIZE_REGEXP = (/[ _]/g);
12459
12612
  var STRING_DASHERIZE_CACHE = {};
12460
- var STRING_DECAMELIZE_REGEXP = (/([a-z])([A-Z])/g);
12613
+ var STRING_DECAMELIZE_REGEXP = (/([a-z\d])([A-Z])/g);
12461
12614
  var STRING_CAMELIZE_REGEXP = (/(\-|_|\.|\s)+(.)?/g);
12462
12615
  var STRING_UNDERSCORE_REGEXP_1 = (/([a-z\d])([A-Z]+)/g);
12463
12616
  var STRING_UNDERSCORE_REGEXP_2 = (/\-|\s+/g);
@@ -13124,7 +13277,7 @@ Ember.Copyable = Ember.Mixin.create(/** @scope Ember.Copyable.prototype */ {
13124
13277
  if (Ember.Freezable && Ember.Freezable.detect(this)) {
13125
13278
  return get(this, 'isFrozen') ? this : this.copy().freeze();
13126
13279
  } else {
13127
- throw new Error(Ember.String.fmt("%@ does not support freezing", [this]));
13280
+ throw new Ember.Error(Ember.String.fmt("%@ does not support freezing", [this]));
13128
13281
  }
13129
13282
  }
13130
13283
  });
@@ -13433,7 +13586,7 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,/**
13433
13586
  @return this
13434
13587
  */
13435
13588
  insertAt: function(idx, object) {
13436
- if (idx > get(this, 'length')) throw new Error(OUT_OF_RANGE_EXCEPTION) ;
13589
+ if (idx > get(this, 'length')) throw new Ember.Error(OUT_OF_RANGE_EXCEPTION) ;
13437
13590
  this.replace(idx, 0, [object]) ;
13438
13591
  return this ;
13439
13592
  },
@@ -13461,7 +13614,7 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,/**
13461
13614
  if ('number' === typeof start) {
13462
13615
 
13463
13616
  if ((start < 0) || (start >= get(this, 'length'))) {
13464
- throw new Error(OUT_OF_RANGE_EXCEPTION);
13617
+ throw new Ember.Error(OUT_OF_RANGE_EXCEPTION);
13465
13618
  }
13466
13619
 
13467
13620
  // fast case
@@ -14274,18 +14427,29 @@ Ember.TargetActionSupport = Ember.Mixin.create({
14274
14427
  */
14275
14428
  triggerAction: function(opts) {
14276
14429
  opts = opts || {};
14277
- var action = opts['action'] || get(this, 'action'),
14278
- target = opts['target'] || get(this, 'targetObject'),
14279
- actionContext = opts['actionContext'] || get(this, 'actionContextObject') || this;
14430
+ var action = opts.action || get(this, 'action'),
14431
+ target = opts.target || get(this, 'targetObject'),
14432
+ actionContext = opts.actionContext;
14433
+
14434
+ function args(options, actionName) {
14435
+ var ret = [];
14436
+ if (actionName) { ret.push(actionName); }
14437
+
14438
+ return ret.concat(options);
14439
+ }
14440
+
14441
+ if (typeof actionContext === 'undefined') {
14442
+ actionContext = get(this, 'actionContextObject') || this;
14443
+ }
14280
14444
 
14281
14445
  if (target && action) {
14282
14446
  var ret;
14283
14447
 
14284
14448
  if (target.send) {
14285
- ret = target.send.apply(target, [action, actionContext]);
14449
+ ret = target.send.apply(target, args(actionContext, action));
14286
14450
  } else {
14287
14451
  Ember.assert("The action '" + action + "' did not exist on " + target, typeof target[action] === 'function');
14288
- ret = target[action].apply(target, [actionContext]);
14452
+ ret = target[action].apply(target, args(actionContext));
14289
14453
  }
14290
14454
 
14291
14455
  if (ret !== false) ret = true;
@@ -14676,6 +14840,7 @@ function installPromise(proxy, promise) {
14676
14840
 
14677
14841
  If the controller is backing a template, the attributes are
14678
14842
  bindable from within that template
14843
+
14679
14844
  ```handlebars
14680
14845
  {{#if isPending}}
14681
14846
  loading...
@@ -14699,7 +14864,7 @@ Ember.PromiseProxyMixin = Ember.Mixin.create({
14699
14864
  installPromise(this, promise);
14700
14865
  return promise;
14701
14866
  } else {
14702
- throw new Error("PromiseProxy's promise must be set");
14867
+ throw new Ember.Error("PromiseProxy's promise must be set");
14703
14868
  }
14704
14869
  }),
14705
14870
 
@@ -14742,9 +14907,9 @@ Ember.TrackedArray = function (items) {
14742
14907
  var length = get(items, 'length');
14743
14908
 
14744
14909
  if (length) {
14745
- this._content = [new ArrayOperation(RETAIN, length, items)];
14910
+ this._operations = [new ArrayOperation(RETAIN, length, items)];
14746
14911
  } else {
14747
- this._content = [];
14912
+ this._operations = [];
14748
14913
  }
14749
14914
  };
14750
14915
 
@@ -14762,8 +14927,10 @@ Ember.TrackedArray.prototype = {
14762
14927
  @param newItems
14763
14928
  */
14764
14929
  addItems: function (index, newItems) {
14765
- var count = get(newItems, 'length'),
14766
- match = this._findArrayOperation(index),
14930
+ var count = get(newItems, 'length');
14931
+ if (count < 1) { return; }
14932
+
14933
+ var match = this._findArrayOperation(index),
14767
14934
  arrayOperation = match.operation,
14768
14935
  arrayOperationIndex = match.index,
14769
14936
  arrayOperationRangeStart = match.rangeStart,
@@ -14778,7 +14945,7 @@ Ember.TrackedArray.prototype = {
14778
14945
  if (arrayOperation) {
14779
14946
  if (!match.split) {
14780
14947
  // insert left of arrayOperation
14781
- this._content.splice(arrayOperationIndex, 0, newArrayOperation);
14948
+ this._operations.splice(arrayOperationIndex, 0, newArrayOperation);
14782
14949
  composeIndex = arrayOperationIndex;
14783
14950
  } else {
14784
14951
  this._split(arrayOperationIndex, index - arrayOperationRangeStart, newArrayOperation);
@@ -14786,7 +14953,7 @@ Ember.TrackedArray.prototype = {
14786
14953
  }
14787
14954
  } else {
14788
14955
  // insert at end
14789
- this._content.push(newArrayOperation);
14956
+ this._operations.push(newArrayOperation);
14790
14957
  composeIndex = arrayOperationIndex;
14791
14958
  }
14792
14959
 
@@ -14801,6 +14968,8 @@ Ember.TrackedArray.prototype = {
14801
14968
  @param count
14802
14969
  */
14803
14970
  removeItems: function (index, count) {
14971
+ if (count < 1) { return; }
14972
+
14804
14973
  var match = this._findArrayOperation(index),
14805
14974
  arrayOperation = match.operation,
14806
14975
  arrayOperationIndex = match.index,
@@ -14811,7 +14980,7 @@ Ember.TrackedArray.prototype = {
14811
14980
  newArrayOperation = new ArrayOperation(DELETE, count);
14812
14981
  if (!match.split) {
14813
14982
  // insert left of arrayOperation
14814
- this._content.splice(arrayOperationIndex, 0, newArrayOperation);
14983
+ this._operations.splice(arrayOperationIndex, 0, newArrayOperation);
14815
14984
  composeIndex = arrayOperationIndex;
14816
14985
  } else {
14817
14986
  this._split(arrayOperationIndex, index - arrayOperationRangeStart, newArrayOperation);
@@ -14826,30 +14995,29 @@ Ember.TrackedArray.prototype = {
14826
14995
  items in the array.
14827
14996
 
14828
14997
  `callback` will be called for each operation and will be passed the following arguments:
14829
- - {array} items The items for the given operation
14830
- - {number} offset The computed offset of the items, ie the index in the
14831
- array of the first item for this operation.
14832
- - {string} operation The type of the operation. One of
14833
- `Ember.TrackedArray.{RETAIN, DELETE, INSERT}`
14998
+ * {array} items The items for the given operation
14999
+ * {number} offset The computed offset of the items, ie the index in the
15000
+ array of the first item for this operation.
15001
+ * {string} operation The type of the operation. One of
15002
+ `Ember.TrackedArray.{RETAIN, DELETE, INSERT}`
14834
15003
 
14835
15004
  @method apply
14836
-
14837
15005
  @param {function} callback
14838
15006
  */
14839
15007
  apply: function (callback) {
14840
15008
  var items = [],
14841
15009
  offset = 0;
14842
15010
 
14843
- forEach(this._content, function (arrayOperation) {
14844
- callback(arrayOperation.items, offset, arrayOperation.operation);
15011
+ forEach(this._operations, function (arrayOperation) {
15012
+ callback(arrayOperation.items, offset, arrayOperation.type);
14845
15013
 
14846
- if (arrayOperation.operation !== DELETE) {
15014
+ if (arrayOperation.type !== DELETE) {
14847
15015
  offset += arrayOperation.count;
14848
15016
  items = items.concat(arrayOperation.items);
14849
15017
  }
14850
15018
  });
14851
15019
 
14852
- this._content = [new ArrayOperation(RETAIN, items.length, items)];
15020
+ this._operations = [new ArrayOperation(RETAIN, items.length, items)];
14853
15021
  },
14854
15022
 
14855
15023
  /**
@@ -14871,10 +15039,10 @@ Ember.TrackedArray.prototype = {
14871
15039
 
14872
15040
  // OPTIMIZE: we could search these faster if we kept a balanced tree.
14873
15041
  // find leftmost arrayOperation to the right of `index`
14874
- for (arrayOperationIndex = arrayOperationRangeStart = 0, len = this._content.length; arrayOperationIndex < len; ++arrayOperationIndex) {
14875
- arrayOperation = this._content[arrayOperationIndex];
15042
+ for (arrayOperationIndex = arrayOperationRangeStart = 0, len = this._operations.length; arrayOperationIndex < len; ++arrayOperationIndex) {
15043
+ arrayOperation = this._operations[arrayOperationIndex];
14876
15044
 
14877
- if (arrayOperation.operation === DELETE) { continue; }
15045
+ if (arrayOperation.type === DELETE) { continue; }
14878
15046
 
14879
15047
  arrayOperationRangeEnd = arrayOperationRangeStart + arrayOperation.count - 1;
14880
15048
 
@@ -14892,25 +15060,24 @@ Ember.TrackedArray.prototype = {
14892
15060
  },
14893
15061
 
14894
15062
  _split: function (arrayOperationIndex, splitIndex, newArrayOperation) {
14895
- var arrayOperation = this._content[arrayOperationIndex],
15063
+ var arrayOperation = this._operations[arrayOperationIndex],
14896
15064
  splitItems = arrayOperation.items.slice(splitIndex),
14897
- splitArrayOperation = new ArrayOperation(arrayOperation.operation, splitItems.length, splitItems);
15065
+ splitArrayOperation = new ArrayOperation(arrayOperation.type, splitItems.length, splitItems);
14898
15066
 
14899
15067
  // truncate LHS
14900
15068
  arrayOperation.count = splitIndex;
14901
15069
  arrayOperation.items = arrayOperation.items.slice(0, splitIndex);
14902
15070
 
14903
- this._content.splice(arrayOperationIndex + 1, 0, newArrayOperation, splitArrayOperation);
15071
+ this._operations.splice(arrayOperationIndex + 1, 0, newArrayOperation, splitArrayOperation);
14904
15072
  },
14905
15073
 
14906
- // TODO: unify _composeInsert, _composeDelete
14907
15074
  // see SubArray for a better implementation.
14908
15075
  _composeInsert: function (index) {
14909
- var newArrayOperation = this._content[index],
14910
- leftArrayOperation = this._content[index-1], // may be undefined
14911
- rightArrayOperation = this._content[index+1], // may be undefined
14912
- leftOp = leftArrayOperation && leftArrayOperation.operation,
14913
- rightOp = rightArrayOperation && rightArrayOperation.operation;
15076
+ var newArrayOperation = this._operations[index],
15077
+ leftArrayOperation = this._operations[index-1], // may be undefined
15078
+ rightArrayOperation = this._operations[index+1], // may be undefined
15079
+ leftOp = leftArrayOperation && leftArrayOperation.type,
15080
+ rightOp = rightArrayOperation && rightArrayOperation.type;
14914
15081
 
14915
15082
  if (leftOp === INSERT) {
14916
15083
  // merge left
@@ -14918,30 +15085,31 @@ Ember.TrackedArray.prototype = {
14918
15085
  leftArrayOperation.items = leftArrayOperation.items.concat(newArrayOperation.items);
14919
15086
 
14920
15087
  if (rightOp === INSERT) {
14921
- // also merge right
15088
+ // also merge right (we have split an insert with an insert)
14922
15089
  leftArrayOperation.count += rightArrayOperation.count;
14923
15090
  leftArrayOperation.items = leftArrayOperation.items.concat(rightArrayOperation.items);
14924
- this._content.splice(index, 2);
15091
+ this._operations.splice(index, 2);
14925
15092
  } else {
14926
15093
  // only merge left
14927
- this._content.splice(index, 1);
15094
+ this._operations.splice(index, 1);
14928
15095
  }
14929
15096
  } else if (rightOp === INSERT) {
14930
15097
  // merge right
14931
15098
  newArrayOperation.count += rightArrayOperation.count;
14932
15099
  newArrayOperation.items = newArrayOperation.items.concat(rightArrayOperation.items);
14933
- this._content.splice(index + 1, 1);
15100
+ this._operations.splice(index + 1, 1);
14934
15101
  }
14935
15102
  },
14936
15103
 
14937
15104
  _composeDelete: function (index) {
14938
- var arrayOperation = this._content[index],
15105
+ var arrayOperation = this._operations[index],
14939
15106
  deletesToGo = arrayOperation.count,
14940
- leftArrayOperation = this._content[index-1], // may be undefined
14941
- leftOp = leftArrayOperation && leftArrayOperation.operation,
15107
+ leftArrayOperation = this._operations[index-1], // may be undefined
15108
+ leftOp = leftArrayOperation && leftArrayOperation.type,
14942
15109
  nextArrayOperation,
14943
15110
  nextOp,
14944
15111
  nextCount,
15112
+ removeNewAndNextOp = false,
14945
15113
  removedItems = [];
14946
15114
 
14947
15115
  if (leftOp === DELETE) {
@@ -14950,8 +15118,8 @@ Ember.TrackedArray.prototype = {
14950
15118
  }
14951
15119
 
14952
15120
  for (var i = index + 1; deletesToGo > 0; ++i) {
14953
- nextArrayOperation = this._content[i];
14954
- nextOp = nextArrayOperation.operation;
15121
+ nextArrayOperation = this._operations[i];
15122
+ nextOp = nextArrayOperation.type;
14955
15123
  nextCount = nextArrayOperation.count;
14956
15124
 
14957
15125
  if (nextOp === DELETE) {
@@ -14960,6 +15128,7 @@ Ember.TrackedArray.prototype = {
14960
15128
  }
14961
15129
 
14962
15130
  if (nextCount > deletesToGo) {
15131
+ // d:2 {r,i}:5 we reduce the retain or insert, but it stays
14963
15132
  removedItems = removedItems.concat(nextArrayOperation.items.splice(0, deletesToGo));
14964
15133
  nextArrayOperation.count -= deletesToGo;
14965
15134
 
@@ -14971,29 +15140,57 @@ Ember.TrackedArray.prototype = {
14971
15140
 
14972
15141
  deletesToGo = 0;
14973
15142
  } else {
15143
+ if (nextCount === deletesToGo) {
15144
+ // Handle edge case of d:2 i:2 in which case both operations go away
15145
+ // during composition.
15146
+ removeNewAndNextOp = true;
15147
+ }
14974
15148
  removedItems = removedItems.concat(nextArrayOperation.items);
14975
15149
  deletesToGo -= nextCount;
14976
15150
  }
14977
15151
 
14978
15152
  if (nextOp === INSERT) {
15153
+ // d:2 i:3 will result in delete going away
14979
15154
  arrayOperation.count -= nextCount;
14980
15155
  }
14981
15156
  }
14982
15157
 
14983
15158
  if (arrayOperation.count > 0) {
14984
- this._content.splice(index+1, i-1-index);
15159
+ // compose our new delete with possibly several operations to the right of
15160
+ // disparate types
15161
+ this._operations.splice(index+1, i-1-index);
14985
15162
  } else {
14986
15163
  // The delete operation can go away; it has merely reduced some other
14987
- // operation, as in D:3 I:4
14988
- this._content.splice(index, 1);
15164
+ // operation, as in d:3 i:4; it may also have eliminated that operation,
15165
+ // as in d:3 i:3.
15166
+ this._operations.splice(index, removeNewAndNextOp ? 2 : 1);
14989
15167
  }
14990
15168
 
14991
15169
  return removedItems;
15170
+ },
15171
+
15172
+ toString: function () {
15173
+ var str = "";
15174
+ forEach(this._operations, function (operation) {
15175
+ str += " " + operation.type + ":" + operation.count;
15176
+ });
15177
+ return str.substring(1);
14992
15178
  }
14993
15179
  };
14994
15180
 
15181
+ /**
15182
+ Internal data structure to represent an array operation.
15183
+
15184
+ @method ArrayOperation
15185
+ @private
15186
+ @property {string} type The type of the operation. One of
15187
+ `Ember.TrackedArray.{RETAIN, INSERT, DELETE}`
15188
+ @property {number} count The number of items in this operation.
15189
+ @property {array} items The items of the operation, if included. RETAIN and
15190
+ INSERT include their items, DELETE does not.
15191
+ */
14995
15192
  function ArrayOperation (operation, count, items) {
14996
- this.operation = operation; // RETAIN | INSERT | DELETE
15193
+ this.type = operation; // RETAIN | INSERT | DELETE
14997
15194
  this.count = count;
14998
15195
  this.items = items;
14999
15196
  }
@@ -15061,7 +15258,7 @@ Ember.SubArray.prototype = {
15061
15258
  @param {number} index The index of the item in the tracked array.
15062
15259
  @param {boolean} match `true` iff the item is included in the subarray.
15063
15260
 
15064
- @returns {number} The index of the item in the subarray.
15261
+ @return {number} The index of the item in the subarray.
15065
15262
  */
15066
15263
  addItem: function(index, match) {
15067
15264
  var returnValue = -1,
@@ -15113,7 +15310,7 @@ Ember.SubArray.prototype = {
15113
15310
 
15114
15311
  @param {number} index The index of the item in the tracked array.
15115
15312
 
15116
- @returns {number} The index of the item in the subarray, or `-1` if the item
15313
+ @return {number} The index of the item in the subarray, or `-1` if the item
15117
15314
  was not in the subarray.
15118
15315
  */
15119
15316
  removeItem: function(index) {
@@ -15131,6 +15328,8 @@ Ember.SubArray.prototype = {
15131
15328
  self._operations.splice(operationIndex, 1);
15132
15329
  self._composeAt(operationIndex);
15133
15330
  }
15331
+ }, function() {
15332
+ throw new Ember.Error("Can't remove an item that has never been added.");
15134
15333
  });
15135
15334
 
15136
15335
  return returnValue;
@@ -15177,6 +15376,7 @@ Ember.SubArray.prototype = {
15177
15376
  if (otherOp.type === op.type) {
15178
15377
  op.count += otherOp.count;
15179
15378
  this._operations.splice(index-1, 1);
15379
+ --index;
15180
15380
  }
15181
15381
  }
15182
15382
 
@@ -15273,7 +15473,14 @@ function makeCtor() {
15273
15473
 
15274
15474
  Ember.assert("Ember.Object.create no longer supports mixing in other definitions, use createWithMixins instead.", !(properties instanceof Ember.Mixin));
15275
15475
 
15276
- for (var keyName in properties) {
15476
+ if (properties === null || typeof properties !== 'object') {
15477
+ Ember.assert("Ember.Object.create only accepts objects.");
15478
+ continue;
15479
+ }
15480
+
15481
+ var keyNames = Ember.keys(properties);
15482
+ for (var j = 0, ll = keyNames.length; j < ll; j++) {
15483
+ var keyName = keyNames[j];
15277
15484
  if (!properties.hasOwnProperty(keyName)) { continue; }
15278
15485
 
15279
15486
  var value = properties[keyName],
@@ -15459,7 +15666,10 @@ CoreObject.PrototypeMixin = Mixin.create({
15459
15666
  are also concatenated, in addition to `classNames`.
15460
15667
 
15461
15668
  This feature is available for you to use throughout the Ember object model,
15462
- although typical app developers are likely to use it infrequently.
15669
+ although typical app developers are likely to use it infrequently. Since
15670
+ it changes expectations about behavior of properties, you should properly
15671
+ document its usage in each individual concatenated property (to not
15672
+ mislead your users to think they can override the property in a subclass).
15463
15673
 
15464
15674
  @property concatenatedProperties
15465
15675
  @type Array
@@ -15599,6 +15809,86 @@ var ClassMixin = Mixin.create({
15599
15809
 
15600
15810
  isMethod: false,
15601
15811
 
15812
+ /**
15813
+ Creates a new subclass.
15814
+
15815
+ ```javascript
15816
+ App.Person = Ember.Object.extend({
15817
+ say: function(thing) {
15818
+ alert(thing);
15819
+ }
15820
+ });
15821
+ ```
15822
+
15823
+ This defines a new subclass of Ember.Object: `App.Person`. It contains one method: `say()`.
15824
+
15825
+ You can also create a subclass from any existing class by calling its `extend()` method. For example, you might want to create a subclass of Ember's built-in `Ember.View` class:
15826
+
15827
+ ```javascript
15828
+ App.PersonView = Ember.View.extend({
15829
+ tagName: 'li',
15830
+ classNameBindings: ['isAdministrator']
15831
+ });
15832
+ ```
15833
+
15834
+ When defining a subclass, you can override methods but still access the implementation of your parent class by calling the special `_super()` method:
15835
+
15836
+ ```javascript
15837
+ App.Person = Ember.Object.extend({
15838
+ say: function(thing) {
15839
+ var name = this.get('name');
15840
+ alert(name + ' says: ' + thing);
15841
+ }
15842
+ });
15843
+
15844
+ App.Soldier = App.Person.extend({
15845
+ say: function(thing) {
15846
+ this._super(thing + ", sir!");
15847
+ },
15848
+ march: function(numberOfHours) {
15849
+ alert(this.get('name') + ' marches for ' + numberOfHours + ' hours.')
15850
+ }
15851
+ });
15852
+
15853
+ var yehuda = App.Soldier.create({
15854
+ name: "Yehuda Katz"
15855
+ });
15856
+
15857
+ yehuda.say("Yes"); // alerts "Yehuda Katz says: Yes, sir!"
15858
+ ```
15859
+
15860
+ The `create()` on line #17 creates an *instance* of the `App.Soldier` class. The `extend()` on line #8 creates a *subclass* of `App.Person`. Any instance of the `App.Person` class will *not* have the `march()` method.
15861
+
15862
+ You can also pass `Ember.Mixin` classes to add additional properties to the subclass.
15863
+
15864
+ ```javascript
15865
+ App.Person = Ember.Object.extend({
15866
+ say: function(thing) {
15867
+ alert(this.get('name') + ' says: ' + thing);
15868
+ }
15869
+ });
15870
+
15871
+ App.SingingMixin = Ember.Mixin.create({
15872
+ sing: function(thing){
15873
+ alert(this.get('name') + ' sings: la la la ' + thing);
15874
+ }
15875
+ });
15876
+
15877
+ App.BroadwayStar = App.Person.extend(App.SingingMixin, {
15878
+ dance: function() {
15879
+ alert(this.get('name') + ' dances: tap tap tap tap ');
15880
+ }
15881
+ });
15882
+ ```
15883
+
15884
+ The `App.BroadwayStar` class contains three methods: `say()`, `sing()`, and `dance()`.
15885
+
15886
+ @method extend
15887
+ @static
15888
+
15889
+ @param {Ember.Mixin} [mixins]* One or more Ember.Mixin classes
15890
+ @param {Object} [arguments]* Object containing values to use within the new class
15891
+ */
15602
15892
  extend: function() {
15603
15893
  var Class = makeCtor(), proto;
15604
15894
  Class.ClassMixin = Mixin.create(this.ClassMixin);
@@ -15679,10 +15969,10 @@ var ClassMixin = Mixin.create({
15679
15969
  },
15680
15970
 
15681
15971
  /**
15682
-
15972
+
15683
15973
  Augments a constructor's prototype with additional
15684
15974
  properties and functions:
15685
-
15975
+
15686
15976
  ```javascript
15687
15977
  MyObject = Ember.Object.extend({
15688
15978
  name: 'an object'
@@ -15702,7 +15992,7 @@ var ClassMixin = Mixin.create({
15702
15992
 
15703
15993
  o.say("goodbye"); // logs "goodbye"
15704
15994
  ```
15705
-
15995
+
15706
15996
  To add functions and properties to the constructor itself,
15707
15997
  see `reopenClass`
15708
15998
 
@@ -15716,7 +16006,7 @@ var ClassMixin = Mixin.create({
15716
16006
 
15717
16007
  /**
15718
16008
  Augments a constructor's own properties and functions:
15719
-
16009
+
15720
16010
  ```javascript
15721
16011
  MyObject = Ember.Object.extend({
15722
16012
  name: 'an object'
@@ -15726,17 +16016,50 @@ var ClassMixin = Mixin.create({
15726
16016
  MyObject.reopenClass({
15727
16017
  canBuild: false
15728
16018
  });
15729
-
16019
+
15730
16020
  MyObject.canBuild; // false
15731
16021
  o = MyObject.create();
15732
16022
  ```
15733
-
16023
+
16024
+ In other words, this creates static properties and functions for the class. These are only available on the class
16025
+ and not on any instance of that class.
16026
+
16027
+ ```javascript
16028
+ App.Person = Ember.Object.extend({
16029
+ name : "",
16030
+ sayHello : function(){
16031
+ alert("Hello. My name is " + this.get('name'));
16032
+ }
16033
+ });
16034
+
16035
+ App.Person.reopenClass({
16036
+ species : "Homo sapiens",
16037
+ createPerson: function(newPersonsName){
16038
+ return App.Person.create({
16039
+ name:newPersonsName
16040
+ });
16041
+ }
16042
+ });
16043
+
16044
+ var tom = App.Person.create({
16045
+ name : "Tom Dale"
16046
+ });
16047
+ var yehuda = App.Person.createPerson("Yehuda Katz");
16048
+
16049
+ tom.sayHello(); // "Hello. My name is Tom Dale"
16050
+ yehuda.sayHello(); // "Hello. My name is Yehuda Katz"
16051
+ alert(App.Person.species); // "Homo sapiens"
16052
+ ```
16053
+
16054
+ Note that `species` and `createPerson` are *not* valid on the `tom` and `yehuda`
16055
+ variables. They are only valid on `App.Person`.
16056
+
15734
16057
  To add functions and properties to instances of
15735
16058
  a constructor by extending the constructor's prototype
15736
16059
  see `reopen`
15737
-
16060
+
15738
16061
  @method reopenClass
15739
- */
16062
+ */
15740
16063
  reopenClass: function() {
15741
16064
  reopen.apply(this.ClassMixin, arguments);
15742
16065
  applyMixin(this, arguments, false);
@@ -16295,7 +16618,7 @@ Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,/** @scope Ember.Array
16295
16618
  },
16296
16619
 
16297
16620
  _insertAt: function(idx, object) {
16298
- if (idx > get(this, 'content.length')) throw new Error(OUT_OF_RANGE_EXCEPTION);
16621
+ if (idx > get(this, 'content.length')) throw new Ember.Error(OUT_OF_RANGE_EXCEPTION);
16299
16622
  this._replace(idx, 0, [object]);
16300
16623
  return this;
16301
16624
  },
@@ -16315,7 +16638,7 @@ Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,/** @scope Ember.Array
16315
16638
  indices = [], i;
16316
16639
 
16317
16640
  if ((start < 0) || (start >= get(this, 'length'))) {
16318
- throw new Error(OUT_OF_RANGE_EXCEPTION);
16641
+ throw new Ember.Error(OUT_OF_RANGE_EXCEPTION);
16319
16642
  }
16320
16643
 
16321
16644
  if (len === undefined) len = 1;
@@ -17082,7 +17405,7 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
17082
17405
  @return {Ember.Set} An empty Set
17083
17406
  */
17084
17407
  clear: function() {
17085
- if (this.isFrozen) { throw new Error(Ember.FROZEN_ERROR); }
17408
+ if (this.isFrozen) { throw new Ember.Error(Ember.FROZEN_ERROR); }
17086
17409
 
17087
17410
  var len = get(this, 'length');
17088
17411
  if (len === 0) { return this; }
@@ -17192,7 +17515,7 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
17192
17515
  @return {Object} The removed object from the set or null.
17193
17516
  */
17194
17517
  pop: function() {
17195
- if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
17518
+ if (get(this, 'isFrozen')) throw new Ember.Error(Ember.FROZEN_ERROR);
17196
17519
  var obj = this.length > 0 ? this[this.length-1] : null;
17197
17520
  this.remove(obj);
17198
17521
  return obj;
@@ -17309,7 +17632,7 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
17309
17632
 
17310
17633
  // implements Ember.MutableEnumerable
17311
17634
  addObject: function(obj) {
17312
- if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
17635
+ if (get(this, 'isFrozen')) throw new Ember.Error(Ember.FROZEN_ERROR);
17313
17636
  if (isNone(obj)) return this; // nothing to do
17314
17637
 
17315
17638
  var guid = guidFor(obj),
@@ -17337,7 +17660,7 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
17337
17660
 
17338
17661
  // implements Ember.MutableEnumerable
17339
17662
  removeObject: function(obj) {
17340
- if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
17663
+ if (get(this, 'isFrozen')) throw new Ember.Error(Ember.FROZEN_ERROR);
17341
17664
  if (isNone(obj)) return this; // nothing to do
17342
17665
 
17343
17666
  var guid = guidFor(obj),
@@ -18044,7 +18367,7 @@ Ember.ArrayController = Ember.ArrayProxy.extend(Ember.ControllerMixin,
18044
18367
  fullName = "controller:" + controllerClass;
18045
18368
 
18046
18369
  if (!container.has(fullName)) {
18047
- throw new Error('Could not resolve itemController: "' + controllerClass + '"');
18370
+ throw new Ember.Error('Could not resolve itemController: "' + controllerClass + '"');
18048
18371
  }
18049
18372
 
18050
18373
  subController = container.lookupFactory(fullName).create({
@@ -18366,6 +18689,19 @@ function escapeAttribute(value) {
18366
18689
  return string.replace(BAD_CHARS_REGEXP, escapeChar);
18367
18690
  }
18368
18691
 
18692
+ // IE 6/7 have bugs arond setting names on inputs during creation.
18693
+ // From http://msdn.microsoft.com/en-us/library/ie/ms536389(v=vs.85).aspx:
18694
+ // "To include the NAME attribute at run time on objects created with the createElement method, use the eTag."
18695
+ var canSetNameOnInputs = (function() {
18696
+ var div = document.createElement('div'),
18697
+ el = document.createElement('input');
18698
+
18699
+ el.setAttribute('name', 'foo');
18700
+ div.appendChild(el);
18701
+
18702
+ return !!div.innerHTML.match('foo');
18703
+ })();
18704
+
18369
18705
  /**
18370
18706
  `Ember.RenderBuffer` gathers information regarding the a view and generates the
18371
18707
  final representation. `Ember.RenderBuffer` will generate HTML which can be pushed
@@ -18725,14 +19061,22 @@ Ember._RenderBuffer.prototype =
18725
19061
 
18726
19062
  generateElement: function() {
18727
19063
  var tagName = this.tagNames.pop(), // pop since we don't need to close
18728
- element = document.createElement(tagName),
18729
- $element = Ember.$(element),
18730
19064
  id = this.elementId,
18731
19065
  classes = this.classes,
18732
19066
  attrs = this.elementAttributes,
18733
19067
  props = this.elementProperties,
18734
19068
  style = this.elementStyle,
18735
- styleBuffer = '', attr, prop;
19069
+ styleBuffer = '', attr, prop, tagString;
19070
+
19071
+ if (attrs && attrs.name && !canSetNameOnInputs) {
19072
+ // IE allows passing a tag to createElement. See note on `canSetNameOnInputs` above as well.
19073
+ tagString = '<'+stripTagName(tagName)+' name="'+escapeAttribute(attrs.name)+'">';
19074
+ } else {
19075
+ tagString = tagName;
19076
+ }
19077
+
19078
+ var element = document.createElement(tagString),
19079
+ $element = Ember.$(element);
18736
19080
 
18737
19081
  if (id) {
18738
19082
  $element.attr('id', id);
@@ -19127,6 +19471,7 @@ var get = Ember.get, set = Ember.set;
19127
19471
  var guidFor = Ember.guidFor;
19128
19472
  var a_forEach = Ember.EnumerableUtils.forEach;
19129
19473
  var a_addObject = Ember.EnumerableUtils.addObject;
19474
+ var meta = Ember.meta;
19130
19475
 
19131
19476
  var childViewsProperty = Ember.computed(function() {
19132
19477
  var childViews = this._childViews, ret = Ember.A(), view = this;
@@ -19147,7 +19492,7 @@ var childViewsProperty = Ember.computed(function() {
19147
19492
  Ember.deprecate("Manipulating an Ember.ContainerView through its childViews property is deprecated. Please use the ContainerView instance itself as an Ember.MutableArray.");
19148
19493
  return view.replace(idx, removedCount, addedViews);
19149
19494
  }
19150
- throw new Error("childViews is immutable");
19495
+ throw new Ember.Error("childViews is immutable");
19151
19496
  };
19152
19497
 
19153
19498
  return ret;
@@ -20837,8 +21182,8 @@ Ember.View = Ember.CoreView.extend(
20837
21182
  If you write a `willDestroyElement()` handler, you can assume that your
20838
21183
  `didInsertElement()` handler was called earlier for the same element.
20839
21184
 
20840
- Normally you will not call or override this method yourself, but you may
20841
- want to implement the above callbacks when it is run.
21185
+ You should not call or override this method yourself, but you may
21186
+ want to implement the above callbacks.
20842
21187
 
20843
21188
  @method destroyElement
20844
21189
  @return {Ember.View} receiver
@@ -20875,12 +21220,6 @@ Ember.View = Ember.CoreView.extend(
20875
21220
  return viewCollection;
20876
21221
  },
20877
21222
 
20878
- _elementWillChange: Ember.beforeObserver(function() {
20879
- this.forEachChildView(function(view) {
20880
- Ember.propertyWillChange(view, 'element');
20881
- });
20882
- }, 'element'),
20883
-
20884
21223
  /**
20885
21224
  @private
20886
21225
 
@@ -20892,7 +21231,7 @@ Ember.View = Ember.CoreView.extend(
20892
21231
  */
20893
21232
  _elementDidChange: Ember.observer(function() {
20894
21233
  this.forEachChildView(function(view) {
20895
- Ember.propertyDidChange(view, 'element');
21234
+ delete meta(view).cache.element;
20896
21235
  });
20897
21236
  }, 'element'),
20898
21237
 
@@ -21340,6 +21679,7 @@ Ember.View = Ember.CoreView.extend(
21340
21679
 
21341
21680
  if (priorState && priorState.exit) { priorState.exit(this); }
21342
21681
  if (currentState.enter) { currentState.enter(this); }
21682
+ if (state === 'inDOM') { delete Ember.meta(this).cache.element; }
21343
21683
 
21344
21684
  if (children !== false) {
21345
21685
  this.forEachChildView(function(view) {
@@ -21371,6 +21711,10 @@ Ember.View = Ember.CoreView.extend(
21371
21711
  target = null;
21372
21712
  }
21373
21713
 
21714
+ if (!root || typeof root !== 'object') {
21715
+ return;
21716
+ }
21717
+
21374
21718
  var view = this,
21375
21719
  stateCheckedObserver = function() {
21376
21720
  view.currentState.invokeObserver(this, observer);
@@ -21687,10 +22031,18 @@ Ember.merge(preRender, {
21687
22031
  var viewCollection = view.viewHierarchyCollection();
21688
22032
 
21689
22033
  viewCollection.trigger('willInsertElement');
21690
- // after createElement, the view will be in the hasElement state.
22034
+
21691
22035
  fn.call(view);
21692
- viewCollection.transitionTo('inDOM', false);
21693
- viewCollection.trigger('didInsertElement');
22036
+
22037
+ // We transition to `inDOM` if the element exists in the DOM
22038
+ var element = view.get('element');
22039
+ while (element = element.parentNode) {
22040
+ if (element === document) {
22041
+ viewCollection.transitionTo('inDOM', false);
22042
+ viewCollection.trigger('didInsertElement');
22043
+ }
22044
+ }
22045
+
21694
22046
  },
21695
22047
 
21696
22048
  renderToBufferIfNeeded: function(view, buffer) {
@@ -21899,7 +22251,7 @@ Ember.merge(inDOM, {
21899
22251
  }
21900
22252
 
21901
22253
  view.addBeforeObserver('elementId', function() {
21902
- throw new Error("Changing a view's elementId after creation is not allowed");
22254
+ throw new Ember.Error("Changing a view's elementId after creation is not allowed");
21903
22255
  });
21904
22256
  },
21905
22257
 
@@ -22139,30 +22491,6 @@ var ViewCollection = Ember._ViewCollection;
22139
22491
  or layout being rendered. The HTML contents of a `Ember.ContainerView`'s DOM
22140
22492
  representation will only be the rendered HTML of its child views.
22141
22493
 
22142
- ## Binding a View to Display
22143
-
22144
- If you would like to display a single view in your ContainerView, you can set
22145
- its `currentView` property. When the `currentView` property is set to a view
22146
- instance, it will be added to the ContainerView. If the `currentView` property
22147
- is later changed to a different view, the new view will replace the old view.
22148
- If `currentView` is set to `null`, the last `currentView` will be removed.
22149
-
22150
- This functionality is useful for cases where you want to bind the display of
22151
- a ContainerView to a controller or state manager. For example, you can bind
22152
- the `currentView` of a container to a controller like this:
22153
-
22154
- ```javascript
22155
- App.appController = Ember.Object.create({
22156
- view: Ember.View.create({
22157
- templateName: 'person_template'
22158
- })
22159
- });
22160
- ```
22161
-
22162
- ```handlebars
22163
- {{view Ember.ContainerView currentViewBinding="App.appController.view"}}
22164
- ```
22165
-
22166
22494
  @class ContainerView
22167
22495
  @namespace Ember
22168
22496
  @extends Ember.View
@@ -22347,7 +22675,7 @@ Ember.merge(states._default, {
22347
22675
 
22348
22676
  Ember.merge(states.inBuffer, {
22349
22677
  childViewsDidChange: function(parentView, views, start, added) {
22350
- throw new Error('You cannot modify child views while in the inBuffer state');
22678
+ throw new Ember.Error('You cannot modify child views while in the inBuffer state');
22351
22679
  }
22352
22680
  });
22353
22681
 
@@ -22839,7 +23167,9 @@ Ember.CollectionView.CONTAINER_MAP = {
22839
23167
 
22840
23168
 
22841
23169
  (function() {
22842
- var get = Ember.get, set = Ember.set, isNone = Ember.isNone;
23170
+ var get = Ember.get, set = Ember.set, isNone = Ember.isNone,
23171
+ a_slice = Array.prototype.slice;
23172
+
22843
23173
 
22844
23174
  /**
22845
23175
  @module ember
@@ -22897,8 +23227,10 @@ var get = Ember.get, set = Ember.set, isNone = Ember.isNone;
22897
23227
 
22898
23228
  ```javascript
22899
23229
  App.AppProfileComponent = Ember.Component.extend({
22900
- hello: function(name) {
22901
- console.log("Hello", name);
23230
+ actions: {
23231
+ hello: function(name) {
23232
+ console.log("Hello", name);
23233
+ }
22902
23234
  }
22903
23235
  });
22904
23236
  ```
@@ -22952,7 +23284,7 @@ Ember.Component = Ember.View.extend(Ember.TargetActionSupport, {
22952
23284
  isVirtual: true,
22953
23285
  tagName: '',
22954
23286
  _contextView: parentView,
22955
- template: get(this, 'template'),
23287
+ template: template,
22956
23288
  context: get(parentView, 'context'),
22957
23289
  controller: get(parentView, 'controller'),
22958
23290
  templateData: { keywords: parentView.cloneKeywords() }
@@ -23011,8 +23343,10 @@ Ember.Component = Ember.View.extend(Ember.TargetActionSupport, {
23011
23343
  });
23012
23344
 
23013
23345
  App.CategoriesController = Ember.Controller.extend({
23014
- didClickCategory: function(category) {
23015
- //Do something with the node/category that was clicked
23346
+ actions: {
23347
+ didClickCategory: function(category) {
23348
+ //Do something with the node/category that was clicked
23349
+ }
23016
23350
  }
23017
23351
  });
23018
23352
  ```
@@ -23026,8 +23360,9 @@ Ember.Component = Ember.View.extend(Ember.TargetActionSupport, {
23026
23360
  @param [action] {String} the action to trigger
23027
23361
  @param [context] {*} a context to send with the action
23028
23362
  */
23029
- sendAction: function(action, context) {
23030
- var actionName;
23363
+ sendAction: function(action) {
23364
+ var actionName,
23365
+ contexts = a_slice.call(arguments, 1);
23031
23366
 
23032
23367
  // Send the default action
23033
23368
  if (action === undefined) {
@@ -23043,7 +23378,7 @@ Ember.Component = Ember.View.extend(Ember.TargetActionSupport, {
23043
23378
 
23044
23379
  this.triggerAction({
23045
23380
  action: actionName,
23046
- actionContext: context
23381
+ actionContext: contexts
23047
23382
  });
23048
23383
  }
23049
23384
  });
@@ -23256,6 +23591,14 @@ define("metamorph",
23256
23591
  range.insertNode(fragment);
23257
23592
  };
23258
23593
 
23594
+ /**
23595
+ * @public
23596
+ *
23597
+ * Remove this object (including starting and ending
23598
+ * placeholders).
23599
+ *
23600
+ * @method remove
23601
+ */
23259
23602
  removeFunc = function() {
23260
23603
  // get a range for the current metamorph object including
23261
23604
  // the starting and ending placeholders.
@@ -23296,7 +23639,7 @@ define("metamorph",
23296
23639
  };
23297
23640
 
23298
23641
  } else {
23299
- /**
23642
+ /*
23300
23643
  * This code is mostly taken from jQuery, with one exception. In jQuery's case, we
23301
23644
  * have some HTML and we need to figure out how to convert it into some nodes.
23302
23645
  *
@@ -23350,12 +23693,12 @@ define("metamorph",
23350
23693
  }
23351
23694
  };
23352
23695
 
23353
- /**
23696
+ /*
23354
23697
  * Given a parent node and some HTML, generate a set of nodes. Return the first
23355
23698
  * node, which will allow us to traverse the rest using nextSibling.
23356
23699
  *
23357
23700
  * We need to do this because innerHTML in IE does not really parse the nodes.
23358
- **/
23701
+ */
23359
23702
  var firstNodeFor = function(parentNode, html) {
23360
23703
  var arr = wrapMap[parentNode.tagName.toLowerCase()] || wrapMap._default;
23361
23704
  var depth = arr[0], start = arr[1], end = arr[2];
@@ -23388,7 +23731,7 @@ define("metamorph",
23388
23731
  return element;
23389
23732
  };
23390
23733
 
23391
- /**
23734
+ /*
23392
23735
  * In some cases, Internet Explorer can create an anonymous node in
23393
23736
  * the hierarchy with no tagName. You can create this scenario via:
23394
23737
  *
@@ -23398,7 +23741,7 @@ define("metamorph",
23398
23741
  *
23399
23742
  * If our script markers are inside such a node, we need to find that
23400
23743
  * node and use *it* as the marker.
23401
- **/
23744
+ */
23402
23745
  var realNode = function(start) {
23403
23746
  while (start.parentNode.tagName === "") {
23404
23747
  start = start.parentNode;
@@ -23407,7 +23750,7 @@ define("metamorph",
23407
23750
  return start;
23408
23751
  };
23409
23752
 
23410
- /**
23753
+ /*
23411
23754
  * When automatically adding a tbody, Internet Explorer inserts the
23412
23755
  * tbody immediately before the first <tr>. Other browsers create it
23413
23756
  * before the first node, no matter what.
@@ -23434,7 +23777,8 @@ define("metamorph",
23434
23777
  *
23435
23778
  * This code reparents the first script tag by making it the tbody's
23436
23779
  * first child.
23437
- **/
23780
+ *
23781
+ */
23438
23782
  var fixParentage = function(start, end) {
23439
23783
  if (start.parentNode !== end.parentNode) {
23440
23784
  end.parentNode.insertBefore(start, end.parentNode.firstChild);
@@ -23633,20 +23977,6 @@ Ember.assert("Ember Handlebars requires Handlebars version 1.0.0, COMPILER_REVIS
23633
23977
  */
23634
23978
  Ember.Handlebars = objectCreate(Handlebars);
23635
23979
 
23636
- function makeBindings(options) {
23637
- var hash = options.hash,
23638
- hashType = options.hashTypes;
23639
-
23640
- for (var prop in hash) {
23641
- if (hashType[prop] === 'ID') {
23642
- hash[prop + 'Binding'] = hash[prop];
23643
- hashType[prop + 'Binding'] = 'STRING';
23644
- delete hash[prop];
23645
- delete hashType[prop];
23646
- }
23647
- }
23648
- }
23649
-
23650
23980
  /**
23651
23981
  Register a bound helper or custom view helper.
23652
23982
 
@@ -23706,7 +24036,6 @@ Ember.Handlebars.helper = function(name, value) {
23706
24036
  if (Ember.View.detect(value)) {
23707
24037
  Ember.Handlebars.registerHelper(name, function(options) {
23708
24038
  Ember.assert("You can only pass attributes (such as name=value) not bare values to a helper for a View", arguments.length < 2);
23709
- makeBindings(options);
23710
24039
  return Ember.Handlebars.helpers.view.call(this, value, options);
23711
24040
  });
23712
24041
  } else {
@@ -23754,7 +24083,6 @@ if (Handlebars.JavaScriptCompiler) {
23754
24083
 
23755
24084
  Ember.Handlebars.JavaScriptCompiler.prototype.namespace = "Ember.Handlebars";
23756
24085
 
23757
-
23758
24086
  Ember.Handlebars.JavaScriptCompiler.prototype.initializeBuffer = function() {
23759
24087
  return "''";
23760
24088
  };
@@ -23858,7 +24186,7 @@ if (Handlebars.compile) {
23858
24186
 
23859
24187
  var template = Ember.Handlebars.template(templateSpec);
23860
24188
  template.isMethod = false; //Make sure we don't wrap templates with ._super
23861
-
24189
+
23862
24190
  return template;
23863
24191
  };
23864
24192
  }
@@ -24126,7 +24454,8 @@ Ember.Handlebars.registerBoundHelper = function(name, fn) {
24126
24454
  data = options.data,
24127
24455
  hash = options.hash,
24128
24456
  view = data.view,
24129
- currentContext = (options.contexts && options.contexts[0]) || this,
24457
+ contexts = options.contexts,
24458
+ currentContext = (contexts && contexts.length) ? contexts[0] : this,
24130
24459
  prefixPathForDependentKeys = '',
24131
24460
  loc, len, hashOption,
24132
24461
  boundOption, property,
@@ -24251,7 +24580,7 @@ function evaluateUnboundHelper(context, fn, normalizedProperties, options) {
24251
24580
 
24252
24581
  for(loc = 0, len = normalizedProperties.length; loc < len; ++loc) {
24253
24582
  property = normalizedProperties[loc];
24254
- args.push(Ember.Handlebars.get(context, property.path, options));
24583
+ args.push(Ember.Handlebars.get(property.root, property.path, options));
24255
24584
  }
24256
24585
  args.push(options);
24257
24586
  return fn.apply(context, args);
@@ -24895,16 +25224,16 @@ function bind(property, options, preserveContext, shouldDisplay, valueNormalizer
24895
25224
  }
24896
25225
  }
24897
25226
 
24898
- function simpleBind(property, options) {
25227
+ function simpleBind(currentContext, property, options) {
24899
25228
  var data = options.data,
24900
25229
  view = data.view,
24901
- currentContext = this,
24902
- normalized, observer;
25230
+ normalized, observer, pathRoot, output;
24903
25231
 
24904
25232
  normalized = normalizePath(currentContext, property, data);
25233
+ pathRoot = normalized.root;
24905
25234
 
24906
25235
  // Set up observers for observable objects
24907
- if ('object' === typeof this) {
25236
+ if (pathRoot && ('object' === typeof pathRoot)) {
24908
25237
  if (data.insideGroup) {
24909
25238
  observer = function() {
24910
25239
  Ember.run.once(view, 'rerender');
@@ -24936,7 +25265,8 @@ function simpleBind(property, options) {
24936
25265
  } else {
24937
25266
  // The object is not observable, so just render it out and
24938
25267
  // be done with it.
24939
- data.buffer.push(handlebarsGet(currentContext, property, options));
25268
+ output = handlebarsGet(currentContext, property, options);
25269
+ data.buffer.push((output === null || typeof output === 'undefined') ? '' : output);
24940
25270
  }
24941
25271
  }
24942
25272
 
@@ -24993,10 +25323,10 @@ EmberHandlebars.registerHelper('_triageMustache', function(property, fn) {
24993
25323
  EmberHandlebars.registerHelper('bind', function(property, options) {
24994
25324
  Ember.assert("You cannot pass more than one argument to the bind helper", arguments.length <= 2);
24995
25325
 
24996
- var context = (options.contexts && options.contexts[0]) || this;
25326
+ var context = (options.contexts && options.contexts.length) ? options.contexts[0] : this;
24997
25327
 
24998
25328
  if (!options.fn) {
24999
- return simpleBind.call(context, property, options);
25329
+ return simpleBind(context, property, options);
25000
25330
  }
25001
25331
 
25002
25332
  return bind.call(context, property, options, false, exists);
@@ -25021,7 +25351,7 @@ EmberHandlebars.registerHelper('bind', function(property, options) {
25021
25351
  @return {String} HTML string
25022
25352
  */
25023
25353
  EmberHandlebars.registerHelper('boundIf', function(property, fn) {
25024
- var context = (fn.contexts && fn.contexts[0]) || this;
25354
+ var context = (fn.contexts && fn.contexts.length) ? fn.contexts[0] : this;
25025
25355
  var func = function(result) {
25026
25356
  var truthy = result && get(result, 'isTruthy');
25027
25357
  if (typeof truthy === 'boolean') { return truthy; }
@@ -25471,6 +25801,35 @@ var EmberHandlebars = Ember.Handlebars;
25471
25801
  var LOWERCASE_A_Z = /^[a-z]/;
25472
25802
  var VIEW_PREFIX = /^view\./;
25473
25803
 
25804
+ function makeBindings(thisContext, options) {
25805
+ var hash = options.hash,
25806
+ hashType = options.hashTypes;
25807
+
25808
+ for (var prop in hash) {
25809
+ if (hashType[prop] === 'ID') {
25810
+
25811
+ var value = hash[prop];
25812
+
25813
+ if (Ember.IS_BINDING.test(prop)) {
25814
+ Ember.warn("You're attempting to render a view by passing " + prop + "=" + value + " to a view helper, but this syntax is ambiguous. You should either surround " + value + " in quotes or remove `Binding` from " + prop + ".");
25815
+ } else {
25816
+ hash[prop + 'Binding'] = value;
25817
+ hashType[prop + 'Binding'] = 'STRING';
25818
+ delete hash[prop];
25819
+ delete hashType[prop];
25820
+ }
25821
+ }
25822
+ }
25823
+
25824
+ if (hash.hasOwnProperty('idBinding')) {
25825
+ // id can't be bound, so just perform one-time lookup.
25826
+ hash.id = EmberHandlebars.get(thisContext, hash.idBinding, options);
25827
+ hashType.id = 'STRING';
25828
+ delete hash.idBinding;
25829
+ delete hashType.idBinding;
25830
+ }
25831
+ }
25832
+
25474
25833
  EmberHandlebars.ViewHelper = Ember.Object.create({
25475
25834
 
25476
25835
  propertiesFromHTMLOptions: function(options, thisContext) {
@@ -25580,6 +25939,8 @@ EmberHandlebars.ViewHelper = Ember.Object.create({
25580
25939
  fn = options.fn,
25581
25940
  newView;
25582
25941
 
25942
+ makeBindings(thisContext, options);
25943
+
25583
25944
  if ('string' === typeof path) {
25584
25945
 
25585
25946
  // TODO: this is a lame conditional, this should likely change
@@ -26070,7 +26431,7 @@ Ember.Handlebars.registerHelper('unbound', function(property, fn) {
26070
26431
  return out;
26071
26432
  }
26072
26433
 
26073
- context = (fn.contexts && fn.contexts[0]) || this;
26434
+ context = (fn.contexts && fn.contexts.length) ? fn.contexts[0] : this;
26074
26435
  return handlebarsGet(context, property, fn);
26075
26436
  });
26076
26437
 
@@ -26100,7 +26461,7 @@ var handlebarsGet = Ember.Handlebars.get, normalizePath = Ember.Handlebars.norma
26100
26461
  @param {String} property
26101
26462
  */
26102
26463
  Ember.Handlebars.registerHelper('log', function(property, options) {
26103
- var context = (options.contexts && options.contexts[0]) || this,
26464
+ var context = (options.contexts && options.contexts.length) ? options.contexts[0] : this,
26104
26465
  normalized = normalizePath(context, property, options.data),
26105
26466
  pathRoot = normalized.root,
26106
26467
  path = normalized.path,
@@ -26656,7 +27017,6 @@ Ember.Handlebars.registerHelper('partial', function(name, options) {
26656
27017
  var get = Ember.get, set = Ember.set;
26657
27018
 
26658
27019
  /**
26659
-
26660
27020
  `{{yield}}` denotes an area of a template that will be rendered inside
26661
27021
  of another template. It has two main uses:
26662
27022
 
@@ -26715,11 +27075,11 @@ var get = Ember.get, set = Ember.set;
26715
27075
  <!-- application.hbs -->
26716
27076
  {{#labeled-textfield value=someProperty}}
26717
27077
  First name:
26718
- {{/my-component}}
27078
+ {{/labeled-textfield}}
26719
27079
  ```
26720
27080
 
26721
27081
  ```handlebars
26722
- <!-- components/my-component.hbs -->
27082
+ <!-- components/labeled-textfield.hbs -->
26723
27083
  <label>
26724
27084
  {{yield}} {{input value=value}}
26725
27085
  </label>
@@ -26917,7 +27277,7 @@ Ember.TextSupport = Ember.Mixin.create({
26917
27277
  Options are:
26918
27278
 
26919
27279
  * `enter`: the user pressed enter
26920
- * `keypress`: the user pressed a key
27280
+ * `keyPress`: the user pressed a key
26921
27281
 
26922
27282
  @property onEvent
26923
27283
  @type String
@@ -26960,7 +27320,7 @@ Ember.TextSupport = Ember.Mixin.create({
26960
27320
  Called by the `Ember.TextSupport` mixin on keyUp if keycode matches 13.
26961
27321
  Uses sendAction to send the `enter` action to the controller.
26962
27322
 
26963
- @method insertNewLine
27323
+ @method insertNewline
26964
27324
  @param {Event} event
26965
27325
  */
26966
27326
  insertNewline: function(event) {
@@ -26971,8 +27331,8 @@ Ember.TextSupport = Ember.Mixin.create({
26971
27331
  /**
26972
27332
  Called when the user hits escape.
26973
27333
 
26974
- Called by the `Ember.TextSupport` mixin on keyUp if keycode matches 13.
26975
- Uses sendAction to send the `enter` action to the controller.
27334
+ Called by the `Ember.TextSupport` mixin on keyUp if keycode matches 27.
27335
+ Uses sendAction to send the `escape-press` action to the controller.
26976
27336
 
26977
27337
  @method cancel
26978
27338
  @param {Event} event
@@ -27062,7 +27422,7 @@ var get = Ember.get, set = Ember.set;
27062
27422
  The internal class used to create text inputs when the `{{input}}`
27063
27423
  helper is used with `type` of `text`.
27064
27424
 
27065
- See Handlebars.helpers.input for usage details.
27425
+ See [handlebars.helpers.input](api/classes/Ember.Handlebars.helpers.html#method_input) for usage details.
27066
27426
 
27067
27427
  ## Layout and LayoutName properties
27068
27428
 
@@ -27072,7 +27432,7 @@ var get = Ember.get, set = Ember.set;
27072
27432
 
27073
27433
  @class TextField
27074
27434
  @namespace Ember
27075
- @extends Ember.View
27435
+ @extends Ember.Component
27076
27436
  @uses Ember.TextSupport
27077
27437
  */
27078
27438
  Ember.TextField = Ember.Component.extend(Ember.TextSupport,
@@ -27264,7 +27624,7 @@ var get = Ember.get, set = Ember.set;
27264
27624
  The internal class used to create textarea element when the `{{textarea}}`
27265
27625
  helper is used.
27266
27626
 
27267
- See handlebars.helpers.textarea for usage details.
27627
+ See [handlebars.helpers.textarea](/api/classes/Ember.Handlebars.helpers.html#method_textarea) for usage details.
27268
27628
 
27269
27629
  ## Layout and LayoutName properties
27270
27630
 
@@ -27274,7 +27634,7 @@ var get = Ember.get, set = Ember.set;
27274
27634
 
27275
27635
  @class TextArea
27276
27636
  @namespace Ember
27277
- @extends Ember.View
27637
+ @extends Ember.Component
27278
27638
  @uses Ember.TextSupport
27279
27639
  */
27280
27640
  Ember.TextArea = Ember.Component.extend(Ember.TextSupport, {
@@ -27393,7 +27753,7 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27393
27753
  `content` property. The underlying data object of the selected `<option>` is
27394
27754
  stored in the `Element.Select`'s `value` property.
27395
27755
 
27396
- ### `content` as an array of Strings
27756
+ ## The Content Property (array of strings)
27397
27757
 
27398
27758
  The simplest version of an `Ember.Select` takes an array of strings as its
27399
27759
  `content` property. The string will be used as both the `value` property and
@@ -27408,7 +27768,7 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27408
27768
  ```
27409
27769
 
27410
27770
  ```handlebars
27411
- {{view Ember.Select contentBinding="names"}}
27771
+ {{view Ember.Select content=names}}
27412
27772
  ```
27413
27773
 
27414
27774
  Would result in the following HTML:
@@ -27421,7 +27781,7 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27421
27781
  ```
27422
27782
 
27423
27783
  You can control which `<option>` is selected through the `Ember.Select`'s
27424
- `value` property directly or as a binding:
27784
+ `value` property:
27425
27785
 
27426
27786
  ```javascript
27427
27787
  App.ApplicationController = Ember.Controller.extend({
@@ -27432,8 +27792,8 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27432
27792
 
27433
27793
  ```handlebars
27434
27794
  {{view Ember.Select
27435
- contentBinding="names"
27436
- valueBinding="selectedName"
27795
+ content=names
27796
+ value=selectedName
27437
27797
  }}
27438
27798
  ```
27439
27799
 
@@ -27449,7 +27809,7 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27449
27809
  A user interacting with the rendered `<select>` to choose "Yehuda" would
27450
27810
  update the value of `selectedName` to "Yehuda".
27451
27811
 
27452
- ### `content` as an Array of Objects
27812
+ ## The Content Property (array of Objects)
27453
27813
 
27454
27814
  An `Ember.Select` can also take an array of JavaScript or Ember objects as
27455
27815
  its `content` property.
@@ -27474,7 +27834,7 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27474
27834
 
27475
27835
  ```handlebars
27476
27836
  {{view Ember.Select
27477
- contentBinding="programmers"
27837
+ content=programmers
27478
27838
  optionValuePath="content.id"
27479
27839
  optionLabelPath="content.firstName"}}
27480
27840
  ```
@@ -27489,8 +27849,7 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27489
27849
  ```
27490
27850
 
27491
27851
  The `value` attribute of the selected `<option>` within an `Ember.Select`
27492
- can be bound to a property on another object by providing a
27493
- `valueBinding` option:
27852
+ can be bound to a property on another object:
27494
27853
 
27495
27854
  ```javascript
27496
27855
  App.ApplicationController = Ember.Controller.extend({
@@ -27506,10 +27865,10 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27506
27865
 
27507
27866
  ```handlebars
27508
27867
  {{view Ember.Select
27509
- contentBinding="programmers"
27868
+ content=programmers
27510
27869
  optionValuePath="content.id"
27511
27870
  optionLabelPath="content.firstName"
27512
- valueBinding="currentProgrammer.id"}}
27871
+ value=currentProgrammer.id}}
27513
27872
  ```
27514
27873
 
27515
27874
  Would result in the following HTML with a selected option:
@@ -27526,8 +27885,8 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27526
27885
  to match the `value` property of the newly selected `<option>`.
27527
27886
 
27528
27887
  Alternatively, you can control selection through the underlying objects
27529
- used to render each object providing a `selectionBinding`. When the selected
27530
- `<option>` is changed, the property path provided to `selectionBinding`
27888
+ used to render each object by binding the `selection` option. When the selected
27889
+ `<option>` is changed, the property path provided to `selection`
27531
27890
  will be updated to match the content object of the rendered `<option>`
27532
27891
  element:
27533
27892
 
@@ -27543,10 +27902,10 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27543
27902
 
27544
27903
  ```handlebars
27545
27904
  {{view Ember.Select
27546
- contentBinding="programmers"
27905
+ content=programmers
27547
27906
  optionValuePath="content.id"
27548
27907
  optionLabelPath="content.firstName"
27549
- selectionBinding="selectedPerson"}}
27908
+ selection=selectedPerson}}
27550
27909
  ```
27551
27910
 
27552
27911
  Would result in the following HTML with a selected option:
@@ -27559,11 +27918,11 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27559
27918
  ```
27560
27919
 
27561
27920
  Interacting with the rendered element by selecting the first option
27562
- ('Yehuda') will update the `selectedPerson` to match the object of
27921
+ ('Yehuda') will update the `selectedPerson` to match the object of
27563
27922
  the newly selected `<option>`. In this case it is the first object
27564
27923
  in the `programmers`
27565
27924
 
27566
- ### Supplying a Prompt
27925
+ ## Supplying a Prompt
27567
27926
 
27568
27927
  A `null` value for the `Ember.Select`'s `value` or `selection` property
27569
27928
  results in there being no `<option>` with a `selected` attribute:
@@ -27580,8 +27939,8 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27580
27939
 
27581
27940
  ``` handlebars
27582
27941
  {{view Ember.Select
27583
- contentBinding="programmers"
27584
- valueBinding="selectedProgrammer"
27942
+ content=programmers
27943
+ value=selectedProgrammer
27585
27944
  }}
27586
27945
  ```
27587
27946
 
@@ -27612,8 +27971,8 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27612
27971
 
27613
27972
  ```handlebars
27614
27973
  {{view Ember.Select
27615
- contentBinding="programmers"
27616
- valueBinding="selectedProgrammer"
27974
+ content=programmers
27975
+ value=selectedProgrammer
27617
27976
  prompt="Please select a name"
27618
27977
  }}
27619
27978
  ```
@@ -27665,11 +28024,11 @@ function program3(depth0,data) {
27665
28024
  function program4(depth0,data) {
27666
28025
 
27667
28026
  var hashContexts, hashTypes;
27668
- hashContexts = {'contentBinding': depth0,'labelBinding': depth0};
27669
- hashTypes = {'contentBinding': "ID",'labelBinding': "ID"};
28027
+ hashContexts = {'content': depth0,'label': depth0};
28028
+ hashTypes = {'content': "ID",'label': "ID"};
27670
28029
  data.buffer.push(escapeExpression(helpers.view.call(depth0, "view.groupView", {hash:{
27671
- 'contentBinding': ("content"),
27672
- 'labelBinding': ("label")
28030
+ 'content': ("content"),
28031
+ 'label': ("label")
27673
28032
  },contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
27674
28033
  }
27675
28034
 
@@ -27685,10 +28044,10 @@ function program6(depth0,data) {
27685
28044
  function program7(depth0,data) {
27686
28045
 
27687
28046
  var hashContexts, hashTypes;
27688
- hashContexts = {'contentBinding': depth0};
27689
- hashTypes = {'contentBinding': "STRING"};
28047
+ hashContexts = {'content': depth0};
28048
+ hashTypes = {'content': "ID"};
27690
28049
  data.buffer.push(escapeExpression(helpers.view.call(depth0, "view.optionView", {hash:{
27691
- 'contentBinding': ("this")
28050
+ 'content': ("")
27692
28051
  },contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
27693
28052
  }
27694
28053
 
@@ -27719,7 +28078,7 @@ function program7(depth0,data) {
27719
28078
  The `disabled` attribute of the select element. Indicates whether
27720
28079
  the element is disabled from interactions.
27721
28080
 
27722
- @property multiple
28081
+ @property disabled
27723
28082
  @type Boolean
27724
28083
  @default false
27725
28084
  */
@@ -27828,8 +28187,9 @@ function program7(depth0,data) {
27828
28187
  groupedContent: Ember.computed(function() {
27829
28188
  var groupPath = get(this, 'optionGroupPath');
27830
28189
  var groupedContent = Ember.A();
28190
+ var content = get(this, 'content') || [];
27831
28191
 
27832
- forEach(get(this, 'content'), function(item) {
28192
+ forEach(content, function(item) {
27833
28193
  var label = get(item, groupPath);
27834
28194
 
27835
28195
  if (get(groupedContent, 'lastObject.label') !== label) {
@@ -27981,18 +28341,9 @@ function program7(depth0,data) {
27981
28341
  (function() {
27982
28342
  /**
27983
28343
  @module ember
27984
- @submodule ember-handlebars
28344
+ @submodule ember-handlebars-compiler
27985
28345
  */
27986
28346
 
27987
- function normalizeHash(hash, hashTypes) {
27988
- for (var prop in hash) {
27989
- if (hashTypes[prop] === 'ID') {
27990
- hash[prop + 'Binding'] = hash[prop];
27991
- delete hash[prop];
27992
- }
27993
- }
27994
- }
27995
-
27996
28347
  /**
27997
28348
 
27998
28349
  The `{{input}}` helper inserts an HTML `<input>` tag into the template,
@@ -28004,30 +28355,32 @@ function normalizeHash(hash, hashTypes) {
28004
28355
  An `{{input}}` with no `type` or a `type` of `text` will render an HTML text input.
28005
28356
  The following HTML attributes can be set via the helper:
28006
28357
 
28007
- * `value`
28008
- * `size`
28009
- * `name`
28010
- * `pattern`
28011
- * `placeholder`
28012
- * `disabled`
28013
- * `maxlength`
28014
- * `tabindex`
28358
+ * `value`
28359
+ * `size`
28360
+ * `name`
28361
+ * `pattern`
28362
+ * `placeholder`
28363
+ * `disabled`
28364
+ * `maxlength`
28365
+ * `tabindex`
28366
+
28015
28367
 
28016
28368
  When set to a quoted string, these values will be directly applied to the HTML
28017
28369
  element. When left unquoted, these values will be bound to a property on the
28018
28370
  template's current rendering context (most typically a controller instance).
28019
28371
 
28020
- Unbound:
28372
+ ## Unbound:
28021
28373
 
28022
28374
  ```handlebars
28023
28375
  {{input value="http://www.facebook.com"}}
28024
28376
  ```
28025
28377
 
28378
+
28026
28379
  ```html
28027
28380
  <input type="text" value="http://www.facebook.com"/>
28028
28381
  ```
28029
28382
 
28030
- Bound:
28383
+ ## Bound:
28031
28384
 
28032
28385
  ```javascript
28033
28386
  App.ApplicationController = Ember.Controller.extend({
@@ -28036,15 +28389,18 @@ function normalizeHash(hash, hashTypes) {
28036
28389
  });
28037
28390
  ```
28038
28391
 
28392
+
28039
28393
  ```handlebars
28040
28394
  {{input type="text" value=firstName disabled=entryNotAllowed size="50"}}
28041
28395
  ```
28042
28396
 
28397
+
28043
28398
  ```html
28044
28399
  <input type="text" value="Stanley" disabled="disabled" size="50"/>
28045
28400
  ```
28046
28401
 
28047
- ### Extension
28402
+ ## Extension
28403
+
28048
28404
  Internally, `{{input type="text"}}` creates an instance of `Ember.TextField`, passing
28049
28405
  arguments from the helper to `Ember.TextField`'s `create` method. You can extend the
28050
28406
  capablilties of text inputs in your applications by reopening this class. For example,
@@ -28057,21 +28413,29 @@ function normalizeHash(hash, hashTypes) {
28057
28413
  });
28058
28414
  ```
28059
28415
 
28416
+ Keep in mind when writing `Ember.TextField` subclasses that `Ember.TextField`
28417
+ itself extends `Ember.Component`, meaning that it does NOT inherit
28418
+ the `controller` of the parent view.
28419
+
28420
+ See more about [Ember components](api/classes/Ember.Component.html)
28421
+
28422
+
28060
28423
  ## Use as checkbox
28424
+
28061
28425
  An `{{input}}` with a `type` of `checkbox` will render an HTML checkbox input.
28062
28426
  The following HTML attributes can be set via the helper:
28063
28427
 
28064
- * `checked`
28065
- * `disabled`
28066
- * `tabindex`
28067
- * `indeterminate`
28068
- * `name`
28428
+ * `checked`
28429
+ * `disabled`
28430
+ * `tabindex`
28431
+ * `indeterminate`
28432
+ * `name`
28069
28433
 
28070
28434
  When set to a quoted string, these values will be directly applied to the HTML
28071
28435
  element. When left unquoted, these values will be bound to a property on the
28072
28436
  template's current rendering context (most typically a controller instance).
28073
28437
 
28074
- Unbound:
28438
+ ## Unbound:
28075
28439
 
28076
28440
  ```handlebars
28077
28441
  {{input type="checkbox" name="isAdmin"}}
@@ -28081,7 +28445,7 @@ function normalizeHash(hash, hashTypes) {
28081
28445
  <input type="checkbox" name="isAdmin" />
28082
28446
  ```
28083
28447
 
28084
- Bound:
28448
+ ## Bound:
28085
28449
 
28086
28450
  ```javascript
28087
28451
  App.ApplicationController = Ember.Controller.extend({
@@ -28089,15 +28453,18 @@ function normalizeHash(hash, hashTypes) {
28089
28453
  });
28090
28454
  ```
28091
28455
 
28456
+
28092
28457
  ```handlebars
28093
28458
  {{input type="checkbox" checked=isAdmin }}
28094
28459
  ```
28095
28460
 
28461
+
28096
28462
  ```html
28097
28463
  <input type="checkbox" checked="checked" />
28098
28464
  ```
28099
28465
 
28100
- ### Extension
28466
+ ## Extension
28467
+
28101
28468
  Internally, `{{input type="checkbox"}}` creates an instance of `Ember.Checkbox`, passing
28102
28469
  arguments from the helper to `Ember.Checkbox`'s `create` method. You can extend the
28103
28470
  capablilties of checkbox inputs in your applications by reopening this class. For example,
@@ -28109,6 +28476,7 @@ function normalizeHash(hash, hashTypes) {
28109
28476
  });
28110
28477
  ```
28111
28478
 
28479
+
28112
28480
  @method input
28113
28481
  @for Ember.Handlebars.helpers
28114
28482
  @param {Hash} options
@@ -28124,8 +28492,6 @@ Ember.Handlebars.registerHelper('input', function(options) {
28124
28492
  delete hash.type;
28125
28493
  delete hash.on;
28126
28494
 
28127
- normalizeHash(hash, types);
28128
-
28129
28495
  if (inputType === 'checkbox') {
28130
28496
  return Ember.Handlebars.helpers.view.call(this, Ember.Checkbox, options);
28131
28497
  } else {
@@ -28255,7 +28621,7 @@ Ember.Handlebars.registerHelper('input', function(options) {
28255
28621
  </textarea>
28256
28622
  ```
28257
28623
 
28258
- ### Extension
28624
+ ## Extension
28259
28625
 
28260
28626
  Internally, `{{textarea}}` creates an instance of `Ember.TextArea`, passing
28261
28627
  arguments from the helper to `Ember.TextArea`'s `create` method. You can
@@ -28272,6 +28638,12 @@ Ember.Handlebars.registerHelper('input', function(options) {
28272
28638
  });
28273
28639
  ```
28274
28640
 
28641
+ Keep in mind when writing `Ember.TextArea` subclasses that `Ember.TextArea`
28642
+ itself extends `Ember.Component`, meaning that it does NOT inherit
28643
+ the `controller` of the parent view.
28644
+
28645
+ See more about [Ember components](api/classes/Ember.Component.html)
28646
+
28275
28647
  @method textarea
28276
28648
  @for Ember.Handlebars.helpers
28277
28649
  @param {Hash} options
@@ -28282,7 +28654,6 @@ Ember.Handlebars.registerHelper('textarea', function(options) {
28282
28654
  var hash = options.hash,
28283
28655
  types = options.hashTypes;
28284
28656
 
28285
- normalizeHash(hash, types);
28286
28657
  return Ember.Handlebars.helpers.view.call(this, Ember.TextArea, options);
28287
28658
  });
28288
28659
 
@@ -28333,7 +28704,7 @@ Ember.Handlebars.bootstrap = function(ctx) {
28333
28704
 
28334
28705
  // Check if template of same name already exists
28335
28706
  if (Ember.TEMPLATES[templateName] !== undefined) {
28336
- throw new Error('Template named "' + templateName + '" already exists.');
28707
+ throw new Ember.Error('Template named "' + templateName + '" already exists.');
28337
28708
  }
28338
28709
 
28339
28710
  // For templates which have a name, we save them and then remove them from the DOM
@@ -28363,13 +28734,14 @@ function registerComponents(container) {
28363
28734
  function registerComponent(container, name) {
28364
28735
  Ember.assert("You provided a template named 'components/" + name + "', but custom components must include a '-'", name.match(/-/));
28365
28736
 
28366
- container.injection('component:' + name, 'layout', 'template:components/' + name);
28367
-
28368
28737
  var fullName = 'component:' + name;
28738
+
28739
+ container.injection(fullName, 'layout', 'template:components/' + name);
28740
+
28369
28741
  var Component = container.lookupFactory(fullName);
28370
28742
 
28371
28743
  if (!Component) {
28372
- container.register('component:' + name, Ember.Component);
28744
+ container.register(fullName, Ember.Component);
28373
28745
  Component = container.lookupFactory(fullName);
28374
28746
  }
28375
28747
 
@@ -30385,8 +30757,12 @@ Ember.Router = Ember.Object.extend({
30385
30757
 
30386
30758
  if (name === 'application') {
30387
30759
  // Inject default `error` handler.
30388
- handler.events = handler.events || {};
30389
- handler.events.error = handler.events.error || Ember.Router._defaultErrorHandler;
30760
+ // Note: `events` is deprecated, but we'll let the
30761
+ // deprecation warnings be handled at event-handling time rather
30762
+ // than duplicating that logic here.
30763
+ var actions = handler._actions || handler.events;
30764
+ if (!actions) { actions = handler._actions = {}; }
30765
+ actions.error = actions.error || Ember.Router._defaultErrorHandler;
30390
30766
  }
30391
30767
 
30392
30768
  handler.routeName = name;
@@ -30453,8 +30829,10 @@ Ember.Router = Ember.Object.extend({
30453
30829
 
30454
30830
  transitionPromise.then(function(route) {
30455
30831
  self._transitionCompleted(route);
30456
- }, function(error){
30457
- Ember.assert("The URL '" + error.message + "' did match any routes in your application", error.name !== "UnrecognizedURLError");
30832
+ }, function(error) {
30833
+ if (error.name === "UnrecognizedURLError") {
30834
+ Ember.assert("The URL '" + error.message + "' did not match any routes in your application");
30835
+ }
30458
30836
  });
30459
30837
 
30460
30838
  // We want to return the configurable promise object
@@ -30500,7 +30878,7 @@ function triggerEvent(handlerInfos, ignoreFailure, args) {
30500
30878
 
30501
30879
  if (!handlerInfos) {
30502
30880
  if (ignoreFailure) { return; }
30503
- throw new Error("Could not trigger event '" + name + "'. There are no active handlers");
30881
+ throw new Ember.Error("Could not trigger event '" + name + "'. There are no active handlers");
30504
30882
  }
30505
30883
 
30506
30884
  var eventWasHandled = false;
@@ -30526,7 +30904,7 @@ function triggerEvent(handlerInfos, ignoreFailure, args) {
30526
30904
  }
30527
30905
 
30528
30906
  if (!eventWasHandled && !ignoreFailure) {
30529
- throw new Error("Nothing handled the event '" + name + "'.");
30907
+ throw new Ember.Error("Nothing handled the event '" + name + "'.");
30530
30908
  }
30531
30909
  }
30532
30910
 
@@ -30845,6 +31223,7 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
30845
31223
  @deprecated
30846
31224
 
30847
31225
  Please use `actions` instead.
31226
+ @method events
30848
31227
  */
30849
31228
  events: null,
30850
31229
 
@@ -30867,11 +31246,13 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
30867
31246
  activate: Ember.K,
30868
31247
 
30869
31248
  /**
30870
- Transition into another route. Optionally supply a model for the
30871
- route in question. The model will be serialized into the URL
30872
- using the `serialize` hook.
31249
+ Transition into another route. Optionally supply model(s) for the
31250
+ route in question. If multiple models are supplied they will be applied
31251
+ last to first recursively up the resource tree (see Multiple Models Example
31252
+ below). The model(s) will be serialized into the URL using the appropriate
31253
+ route's `serialize` hook. See also 'replaceWith'.
30873
31254
 
30874
- Example
31255
+ Simple Transition Example
30875
31256
 
30876
31257
  ```javascript
30877
31258
  App.Router.map(function() {
@@ -30892,9 +31273,31 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
30892
31273
  });
30893
31274
  ```
30894
31275
 
31276
+ Multiple Models Example
31277
+
31278
+ ```javascript
31279
+ App.Router.map(function() {
31280
+ this.route("index");
31281
+ this.resource('breakfast', {path:':breakfastId'}, function(){
31282
+ this.resource('cereal', {path: ':cerealId'});
31283
+ });
31284
+ });
31285
+
31286
+ App.IndexRoute = Ember.Route.extend({
31287
+ actions: {
31288
+ moveToChocolateCereal: function(){
31289
+ var cereal = { cerealId: "ChocolateYumminess"},
31290
+ breakfast = {breakfastId: "CerealAndMilk"};
31291
+
31292
+ this.transitionTo('cereal', breakfast, cereal);
31293
+ }
31294
+ }
31295
+ });
31296
+
30895
31297
  @method transitionTo
30896
31298
  @param {String} name the name of the route
30897
- @param {...Object} models
31299
+ @param {...Object} models the model(s) to be used while transitioning
31300
+ to the route.
30898
31301
  */
30899
31302
  transitionTo: function(name, context) {
30900
31303
  var router = this.router;
@@ -30902,8 +31305,10 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
30902
31305
  },
30903
31306
 
30904
31307
  /**
30905
- Transition into another route while replacing the current URL if
30906
- possible. Identical to `transitionTo` in all other respects.
31308
+ Transition into another route while replacing the current URL, if possible.
31309
+ This will replace the current history entry instead of adding a new one.
31310
+ Beside that, it is identical to `transitionTo` in all other respects. See
31311
+ 'transitionTo' for additional information regarding multiple models.
30907
31312
 
30908
31313
  Example
30909
31314
 
@@ -30924,7 +31329,8 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
30924
31329
 
30925
31330
  @method replaceWith
30926
31331
  @param {String} name the name of the route
30927
- @param {...Object} models
31332
+ @param {...Object} models the model(s) to be used while transitioning
31333
+ to the route.
30928
31334
  */
30929
31335
  replaceWith: function() {
30930
31336
  var router = this.router;
@@ -31003,15 +31409,15 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
31003
31409
  },
31004
31410
 
31005
31411
  /**
31006
- @deprecated
31007
-
31008
31412
  A hook you can implement to optionally redirect to another route.
31009
31413
 
31010
31414
  If you call `this.transitionTo` from inside of this hook, this route
31011
31415
  will not be entered in favor of the other hook.
31012
31416
 
31013
- This hook is deprecated in favor of using the `afterModel` hook
31014
- for performing redirects after the model has resolved.
31417
+ Note that this hook is called by the default implementation of
31418
+ `afterModel`, so if you override `afterModel`, you must either
31419
+ explicitly call `redirect` or just put your redirecting
31420
+ `this.transitionTo()` call within `afterModel`.
31015
31421
 
31016
31422
  @method redirect
31017
31423
  @param {Object} model the model for this route
@@ -31105,7 +31511,7 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
31105
31511
  resolved.
31106
31512
 
31107
31513
  ```js
31108
- App.PostRoute = Ember.Route.extend({
31514
+ App.PostsRoute = Ember.Route.extend({
31109
31515
  afterModel: function(posts, transition) {
31110
31516
  if (posts.length === 1) {
31111
31517
  this.transitionTo('post.show', posts[0]);
@@ -32023,6 +32429,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32023
32429
 
32024
32430
  This method is invoked by observers installed during `init` that fire
32025
32431
  whenever the helpers
32432
+ @method _paramsChanged
32026
32433
  */
32027
32434
  _paramsChanged: function() {
32028
32435
  this.notifyPropertyChange('resolvedParams');
@@ -32196,7 +32603,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32196
32603
  @property href
32197
32604
  **/
32198
32605
  href: Ember.computed(function() {
32199
- if (get(this, 'tagName') !== 'a') { return false; }
32606
+ if (get(this, 'tagName') !== 'a') { return; }
32200
32607
 
32201
32608
  var router = get(this, 'router'),
32202
32609
  routeArgs = get(this, 'routeArgs');
@@ -32255,7 +32662,44 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32255
32662
 
32256
32663
  To override this option for your entire application, see
32257
32664
  "Overriding Application-wide Defaults".
32258
-
32665
+
32666
+ ### Disabling the `link-to` helper
32667
+ By default `{{link-to}}` is enabled.
32668
+ any passed value to `disabled` helper property will disable the `link-to` helper.
32669
+
32670
+ static use: the `disabled` option:
32671
+
32672
+ ```handlebars
32673
+ {{#link-to 'photoGallery' disabled=true}}
32674
+ Great Hamster Photos
32675
+ {{/link-to}}
32676
+ ```
32677
+
32678
+ dynamic use: the `disabledWhen` option:
32679
+
32680
+ ```handlebars
32681
+ {{#link-to 'photoGallery' disabledWhen=controller.someProperty}}
32682
+ Great Hamster Photos
32683
+ {{/link-to}}
32684
+ ```
32685
+
32686
+ any passed value to `disabled` will disable it except `undefined`.
32687
+ to ensure that only `true` disable the `link-to` helper you can
32688
+ override the global behaviour of `Ember.LinkView`.
32689
+
32690
+ ```javascript
32691
+ Ember.LinkView.reopen({
32692
+ disabled: Ember.computed(function(key, value) {
32693
+ if (value !== undefined) {
32694
+ this.set('_isDisabled', value === true);
32695
+ }
32696
+ return value === true ? get(this, 'disabledClass') : false;
32697
+ })
32698
+ });
32699
+ ```
32700
+
32701
+ see "Overriding Application-wide Defaults" for more.
32702
+
32259
32703
  ### Handling `href`
32260
32704
  `{{link-to}}` will use your application's Router to
32261
32705
  fill the element's `href` property with a url that
@@ -32311,7 +32755,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32311
32755
  ```javascript
32312
32756
  App.Router.map(function() {
32313
32757
  this.resource("photoGallery", {path: "hamster-photos/:photo_id"});
32314
- })
32758
+ });
32315
32759
  ```
32316
32760
 
32317
32761
  ```handlebars
@@ -32353,6 +32797,34 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32353
32797
  A+++ would snuggle again.
32354
32798
  </a>
32355
32799
  ```
32800
+
32801
+ ### Supplying an explicit dynamic segment value
32802
+ If you don't have a model object available to pass to `{{link-to}}`,
32803
+ an optional string or integer argument can be passed for routes whose
32804
+ paths contain dynamic segments. This argument will become the value
32805
+ of the dynamic segment:
32806
+
32807
+ ```javascript
32808
+ App.Router.map(function() {
32809
+ this.resource("photoGallery", {path: "hamster-photos/:photo_id"});
32810
+ });
32811
+ ```
32812
+
32813
+ ```handlebars
32814
+ {{#link-to 'photoGallery' aPhotoId}}
32815
+ {{aPhoto.title}}
32816
+ {{/link-to}}
32817
+ ```
32818
+
32819
+ ```html
32820
+ <a href="/hamster-photos/42">
32821
+ Tomster
32822
+ </a>
32823
+ ```
32824
+
32825
+ When transitioning into the linked route, the `model` hook will
32826
+ be triggered with parameters including this passed identifier.
32827
+
32356
32828
  ### Overriding attributes
32357
32829
  You can override any given property of the Ember.LinkView
32358
32830
  that is generated by the `{{link-to}}` helper by passing
@@ -32362,8 +32834,9 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32362
32834
  {{#link-to aPhoto tagName='li' title='Following this link will change your life' classNames=['pic', 'sweet']}}
32363
32835
  Uh-mazing!
32364
32836
  {{/link-to}}
32837
+ ```
32365
32838
 
32366
- See {{#crossLink "Ember.LinkView"}}{{/crossLink}} for a
32839
+ See [Ember.LinkView](/api/classes/Ember.LinkView.html) for a
32367
32840
  complete list of overrideable properties. Be sure to also
32368
32841
  check out inherited properties of `LinkView`.
32369
32842
 
@@ -32393,7 +32866,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32393
32866
  @for Ember.Handlebars.helpers
32394
32867
  @param {String} routeName
32395
32868
  @param {Object} [context]*
32396
- @param [options] {Object} Handlebars key/value pairs of options, you can over-ride any property of {{#crossLink "Ember.LinkView"}}{{/crossLink}}
32869
+ @param [options] {Object} Handlebars key/value pairs of options, you can override any property of Ember.LinkView
32397
32870
  @return {String} HTML string
32398
32871
  @see {Ember.LinkView}
32399
32872
  */
@@ -32414,7 +32887,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32414
32887
  });
32415
32888
 
32416
32889
  /**
32417
- See `link-to`
32890
+ See [link-to](/api/classes/Ember.Handlebars.helpers.html#method_link-to)
32418
32891
 
32419
32892
  @method linkTo
32420
32893
  @for Ember.Handlebars.helpers
@@ -32559,7 +33032,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32559
33032
  Example:
32560
33033
 
32561
33034
  ```javascript
32562
- App.NavigationController = Ember.Controller.extned({
33035
+ App.NavigationController = Ember.Controller.extend({
32563
33036
  who: "world"
32564
33037
  });
32565
33038
  ```
@@ -32718,6 +33191,10 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32718
33191
  return isSimpleClick(event);
32719
33192
  }
32720
33193
 
33194
+ if (allowedKeys.indexOf("any") >= 0) {
33195
+ return true;
33196
+ }
33197
+
32721
33198
  var allowed = true;
32722
33199
 
32723
33200
  forEach.call(keys, function(key) {
@@ -32771,16 +33248,16 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32771
33248
 
32772
33249
  /**
32773
33250
  The `{{action}}` helper registers an HTML element within a template for DOM
32774
- event handling and forwards that interaction to the view's controller
33251
+ event handling and forwards that interaction to the templates's controller
32775
33252
  or supplied `target` option (see 'Specifying a Target').
32776
33253
 
32777
- If the view's controller does not implement the event, the event is sent
33254
+ If the controller does not implement the event, the event is sent
32778
33255
  to the current route, and it bubbles up the route hierarchy from there.
32779
33256
 
32780
33257
  User interaction with that element will invoke the supplied action name on
32781
33258
  the appropriate target.
32782
33259
 
32783
- Given the following Handlebars template on the page
33260
+ Given the following application Handlebars template on the page
32784
33261
 
32785
33262
  ```handlebars
32786
33263
  <div {{action 'anActionName'}}>
@@ -32791,17 +33268,13 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32791
33268
  And application code
32792
33269
 
32793
33270
  ```javascript
32794
- AController = Ember.Controller.extend({
32795
- anActionName: function() {}
32796
- });
32797
-
32798
- AView = Ember.View.extend({
32799
- controller: AController.create(),
32800
- templateName: 'a-template'
33271
+ App.ApplicationController = Ember.Controller.extend({
33272
+ actions: {
33273
+ anActionName: function() {
33274
+
33275
+ }
33276
+ }
32801
33277
  });
32802
-
32803
- aView = AView.create();
32804
- aView.appendTo('body');
32805
33278
  ```
32806
33279
 
32807
33280
  Will result in the following rendered HTML
@@ -32814,8 +33287,8 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32814
33287
  </div>
32815
33288
  ```
32816
33289
 
32817
- Clicking "click me" will trigger the `anActionName` method of the
32818
- `AController`. In this case, no additional parameters will be passed.
33290
+ Clicking "click me" will trigger the `anActionName` action of the
33291
+ `App.ApplicationController`. In this case, no additional parameters will be passed.
32819
33292
 
32820
33293
  If you provide additional parameters to the helper:
32821
33294
 
@@ -32848,11 +33321,9 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32848
33321
  supply an `on` option to the helper to specify a different DOM event name:
32849
33322
 
32850
33323
  ```handlebars
32851
- <script type="text/x-handlebars" data-template-name='a-template'>
32852
- <div {{action 'anActionName' on="doubleClick"}}>
32853
- click me
32854
- </div>
32855
- </script>
33324
+ <div {{action "anActionName" on="doubleClick"}}>
33325
+ click me
33326
+ </div>
32856
33327
  ```
32857
33328
 
32858
33329
  See `Ember.View` 'Responding to Browser Events' for a list of
@@ -32870,15 +33341,21 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32870
33341
  keys. You can supply an `allowedKeys` option to specify which keys should not be ignored.
32871
33342
 
32872
33343
  ```handlebars
32873
- <script type="text/x-handlebars" data-template-name='a-template'>
32874
- <div {{action 'anActionName' allowedKeys="alt"}}>
32875
- click me
32876
- </div>
32877
- </script>
33344
+ <div {{action "anActionName" allowedKeys="alt"}}>
33345
+ click me
33346
+ </div>
32878
33347
  ```
32879
33348
 
32880
33349
  This way the `{{action}}` will fire when clicking with the alt key pressed down.
32881
33350
 
33351
+ Alternatively, supply "any" to the `allowedKeys` option to accept any combination of modifier keys.
33352
+
33353
+ ```handlebars
33354
+ <div {{action "anActionName" allowedKeys="any"}}>
33355
+ click me with any key pressed
33356
+ </div>
33357
+ ```
33358
+
32882
33359
  ### Specifying a Target
32883
33360
 
32884
33361
  There are several possible target objects for `{{action}}` helpers:
@@ -32892,43 +33369,21 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32892
33369
  to an object, accessible in the current context:
32893
33370
 
32894
33371
  ```handlebars
32895
- <script type="text/x-handlebars" data-template-name='a-template'>
32896
- <div {{action 'anActionName' target="MyApplication.someObject"}}>
32897
- click me
32898
- </div>
32899
- </script>
32900
- ```
32901
-
32902
- Clicking "click me" in the rendered HTML of the above template will trigger
32903
- the `anActionName` method of the object at `MyApplication.someObject`.
32904
-
32905
- If an action's target does not implement a method that matches the supplied
32906
- action name an error will be thrown.
32907
-
32908
- ```handlebars
32909
- <script type="text/x-handlebars" data-template-name='a-template'>
32910
- <div {{action 'aMethodNameThatIsMissing'}}>
32911
- click me
32912
- </div>
32913
- </script>
33372
+ {{! the application template }}
33373
+ <div {{action "anActionName" target=view}}>
33374
+ click me
33375
+ </div>
32914
33376
  ```
32915
33377
 
32916
- With the following application code
32917
-
32918
33378
  ```javascript
32919
- AView = Ember.View.extend({
32920
- templateName; 'a-template',
32921
- // note: no method 'aMethodNameThatIsMissing'
32922
- anActionName: function(event) {}
33379
+ App.ApplicationView = Ember.View.extend({
33380
+ actions: {
33381
+ anActionName: function(){}
33382
+ }
32923
33383
  });
32924
33384
 
32925
- aView = AView.create();
32926
- aView.appendTo('body');
32927
33385
  ```
32928
33386
 
32929
- Will throw `Uncaught TypeError: Cannot call method 'call' of undefined` when
32930
- "click me" is clicked.
32931
-
32932
33387
  ### Additional Parameters
32933
33388
 
32934
33389
  You may specify additional parameters to the `{{action}}` helper. These
@@ -32936,17 +33391,15 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32936
33391
  implementing the action.
32937
33392
 
32938
33393
  ```handlebars
32939
- <script type="text/x-handlebars" data-template-name='a-template'>
32940
- {{#each person in people}}
32941
- <div {{action 'edit' person}}>
32942
- click me
32943
- </div>
32944
- {{/each}}
32945
- </script>
33394
+ {{#each person in people}}
33395
+ <div {{action "edit" person}}>
33396
+ click me
33397
+ </div>
33398
+ {{/each}}
32946
33399
  ```
32947
33400
 
32948
- Clicking "click me" will trigger the `edit` method on the current view's
32949
- controller with the current person as a parameter.
33401
+ Clicking "click me" will trigger the `edit` method on the current controller
33402
+ with the value of `person` as a parameter.
32950
33403
 
32951
33404
  @method action
32952
33405
  @for Ember.Handlebars.helpers
@@ -33131,8 +33584,23 @@ Ember.ControllerMixin.reopen({
33131
33584
  aController.transitionToRoute('blogPost', aPost);
33132
33585
  ```
33133
33586
 
33587
+ Multiple models will be applied last to first recursively up the
33588
+ resource tree.
33589
+
33590
+ ```javascript
33591
+
33592
+ this.resource('blogPost', {path:':blogPostId'}, function(){
33593
+ this.resource('blogComment', {path: ':blogCommentId'});
33594
+ });
33595
+
33596
+ aController.transitionToRoute('blogComment', aPost, aComment);
33597
+ ```
33598
+
33599
+ See also 'replaceRoute'.
33600
+
33134
33601
  @param {String} name the name of the route
33135
- @param {...Object} models the
33602
+ @param {...Object} models the model(s) to be used while transitioning
33603
+ to the route.
33136
33604
  @for Ember.ControllerMixin
33137
33605
  @method transitionToRoute
33138
33606
  */
@@ -33154,8 +33622,9 @@ Ember.ControllerMixin.reopen({
33154
33622
  },
33155
33623
 
33156
33624
  /**
33157
- Alernative to `transitionToRoute`. Transition the application into another route. The route may
33158
- be either a single route or route path:
33625
+ Transition into another route while replacing the current URL, if possible.
33626
+ This will replace the current history entry instead of adding a new one.
33627
+ Beside that, it is identical to `transitionToRoute` in all other respects.
33159
33628
 
33160
33629
  ```javascript
33161
33630
  aController.replaceRoute('blogPosts');
@@ -33170,8 +33639,21 @@ Ember.ControllerMixin.reopen({
33170
33639
  aController.replaceRoute('blogPost', aPost);
33171
33640
  ```
33172
33641
 
33642
+ Multiple models will be applied last to first recursively up the
33643
+ resource tree.
33644
+
33645
+ ```javascript
33646
+
33647
+ this.resource('blogPost', {path:':blogPostId'}, function(){
33648
+ this.resource('blogComment', {path: ':blogCommentId'});
33649
+ });
33650
+
33651
+ aController.replaceRoute('blogComment', aPost, aComment);
33652
+ ```
33653
+
33173
33654
  @param {String} name the name of the route
33174
- @param {...Object} models the
33655
+ @param {...Object} models the model(s) to be used while transitioning
33656
+ to the route.
33175
33657
  @for Ember.ControllerMixin
33176
33658
  @method replaceRoute
33177
33659
  */
@@ -33974,7 +34456,7 @@ DAG.prototype.addEdge = function(fromName, toName) {
33974
34456
  }
33975
34457
  function checkCycle(vertex, path) {
33976
34458
  if (vertex.name === toName) {
33977
- throw new Error("cycle detected: " + toName + " <- " + path.join(" <- "));
34459
+ throw new Ember.Error("cycle detected: " + toName + " <- " + path.join(" <- "));
33978
34460
  }
33979
34461
  }
33980
34462
  visit(from, checkCycle);
@@ -34042,11 +34524,11 @@ var get = Ember.get,
34042
34524
  container lookups before consulting the container for registered
34043
34525
  items:
34044
34526
 
34045
- * templates are looked up on `Ember.TEMPLATES`
34046
- * other names are looked up on the application after converting
34047
- the name. For example, `controller:post` looks up
34048
- `App.PostController` by default.
34049
- * there are some nuances (see examples below)
34527
+ * templates are looked up on `Ember.TEMPLATES`
34528
+ * other names are looked up on the application after converting
34529
+ the name. For example, `controller:post` looks up
34530
+ `App.PostController` by default.
34531
+ * there are some nuances (see examples below)
34050
34532
 
34051
34533
  ### How Resolving Works
34052
34534
 
@@ -34415,16 +34897,15 @@ DeprecatedContainer.prototype = {
34415
34897
  example, the `keypress` event causes the `keyPress` method on the view to be
34416
34898
  called, the `dblclick` event causes `doubleClick` to be called, and so on.
34417
34899
 
34418
- If there is a browser event that Ember does not listen for by default, you
34419
- can specify custom events and their corresponding view method names by
34420
- setting the application's `customEvents` property:
34900
+ If there is a bubbling browser event that Ember does not listen for by
34901
+ default, you can specify custom events and their corresponding view method
34902
+ names by setting the application's `customEvents` property:
34421
34903
 
34422
34904
  ```javascript
34423
34905
  App = Ember.Application.create({
34424
34906
  customEvents: {
34425
- // add support for the loadedmetadata media
34426
- // player event
34427
- 'loadedmetadata': "loadedMetadata"
34907
+ // add support for the paste event
34908
+ 'paste: "paste"
34428
34909
  }
34429
34910
  });
34430
34911
  ```
@@ -34537,7 +35018,7 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
34537
35018
  `keyup`, and delegates them to your application's `Ember.View`
34538
35019
  instances.
34539
35020
 
34540
- If you would like additional events to be delegated to your
35021
+ If you would like additional bubbling events to be delegated to your
34541
35022
  views, set your `Ember.Application`'s `customEvents` property
34542
35023
  to a hash containing the DOM event name as the key and the
34543
35024
  corresponding view method name as the value. For example:
@@ -34545,9 +35026,8 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
34545
35026
  ```javascript
34546
35027
  App = Ember.Application.create({
34547
35028
  customEvents: {
34548
- // add support for the loadedmetadata media
34549
- // player event
34550
- 'loadedmetadata': "loadedMetadata"
35029
+ // add support for the paste event
35030
+ 'paste: "paste"
34551
35031
  }
34552
35032
  });
34553
35033
  ```
@@ -34573,12 +35053,18 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
34573
35053
 
34574
35054
  this.scheduleInitialize();
34575
35055
 
34576
- if (Ember.LOG_VERSION) {
35056
+ Ember.libraries.registerCoreLibrary('Handlebars', Ember.Handlebars.VERSION);
35057
+ Ember.libraries.registerCoreLibrary('jQuery', Ember.$().jquery);
35058
+
35059
+ if ( Ember.LOG_VERSION ) {
34577
35060
  Ember.LOG_VERSION = false; // we only need to see this once per Application#init
35061
+ var maxNameLength = Math.max.apply(this, Ember.A(Ember.libraries).mapBy("name.length"));
35062
+
34578
35063
  Ember.debug('-------------------------------');
34579
- Ember.debug('Ember.VERSION : ' + Ember.VERSION);
34580
- Ember.debug('Handlebars.VERSION : ' + Ember.Handlebars.VERSION);
34581
- Ember.debug('jQuery.VERSION : ' + Ember.$().jquery);
35064
+ Ember.libraries.each(function(name, version) {
35065
+ var spaces = new Array(maxNameLength - name.length + 1).join(" ");
35066
+ Ember.debug([name, spaces, ' : ', version].join(""));
35067
+ });
34582
35068
  Ember.debug('-------------------------------');
34583
35069
  }
34584
35070
  },
@@ -34712,19 +35198,20 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
34712
35198
  ```javascript
34713
35199
  App = Ember.Application.create();
34714
35200
 
34715
- App.Person = Ember.Object.extend({});
34716
- App.Orange = Ember.Object.extend({});
34717
- App.Email = Ember.Object.extend({});
35201
+ App.Person = Ember.Object.extend({});
35202
+ App.Orange = Ember.Object.extend({});
35203
+ App.Email = Ember.Object.extend({});
35204
+ App.Session = Ember.Object.create({});
34718
35205
 
34719
35206
  App.register('model:user', App.Person, {singleton: false });
34720
35207
  App.register('fruit:favorite', App.Orange);
34721
35208
  App.register('communication:main', App.Email, {singleton: false});
35209
+ App.register('session', App.Session, {instantiate: false});
34722
35210
  ```
34723
35211
 
34724
35212
  @method register
34725
- @param type {String}
34726
- @param name {String}
34727
- @param factory {String}
35213
+ @param fullName {String} type:name (e.g., 'model:user')
35214
+ @param factory {Function} (e.g., App.Person)
34728
35215
  @param options {String} (optional)
34729
35216
  **/
34730
35217
  register: function() {
@@ -34781,7 +35268,9 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
34781
35268
  if (this.isDestroyed) { return; }
34782
35269
 
34783
35270
  // At this point, the App.Router must already be assigned
34784
- this.register('router:main', this.Router);
35271
+ if (this.Router) {
35272
+ this.register('router:main', this.Router);
35273
+ }
34785
35274
 
34786
35275
  this.runInitializers();
34787
35276
  Ember.runLoadHooks('application', this);
@@ -34891,10 +35380,10 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
34891
35380
  container = this.__container__,
34892
35381
  graph = new Ember.DAG(),
34893
35382
  namespace = this,
34894
- i, initializer;
35383
+ name, initializer;
34895
35384
 
34896
- for (i=0; i<initializers.length; i++) {
34897
- initializer = initializers[i];
35385
+ for (name in initializers) {
35386
+ initializer = initializers[name];
34898
35387
  graph.addEdges(initializer.name, initializer.initialize, initializer.before, initializer.after);
34899
35388
  }
34900
35389
 
@@ -34944,8 +35433,8 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
34944
35433
  /**
34945
35434
  @private
34946
35435
 
34947
- If the application has a router, use it to route to the current URL, and
34948
35436
  trigger a new call to `route` whenever the URL changes.
35437
+ If the application has a router, use it to route to the current URL, and
34949
35438
 
34950
35439
  @method startRouting
34951
35440
  @property router {Ember.Router}
@@ -34972,10 +35461,10 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
34972
35461
  ready: Ember.K,
34973
35462
 
34974
35463
  /**
34975
-
34976
35464
  @deprecated Use 'Resolver' instead
34977
35465
  Set this to provide an alternate class to `Ember.DefaultResolver`
34978
35466
 
35467
+
34979
35468
  @property resolver
34980
35469
  */
34981
35470
  resolver: null,
@@ -34999,16 +35488,23 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
34999
35488
  });
35000
35489
 
35001
35490
  Ember.Application.reopenClass({
35002
- concatenatedProperties: ['initializers'],
35003
- initializers: Ember.A(),
35491
+ initializers: {},
35004
35492
  initializer: function(initializer) {
35005
- var initializers = get(this, 'initializers');
35493
+ // If this is the first initializer being added to a subclass, we are going to reopen the class
35494
+ // to make sure we have a new `initializers` object, which extends from the parent class' using
35495
+ // prototypal inheritance. Without this, attempting to add initializers to the subclass would
35496
+ // pollute the parent class as well as other subclasses.
35497
+ if (this.superclass.initializers !== undefined && this.superclass.initializers === this.initializers) {
35498
+ this.reopenClass({
35499
+ initializers: Ember.create(this.initializers)
35500
+ });
35501
+ }
35006
35502
 
35007
- Ember.assert("The initializer '" + initializer.name + "' has already been registered", !initializers.findBy('name', initializers.name));
35008
- Ember.assert("An injection cannot be registered with both a before and an after", !(initializer.before && initializer.after));
35009
- Ember.assert("An injection cannot be registered without an injection function", Ember.canInvoke(initializer, 'initialize'));
35503
+ Ember.assert("The initializer '" + initializer.name + "' has already been registered", !this.initializers[initializer.name]);
35504
+ Ember.assert("An initializer cannot be registered with both a before and an after", !(initializer.before && initializer.after));
35505
+ Ember.assert("An initializer cannot be registered without an initialize function", Ember.canInvoke(initializer, 'initialize'));
35010
35506
 
35011
- initializers.push(initializer);
35507
+ this.initializers[initializer.name] = initializer;
35012
35508
  },
35013
35509
 
35014
35510
  /**
@@ -35089,7 +35585,7 @@ Ember.Application.reopenClass({
35089
35585
  */
35090
35586
  function resolverFor(namespace) {
35091
35587
  if (namespace.get('resolver')) {
35092
- Ember.deprecate('Application.resolver is deprecated infavour of Application.Resolver', false);
35588
+ Ember.deprecate('Application.resolver is deprecated in favor of Application.Resolver', false);
35093
35589
  }
35094
35590
 
35095
35591
  var ResolverClass = namespace.get('resolver') || namespace.get('Resolver') || Ember.DefaultResolver;
@@ -35197,6 +35693,8 @@ Ember.ControllerMixin.reopen({
35197
35693
  length = get(needs, 'length');
35198
35694
 
35199
35695
  if (length > 0) {
35696
+ Ember.assert(' `' + Ember.inspect(this) + ' specifies `needs`, but does not have a container. Please ensure this controller was instantiated with a container.', this.container);
35697
+
35200
35698
  verifyNeedsDependencies(this, this.container, needs);
35201
35699
 
35202
35700
  // if needs then initialize controllers proxy
@@ -35206,6 +35704,11 @@ Ember.ControllerMixin.reopen({
35206
35704
  this._super.apply(this, arguments);
35207
35705
  },
35208
35706
 
35707
+ /**
35708
+ @method controllerFor
35709
+ @see {Ember.Route#controllerFor}
35710
+ @deprecated Use `needs` instead
35711
+ */
35209
35712
  controllerFor: function(controllerName) {
35210
35713
  Ember.deprecate("Controller#controllerFor is deprecated, please use Controller#needs instead");
35211
35714
  return Ember.controllerFor(get(this, 'container'), controllerName);
@@ -36136,6 +36639,7 @@ Test.onInjectHelpers(function() {
36136
36639
  });
36137
36640
 
36138
36641
  Ember.$(document).ajaxStop(function() {
36642
+ Ember.assert("An ajaxStop event which would cause the number of pending AJAX requests to be negative has been triggered. This is most likely caused by AJAX events that were started before calling `injectTestHelpers()`.", Test.pendingAjaxRequests !== 0);
36139
36643
  Test.pendingAjaxRequests--;
36140
36644
  });
36141
36645
  });
@@ -36154,7 +36658,16 @@ function click(app, selector, context) {
36154
36658
  if ($el.is(':input')) {
36155
36659
  var type = $el.prop('type');
36156
36660
  if (type !== 'checkbox' && type !== 'radio' && type !== 'hidden') {
36157
- Ember.run($el, 'focus');
36661
+ Ember.run($el, function(){
36662
+ // Firefox does not trigger the `focusin` event if the window
36663
+ // does not have focus. If the document doesn't have focus just
36664
+ // use trigger('focusin') instead.
36665
+ if (!document.hasFocus || document.hasFocus()) {
36666
+ this.focus();
36667
+ } else {
36668
+ this.trigger('focusin');
36669
+ }
36670
+ });
36158
36671
  }
36159
36672
  }
36160
36673
 
@@ -36193,7 +36706,7 @@ function fillIn(app, selector, context, text) {
36193
36706
  function findWithAssert(app, selector, context) {
36194
36707
  var $el = find(app, selector, context);
36195
36708
  if ($el.length === 0) {
36196
- throw new Error("Element " + selector + " not found.");
36709
+ throw new Ember.Error("Element " + selector + " not found.");
36197
36710
  }
36198
36711
  return $el;
36199
36712
  }
@@ -36305,7 +36818,7 @@ function chain(app, promise, fn) {
36305
36818
  *
36306
36819
  * @method visit
36307
36820
  * @param {String} url the name of the route
36308
- * @returns {RSVP.Promise}
36821
+ * @return {RSVP.Promise}
36309
36822
  */
36310
36823
  helper('visit', visit);
36311
36824
 
@@ -36323,7 +36836,7 @@ helper('visit', visit);
36323
36836
  *
36324
36837
  * @method click
36325
36838
  * @param {String} selector jQuery selector for finding element on the DOM
36326
- * @returns {RSVP.Promise}
36839
+ * @return {RSVP.Promise}
36327
36840
  */
36328
36841
  helper('click', click);
36329
36842
 
@@ -36342,7 +36855,7 @@ helper('click', click);
36342
36855
  * @param {String} selector jQuery selector for finding element on the DOM
36343
36856
  * @param {String} the type of key event, e.g. `keypress`, `keydown`, `keyup`
36344
36857
  * @param {Number} the keyCode of the simulated key event
36345
- * @returns {RSVP.Promise}
36858
+ * @return {RSVP.Promise}
36346
36859
  */
36347
36860
  helper('keyEvent', keyEvent);
36348
36861
 
@@ -36361,7 +36874,7 @@ helper('keyEvent', keyEvent);
36361
36874
  * @param {String} selector jQuery selector finding an input element on the DOM
36362
36875
  * to fill text with
36363
36876
  * @param {String} text text to place inside the input element
36364
- * @returns {RSVP.Promise}
36877
+ * @return {RSVP.Promise}
36365
36878
  */
36366
36879
  helper('fillIn', fillIn);
36367
36880
 
@@ -36377,7 +36890,7 @@ helper('fillIn', fillIn);
36377
36890
  *
36378
36891
  * @method find
36379
36892
  * @param {String} selector jQuery string selector for element lookup
36380
- * @returns {Object} jQuery object representing the results of the query
36893
+ * @return {Object} jQuery object representing the results of the query
36381
36894
  */
36382
36895
  helper('find', find);
36383
36896
 
@@ -36449,7 +36962,7 @@ Ember
36449
36962
 
36450
36963
  function throwWithMessage(msg) {
36451
36964
  return function() {
36452
- throw new Error(msg);
36965
+ throw new Ember.Error(msg);
36453
36966
  };
36454
36967
  }
36455
36968
 
@@ -36463,7 +36976,23 @@ function generateRemovedClass(className) {
36463
36976
  }
36464
36977
 
36465
36978
  Ember.StateManager = generateRemovedClass("Ember.StateManager");
36979
+
36980
+ /**
36981
+ This was exported to ember-states plugin for v 1.0.0 release. See: https://github.com/emberjs/ember-states
36982
+
36983
+ @class StateManager
36984
+ @namespace Ember
36985
+ */
36986
+
36466
36987
  Ember.State = generateRemovedClass("Ember.State");
36988
+
36989
+ /**
36990
+ This was exported to ember-states plugin for v 1.0.0 release. See: https://github.com/emberjs/ember-states
36991
+
36992
+ @class State
36993
+ @namespace Ember
36994
+ */
36995
+
36467
36996
  })();
36468
36997
 
36469
36998