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.
@@ -61,7 +61,7 @@ var define, requireModule;
61
61
 
62
62
  @class Ember
63
63
  @static
64
- @version 1.0.0
64
+ @version 1.1.2
65
65
  */
66
66
 
67
67
  if ('undefined' === typeof Ember) {
@@ -88,10 +88,10 @@ Ember.toString = function() { return "Ember"; };
88
88
  /**
89
89
  @property VERSION
90
90
  @type String
91
- @default '1.0.0'
91
+ @default '1.1.2'
92
92
  @final
93
93
  */
94
- Ember.VERSION = '1.0.0';
94
+ Ember.VERSION = '1.1.2';
95
95
 
96
96
  /**
97
97
  Standard environmental variables. You can define these in a global `ENV`
@@ -116,6 +116,27 @@ Ember.ENV = Ember.ENV || ENV;
116
116
 
117
117
  Ember.config = Ember.config || {};
118
118
 
119
+ /**
120
+ Hash of enabled Canary features. Add to before creating your application.
121
+
122
+ @property FEATURES
123
+ @type Hash
124
+ */
125
+
126
+ Ember.FEATURES = {};
127
+
128
+ /**
129
+ Test that a feature is enabled. Parsed by Ember's build tools to leave
130
+ experimental features out of beta/stable builds.
131
+
132
+ @method isEnabled
133
+ @param {string} feature
134
+ */
135
+
136
+ Ember.FEATURES.isEnabled = function(feature) {
137
+ return Ember.FEATURES[feature];
138
+ };
139
+
119
140
  // ..........................................................
120
141
  // BOOTSTRAP
121
142
  //
@@ -326,7 +347,7 @@ Ember.Logger = {
326
347
 
327
348
  @method assert
328
349
  @for Ember.Logger
329
- @param @param {Boolean} bool Value to test
350
+ @param {Boolean} bool Value to test
330
351
  */
331
352
  assert: consoleMethod('assert') || assertPolyfill
332
353
  };
@@ -2074,6 +2095,7 @@ function suspendListeners(obj, eventNames, target, method, callback) {
2074
2095
  }
2075
2096
 
2076
2097
  var suspendedActions = [],
2098
+ actionsList = [],
2077
2099
  eventName, actions, i, l;
2078
2100
 
2079
2101
  for (i=0, l=eventNames.length; i<l; i++) {
@@ -2084,6 +2106,7 @@ function suspendListeners(obj, eventNames, target, method, callback) {
2084
2106
  if (actionIndex !== -1) {
2085
2107
  actions[actionIndex+2] |= SUSPENDED;
2086
2108
  suspendedActions.push(actionIndex);
2109
+ actionsList.push(actions);
2087
2110
  }
2088
2111
  }
2089
2112
 
@@ -2092,7 +2115,7 @@ function suspendListeners(obj, eventNames, target, method, callback) {
2092
2115
  function finalizer() {
2093
2116
  for (var i = 0, l = suspendedActions.length; i < l; i++) {
2094
2117
  var actionIndex = suspendedActions[i];
2095
- actions[actionIndex+2] &= ~SUSPENDED;
2118
+ actionsList[i][actionIndex+2] &= ~SUSPENDED;
2096
2119
  }
2097
2120
  }
2098
2121
 
@@ -4429,18 +4452,18 @@ function registerComputedWithProperties(name, macro) {
4429
4452
  }
4430
4453
 
4431
4454
  /**
4432
- A computed property that returns true of the value of the dependent
4455
+ A computed property that returns true if the value of the dependent
4433
4456
  property is null, an empty string, empty array, or empty function.
4434
4457
 
4435
4458
  Note: When using `Ember.computed.empty` to watch an array make sure to
4436
- use the `array.length` syntax so the computed can subscribe to transitions
4459
+ use the `array.[]` syntax so the computed can subscribe to transitions
4437
4460
  from empty to non-empty states.
4438
4461
 
4439
4462
  Example
4440
4463
 
4441
4464
  ```javascript
4442
4465
  var ToDoList = Ember.Object.extend({
4443
- done: Ember.computed.empty('todos.length')
4466
+ done: Ember.computed.empty('todos.[]') // detect array changes
4444
4467
  });
4445
4468
  var todoList = ToDoList.create({todos: ['Unit Test', 'Documentation', 'Release']});
4446
4469
  todoList.get('done'); // false
@@ -4459,7 +4482,7 @@ registerComputed('empty', function(dependentKey) {
4459
4482
  });
4460
4483
 
4461
4484
  /**
4462
- A computed property that returns true of the value of the dependent
4485
+ A computed property that returns true if the value of the dependent
4463
4486
  property is NOT null, an empty string, empty array, or empty function.
4464
4487
 
4465
4488
  Example
@@ -4485,7 +4508,7 @@ registerComputed('notEmpty', function(dependentKey) {
4485
4508
  });
4486
4509
 
4487
4510
  /**
4488
- A computed property that returns true of the value of the dependent
4511
+ A computed property that returns true if the value of the dependent
4489
4512
  property is null or undefined. This avoids errors from JSLint complaining
4490
4513
  about use of ==, which can be technically confusing.
4491
4514
 
@@ -4524,9 +4547,9 @@ registerComputed('none', function(dependentKey) {
4524
4547
  isAnonymous: Ember.computed.not('loggedIn')
4525
4548
  });
4526
4549
  var user = User.create({loggedIn: false});
4527
- user.get('isAnonymous'); // false
4528
- user.set('loggedIn', true);
4529
4550
  user.get('isAnonymous'); // true
4551
+ user.set('loggedIn', true);
4552
+ user.get('isAnonymous'); // false
4530
4553
  ```
4531
4554
 
4532
4555
  @method computed.not
@@ -4560,7 +4583,7 @@ registerComputed('not', function(dependentKey) {
4560
4583
  @method computed.bool
4561
4584
  @for Ember
4562
4585
  @param {String} dependentKey
4563
- @return {Ember.ComputedProperty} computed property which convert
4586
+ @return {Ember.ComputedProperty} computed property which converts
4564
4587
  to boolean the original value for property
4565
4588
  */
4566
4589
  registerComputed('bool', function(dependentKey) {
@@ -4611,7 +4634,7 @@ registerComputed('match', function(dependentKey, regexp) {
4611
4634
  var hampster = Hampster.create();
4612
4635
  hampster.get('napTime'); // false
4613
4636
  hampster.set('state', 'sleepy');
4614
- hampster.get('napTime'); // false
4637
+ hampster.get('napTime'); // true
4615
4638
  hampster.set('state', 'hungry');
4616
4639
  hampster.get('napTime'); // false
4617
4640
  ```
@@ -4778,7 +4801,7 @@ registerComputedWithProperties('and', function(properties) {
4778
4801
  });
4779
4802
 
4780
4803
  /**
4781
- A computed property that which performs a logical `or` on the
4804
+ A computed property which performs a logical `or` on the
4782
4805
  original values for the provided dependent properties.
4783
4806
 
4784
4807
  Example
@@ -4945,7 +4968,7 @@ Ember.computed.alias = function(dependentKey) {
4945
4968
  @method computed.oneWay
4946
4969
  @for Ember
4947
4970
  @param {String} dependentKey
4948
- @return {Ember.ComputedProperty} computed property which creates an
4971
+ @return {Ember.ComputedProperty} computed property which creates a
4949
4972
  one way computed property to the original value for property.
4950
4973
  */
4951
4974
  Ember.computed.oneWay = function(dependentKey) {
@@ -4957,7 +4980,7 @@ Ember.computed.oneWay = function(dependentKey) {
4957
4980
 
4958
4981
  /**
4959
4982
  A computed property that acts like a standard getter and setter,
4960
- but retruns the value at the provided `defaultPath` if the
4983
+ but returns the value at the provided `defaultPath` if the
4961
4984
  property itself has not been set to a value
4962
4985
 
4963
4986
  Example
@@ -5325,7 +5348,12 @@ define("backburner",
5325
5348
  debouncees = [],
5326
5349
  timers = [],
5327
5350
  autorun, laterTimer, laterTimerExpiresAt,
5328
- global = this;
5351
+ global = this,
5352
+ NUMBER = /\d+/;
5353
+
5354
+ function isCoercableNumber(number) {
5355
+ return typeof number === 'number' || NUMBER.test(number);
5356
+ }
5329
5357
 
5330
5358
  function Backburner(queueNames, options) {
5331
5359
  this.queueNames = queueNames;
@@ -5440,32 +5468,60 @@ define("backburner",
5440
5468
  },
5441
5469
 
5442
5470
  setTimeout: function() {
5443
- var self = this,
5444
- wait = pop.call(arguments),
5445
- target = arguments[0],
5446
- method = arguments[1],
5447
- executeAt = (+new Date()) + wait;
5471
+ var args = slice.call(arguments);
5472
+ var length = args.length;
5473
+ var method, wait, target;
5474
+ var self = this;
5475
+ var methodOrTarget, methodOrWait, methodOrArgs;
5448
5476
 
5449
- if (!method) {
5450
- method = target;
5451
- target = null;
5477
+ if (length === 0) {
5478
+ return;
5479
+ } else if (length === 1) {
5480
+ method = args.shift();
5481
+ wait = 0;
5482
+ } else if (length === 2) {
5483
+ methodOrTarget = args[0];
5484
+ methodOrWait = args[1];
5485
+
5486
+ if (typeof methodOrWait === 'function' || typeof methodOrTarget[methodOrWait] === 'function') {
5487
+ target = args.shift();
5488
+ method = args.shift();
5489
+ wait = 0;
5490
+ } else if (isCoercableNumber(methodOrWait)) {
5491
+ method = args.shift();
5492
+ wait = args.shift();
5493
+ } else {
5494
+ method = args.shift();
5495
+ wait = 0;
5496
+ }
5497
+ } else {
5498
+ var last = args[args.length - 1];
5499
+
5500
+ if (isCoercableNumber(last)) {
5501
+ wait = args.pop();
5502
+ }
5503
+
5504
+ methodOrTarget = args[0];
5505
+ methodOrArgs = args[1];
5506
+
5507
+ if (typeof methodOrArgs === 'function' || (typeof methodOrArgs === 'string' &&
5508
+ methodOrTarget !== null &&
5509
+ methodOrArgs in methodOrTarget)) {
5510
+ target = args.shift();
5511
+ method = args.shift();
5512
+ } else {
5513
+ method = args.shift();
5514
+ }
5452
5515
  }
5453
5516
 
5517
+ var executeAt = (+new Date()) + parseInt(wait, 10);
5518
+
5454
5519
  if (typeof method === 'string') {
5455
5520
  method = target[method];
5456
5521
  }
5457
5522
 
5458
- var fn, args;
5459
- if (arguments.length > 2) {
5460
- args = slice.call(arguments, 2);
5461
-
5462
- fn = function() {
5463
- method.apply(target, args);
5464
- };
5465
- } else {
5466
- fn = function() {
5467
- method.call(target);
5468
- };
5523
+ function fn() {
5524
+ method.apply(target, args);
5469
5525
  }
5470
5526
 
5471
5527
  // find position to insert - TODO: binary search
@@ -5666,6 +5722,7 @@ define("backburner",
5666
5722
 
5667
5723
  __exports__.Backburner = Backburner;
5668
5724
  });
5725
+
5669
5726
  })();
5670
5727
 
5671
5728
 
@@ -6839,15 +6896,14 @@ function addNormalizedProperty(base, key, value, meta, descs, values, concats, m
6839
6896
  descs[key] = value;
6840
6897
  values[key] = undefined;
6841
6898
  } else {
6842
- // impl super if needed...
6843
- if (isMethod(value)) {
6844
- value = giveMethodSuper(base, key, value, values, descs);
6845
- } else if ((concats && a_indexOf.call(concats, key) >= 0) ||
6899
+ if ((concats && a_indexOf.call(concats, key) >= 0) ||
6846
6900
  key === 'concatenatedProperties' ||
6847
6901
  key === 'mergedProperties') {
6848
6902
  value = applyConcatenatedProperties(base, key, value, values);
6849
6903
  } else if ((mergings && a_indexOf.call(mergings, key) >= 0)) {
6850
6904
  value = applyMergedProperties(base, key, value, values);
6905
+ } else if (isMethod(value)) {
6906
+ value = giveMethodSuper(base, key, value, values, descs);
6851
6907
  }
6852
6908
 
6853
6909
  descs[key] = undefined;
@@ -7283,11 +7339,10 @@ Alias.prototype = new Ember.Descriptor();
7283
7339
  @deprecated Use `Ember.aliasMethod` or `Ember.computed.alias` instead
7284
7340
  */
7285
7341
  Ember.alias = function(methodName) {
7342
+
7286
7343
  return new Alias(methodName);
7287
7344
  };
7288
7345
 
7289
- Ember.alias = Ember.deprecateFunc("Ember.alias is deprecated. Please use Ember.aliasMethod or Ember.computed.alias instead.", Ember.alias);
7290
-
7291
7346
  /**
7292
7347
  Makes a method available via an additional name.
7293
7348
 
@@ -7429,6 +7484,55 @@ Ember.beforeObserver = function(func) {
7429
7484
 
7430
7485
 
7431
7486
 
7487
+ (function() {
7488
+ // Provides a way to register library versions with ember.
7489
+ var forEach = Ember.EnumerableUtils.forEach,
7490
+ indexOf = Ember.EnumerableUtils.indexOf;
7491
+
7492
+ Ember.libraries = function() {
7493
+ var libraries = [];
7494
+ var coreLibIndex = 0;
7495
+
7496
+ var getLibrary = function(name) {
7497
+ for (var i = 0; i < libraries.length; i++) {
7498
+ if (libraries[i].name === name) {
7499
+ return libraries[i];
7500
+ }
7501
+ }
7502
+ };
7503
+
7504
+ libraries.register = function(name, version) {
7505
+ if (!getLibrary(name)) {
7506
+ libraries.push({name: name, version: version});
7507
+ }
7508
+ };
7509
+
7510
+ libraries.registerCoreLibrary = function(name, version) {
7511
+ if (!getLibrary(name)) {
7512
+ libraries.splice(coreLibIndex++, 0, {name: name, version: version});
7513
+ }
7514
+ };
7515
+
7516
+ libraries.deRegister = function(name) {
7517
+ var lib = getLibrary(name);
7518
+ if (lib) libraries.splice(indexOf(libraries, lib), 1);
7519
+ };
7520
+
7521
+ libraries.each = function (callback) {
7522
+ forEach(libraries, function(lib) {
7523
+ callback(lib.name, lib.version);
7524
+ });
7525
+ };
7526
+
7527
+ return libraries;
7528
+ }();
7529
+
7530
+ Ember.libraries.registerCoreLibrary('Ember', Ember.VERSION);
7531
+
7532
+ })();
7533
+
7534
+
7535
+
7432
7536
  (function() {
7433
7537
  /**
7434
7538
  Ember Metal
@@ -8087,6 +8191,13 @@ define("rsvp",
8087
8191
 
8088
8192
  (function() {
8089
8193
  /**
8194
+ @private
8195
+ Public api for the container is still in flux.
8196
+ The public api, specified on the application namespace should be considered the stable api.
8197
+ // @module container
8198
+ */
8199
+
8200
+ /*
8090
8201
  Flag to enable/disable model factory injections (disabled by default)
8091
8202
  If model factory injections are enabled, models should not be
8092
8203
  accessed globally (only through `container.lookupFactory('model:modelName'))`);
@@ -8097,11 +8208,7 @@ define("container",
8097
8208
  [],
8098
8209
  function() {
8099
8210
 
8100
- /**
8101
- A safe and simple inheriting object.
8102
-
8103
- @class InheritingDict
8104
- */
8211
+ // A safe and simple inheriting object.
8105
8212
  function InheritingDict(parent) {
8106
8213
  this.parent = parent;
8107
8214
  this.dict = {};
@@ -8174,7 +8281,7 @@ define("container",
8174
8281
 
8175
8282
  @method has
8176
8283
  @param {String} key
8177
- @returns {Boolean}
8284
+ @return {Boolean}
8178
8285
  */
8179
8286
  has: function(key) {
8180
8287
  var dict = this.dict;
@@ -8208,11 +8315,10 @@ define("container",
8208
8315
  }
8209
8316
  };
8210
8317
 
8211
- /**
8212
- A lightweight container that helps to assemble and decouple components.
8213
8318
 
8214
- @class Container
8215
- */
8319
+ // A lightweight container that helps to assemble and decouple components.
8320
+ // Public api for the container is still in flux.
8321
+ // The public api, specified on the application namespace should be considered the stable api.
8216
8322
  function Container(parent) {
8217
8323
  this.parent = parent;
8218
8324
  this.children = [];
@@ -8301,7 +8407,7 @@ define("container",
8301
8407
  to correctly inherit from the current container.
8302
8408
 
8303
8409
  @method child
8304
- @returns {Container}
8410
+ @return {Container}
8305
8411
  */
8306
8412
  child: function() {
8307
8413
  var container = new Container(this);
@@ -8337,25 +8443,25 @@ define("container",
8337
8443
  ```
8338
8444
 
8339
8445
  @method register
8340
- @param {String} type
8341
- @param {String} name
8446
+ @param {String} fullName
8342
8447
  @param {Function} factory
8343
8448
  @param {Object} options
8344
8449
  */
8345
- register: function(type, name, factory, options) {
8346
- var fullName;
8347
-
8348
- if (type.indexOf(':') !== -1) {
8349
- options = factory;
8350
- factory = name;
8351
- fullName = type;
8352
- } else {
8450
+ register: function(fullName, factory, options) {
8451
+ if (fullName.indexOf(':') === -1) {
8452
+ throw new TypeError("malformed fullName, expected: `type:name` got: " + fullName + "");
8453
+ }
8353
8454
 
8354
- fullName = type + ":" + name;
8455
+ if (factory === undefined) {
8456
+ throw new TypeError('Attempting to register an unknown factory: `' + fullName + '`');
8355
8457
  }
8356
8458
 
8357
8459
  var normalizedName = this.normalize(fullName);
8358
8460
 
8461
+ if (this.cache.has(normalizedName)) {
8462
+ throw new Error('Cannot re-register: `' + fullName +'`, as it has already been looked up.');
8463
+ }
8464
+
8359
8465
  this.registry.set(normalizedName, factory);
8360
8466
  this._options.set(normalizedName, options || {});
8361
8467
  },
@@ -8415,7 +8521,7 @@ define("container",
8415
8521
 
8416
8522
  @method resolve
8417
8523
  @param {String} fullName
8418
- @returns {Function} fullName's factory
8524
+ @return {Function} fullName's factory
8419
8525
  */
8420
8526
  resolve: function(fullName) {
8421
8527
  return this.resolver(fullName) || this.registry.get(fullName);
@@ -8450,7 +8556,7 @@ define("container",
8450
8556
  @method makeToString
8451
8557
 
8452
8558
  @param {any} factory
8453
- @param {string} fullNae
8559
+ @param {string} fullName
8454
8560
  @return {function} toString function
8455
8561
  */
8456
8562
  makeToString: function(factory, fullName) {
@@ -8507,7 +8613,7 @@ define("container",
8507
8613
 
8508
8614
  var value = instantiate(this, fullName);
8509
8615
 
8510
- if (!value) { return; }
8616
+ if (value === undefined) { return; }
8511
8617
 
8512
8618
  if (isSingleton(this, fullName) && options.singleton !== false) {
8513
8619
  this.cache.set(fullName, value);
@@ -8585,7 +8691,7 @@ define("container",
8585
8691
  this.optionsForType(type, options);
8586
8692
  },
8587
8693
 
8588
- /*
8694
+ /**
8589
8695
  @private
8590
8696
 
8591
8697
  Used only via `injection`.
@@ -8627,7 +8733,7 @@ define("container",
8627
8733
  addTypeInjection(this.typeInjections, type, property, fullName);
8628
8734
  },
8629
8735
 
8630
- /*
8736
+ /**
8631
8737
  Defines injection rules.
8632
8738
 
8633
8739
  These rules are used to inject dependencies onto objects when they
@@ -8635,8 +8741,8 @@ define("container",
8635
8741
 
8636
8742
  Two forms of injections are possible:
8637
8743
 
8638
- * Injecting one fullName on another fullName
8639
- * Injecting one fullName on a type
8744
+ * Injecting one fullName on another fullName
8745
+ * Injecting one fullName on a type
8640
8746
 
8641
8747
  Example:
8642
8748
 
@@ -8682,7 +8788,7 @@ define("container",
8682
8788
  },
8683
8789
 
8684
8790
 
8685
- /*
8791
+ /**
8686
8792
  @private
8687
8793
 
8688
8794
  Used only via `factoryInjection`.
@@ -8719,7 +8825,7 @@ define("container",
8719
8825
  addTypeInjection(this.factoryTypeInjections, type, property, fullName);
8720
8826
  },
8721
8827
 
8722
- /*
8828
+ /**
8723
8829
  Defines factory injection rules.
8724
8830
 
8725
8831
  Similar to regular injection rules, but are run against factories, via
@@ -8730,8 +8836,8 @@ define("container",
8730
8836
 
8731
8837
  Two forms of injections are possible:
8732
8838
 
8733
- * Injecting one fullName on another fullName
8734
- * Injecting one fullName on a type
8839
+ * Injecting one fullName on another fullName
8840
+ * Injecting one fullName on a type
8735
8841
 
8736
8842
  Example:
8737
8843
 
@@ -8833,7 +8939,7 @@ define("container",
8833
8939
  injection = injections[i];
8834
8940
  lookup = container.lookup(injection.fullName);
8835
8941
 
8836
- if (lookup) {
8942
+ if (lookup !== undefined) {
8837
8943
  hash[injection.property] = lookup;
8838
8944
  } else {
8839
8945
  throw new Error('Attempting to inject an unknown injection: `' + injection.fullName + '`');
@@ -8865,13 +8971,13 @@ define("container",
8865
8971
  var cache = container.factoryCache;
8866
8972
  var type = fullName.split(":")[0];
8867
8973
 
8868
- if (!factory) { return; }
8974
+ if (factory === undefined) { return; }
8869
8975
 
8870
8976
  if (cache.has(fullName)) {
8871
8977
  return cache.get(fullName);
8872
8978
  }
8873
8979
 
8874
- if (typeof factory.extend !== 'function' || (!Ember.MODEL_FACTORY_INJECTIONS && type === 'model')) {
8980
+ if (!factory || typeof factory.extend !== 'function' || (!Ember.MODEL_FACTORY_INJECTIONS && type === 'model')) {
8875
8981
  // TODO: think about a 'safe' merge style extension
8876
8982
  // for now just fallback to create time injection
8877
8983
  return factory;
@@ -9246,16 +9352,39 @@ Ember.ORDER_DEFINITION = Ember.ENV.ORDER_DEFINITION || [
9246
9352
  Ember.keys = Object.keys;
9247
9353
 
9248
9354
  if (!Ember.keys || Ember.create.isSimulated) {
9355
+ var prototypeProperties = [
9356
+ 'constructor',
9357
+ 'hasOwnProperty',
9358
+ 'isPrototypeOf',
9359
+ 'propertyIsEnumerable',
9360
+ 'valueOf',
9361
+ 'toLocaleString',
9362
+ 'toString'
9363
+ ],
9364
+ pushPropertyName = function(obj, array, key) {
9365
+ // Prevents browsers that don't respect non-enumerability from
9366
+ // copying internal Ember properties
9367
+ if (key.substring(0,2) === '__') return;
9368
+ if (key === '_super') return;
9369
+ if (indexOf(array, key) >= 0) return;
9370
+ if (!obj.hasOwnProperty(key)) return;
9371
+
9372
+ array.push(key);
9373
+ };
9374
+
9249
9375
  Ember.keys = function(obj) {
9250
- var ret = [];
9251
- for(var key in obj) {
9252
- // Prevents browsers that don't respect non-enumerability from
9253
- // copying internal Ember properties
9254
- if (key.substring(0,2) === '__') continue;
9255
- if (key === '_super') continue;
9376
+ var ret = [], key;
9377
+ for (key in obj) {
9378
+ pushPropertyName(obj, ret, key);
9379
+ }
9256
9380
 
9257
- if (obj.hasOwnProperty(key)) { ret.push(key); }
9381
+ // IE8 doesn't enumerate property that named the same as prototype properties.
9382
+ for (var i = 0, l = prototypeProperties.length; i < l; i++) {
9383
+ key = prototypeProperties[i];
9384
+
9385
+ pushPropertyName(obj, ret, key);
9258
9386
  }
9387
+
9259
9388
  return ret;
9260
9389
  };
9261
9390
  }
@@ -10695,6 +10824,8 @@ var get = Ember.get,
10695
10824
  set = Ember.set,
10696
10825
  guidFor = Ember.guidFor,
10697
10826
  metaFor = Ember.meta,
10827
+ propertyWillChange = Ember.propertyWillChange,
10828
+ propertyDidChange = Ember.propertyDidChange,
10698
10829
  addBeforeObserver = Ember.addBeforeObserver,
10699
10830
  removeBeforeObserver = Ember.removeBeforeObserver,
10700
10831
  addObserver = Ember.addObserver,
@@ -10749,11 +10880,13 @@ function ItemPropertyObserverContext (dependentArray, index, trackedArray) {
10749
10880
  this.trackedArray = trackedArray;
10750
10881
  this.beforeObserver = null;
10751
10882
  this.observer = null;
10883
+
10884
+ this.destroyed = false;
10752
10885
  }
10753
10886
 
10754
10887
  DependentArraysObserver.prototype = {
10755
10888
  setValue: function (newValue) {
10756
- this.instanceMeta.setValue(newValue);
10889
+ this.instanceMeta.setValue(newValue, true);
10757
10890
  },
10758
10891
  getValue: function () {
10759
10892
  return this.instanceMeta.getValue();
@@ -10818,6 +10951,7 @@ DependentArraysObserver.prototype = {
10818
10951
  if (operation === Ember.TrackedArray.DELETE) { return; }
10819
10952
 
10820
10953
  forEach(observerContexts, function (observerContext) {
10954
+ observerContext.destroyed = true;
10821
10955
  beforeObserver = observerContext.beforeObserver;
10822
10956
  observer = observerContext.observer;
10823
10957
  item = observerContext.item;
@@ -10842,11 +10976,10 @@ DependentArraysObserver.prototype = {
10842
10976
  var dependentArrayObserver = this;
10843
10977
 
10844
10978
  observerContext.beforeObserver = function (obj, keyName) {
10845
- dependentArrayObserver.updateIndexes(observerContext.trackedArray, observerContext.dependentArray);
10846
- return dependentArrayObserver.itemPropertyWillChange(obj, keyName, observerContext.dependentArray, observerContext.index);
10979
+ return dependentArrayObserver.itemPropertyWillChange(obj, keyName, observerContext.dependentArray, observerContext);
10847
10980
  };
10848
10981
  observerContext.observer = function (obj, keyName) {
10849
- return dependentArrayObserver.itemPropertyDidChange(obj, keyName, observerContext.dependentArray, observerContext.index);
10982
+ return dependentArrayObserver.itemPropertyDidChange(obj, keyName, observerContext.dependentArray, observerContext);
10850
10983
  };
10851
10984
  },
10852
10985
 
@@ -10854,14 +10987,14 @@ DependentArraysObserver.prototype = {
10854
10987
  this.trackedArraysByGuid[dependentKey] = new Ember.TrackedArray(observerContexts);
10855
10988
  },
10856
10989
 
10857
- addTransformation: function (dependentKey, index, newItems) {
10990
+ trackAdd: function (dependentKey, index, newItems) {
10858
10991
  var trackedArray = this.trackedArraysByGuid[dependentKey];
10859
10992
  if (trackedArray) {
10860
10993
  trackedArray.addItems(index, newItems);
10861
10994
  }
10862
10995
  },
10863
10996
 
10864
- removeTransformation: function (dependentKey, index, removedCount) {
10997
+ trackRemove: function (dependentKey, index, removedCount) {
10865
10998
  var trackedArray = this.trackedArraysByGuid[dependentKey];
10866
10999
 
10867
11000
  if (trackedArray) {
@@ -10902,10 +11035,10 @@ DependentArraysObserver.prototype = {
10902
11035
  sliceIndex,
10903
11036
  observerContexts;
10904
11037
 
10905
- observerContexts = this.removeTransformation(dependentKey, index, removedCount);
10906
-
11038
+ observerContexts = this.trackRemove(dependentKey, index, removedCount);
10907
11039
 
10908
11040
  function removeObservers(propertyKey) {
11041
+ observerContexts[sliceIndex].destroyed = true;
10909
11042
  removeBeforeObserver(item, propertyKey, this, observerContexts[sliceIndex].beforeObserver);
10910
11043
  removeObserver(item, propertyKey, this, observerContexts[sliceIndex].observer);
10911
11044
  }
@@ -10947,33 +11080,38 @@ DependentArraysObserver.prototype = {
10947
11080
  this.instanceMeta.context, this.getValue(), item, changeMeta, this.instanceMeta.sugarMeta));
10948
11081
  }, this);
10949
11082
 
10950
- this.addTransformation(dependentKey, index, observerContexts);
11083
+ this.trackAdd(dependentKey, index, observerContexts);
10951
11084
  },
10952
11085
 
10953
- itemPropertyWillChange: function (obj, keyName, array, index) {
11086
+ itemPropertyWillChange: function (obj, keyName, array, observerContext) {
10954
11087
  var guid = guidFor(obj);
10955
11088
 
10956
11089
  if (!this.changedItems[guid]) {
10957
11090
  this.changedItems[guid] = {
10958
- array: array,
10959
- index: index,
10960
- obj: obj,
10961
- previousValues: {}
11091
+ array: array,
11092
+ observerContext: observerContext,
11093
+ obj: obj,
11094
+ previousValues: {}
10962
11095
  };
10963
11096
  }
10964
11097
 
10965
11098
  this.changedItems[guid].previousValues[keyName] = get(obj, keyName);
10966
11099
  },
10967
11100
 
10968
- itemPropertyDidChange: function(obj, keyName, array, index) {
10969
- Ember.run.once(this, 'flushChanges');
11101
+ itemPropertyDidChange: function(obj, keyName, array, observerContext) {
11102
+ this.flushChanges();
10970
11103
  },
10971
11104
 
10972
11105
  flushChanges: function() {
10973
11106
  var changedItems = this.changedItems, key, c, changeMeta;
11107
+
10974
11108
  for (key in changedItems) {
10975
11109
  c = changedItems[key];
10976
- changeMeta = createChangeMeta(c.array, c.obj, c.index, this.instanceMeta.propertyName, this.cp, c.previousValues);
11110
+ if (c.observerContext.destroyed) { continue; }
11111
+
11112
+ this.updateIndexes(c.observerContext.trackedArray, c.observerContext.dependentArray);
11113
+
11114
+ changeMeta = createChangeMeta(c.array, c.obj, c.observerContext.index, this.instanceMeta.propertyName, this.cp, c.previousValues);
10977
11115
  this.setValue(
10978
11116
  this.callbacks.removedItem.call(this.instanceMeta.context, this.getValue(), c.obj, changeMeta, this.instanceMeta.sugarMeta));
10979
11117
  this.setValue(
@@ -11043,11 +11181,21 @@ ReduceComputedPropertyInstanceMeta.prototype = {
11043
11181
  }
11044
11182
  },
11045
11183
 
11046
- setValue: function(newValue) {
11184
+ setValue: function(newValue, triggerObservers) {
11047
11185
  // This lets sugars force a recomputation, handy for very simple
11048
11186
  // implementations of eg max.
11049
11187
  if (newValue !== undefined) {
11188
+ var fireObservers = triggerObservers && (newValue !== this.cache[this.propertyName]);
11189
+
11190
+ if (fireObservers) {
11191
+ propertyWillChange(this.context, this.propertyName);
11192
+ }
11193
+
11050
11194
  this.cache[this.propertyName] = newValue;
11195
+
11196
+ if (fireObservers) {
11197
+ propertyDidChange(this.context, this.propertyName);
11198
+ }
11051
11199
  } else {
11052
11200
  delete this.cache[this.propertyName];
11053
11201
  }
@@ -11173,13 +11321,11 @@ ReduceComputedProperty.prototype._instanceMeta = function (context, propertyName
11173
11321
  };
11174
11322
 
11175
11323
  ReduceComputedProperty.prototype.initialValue = function () {
11176
- switch (typeof this.options.initialValue) {
11177
- case 'undefined':
11178
- throw new Error("reduce computed properties require an initial value: did you forget to pass one to Ember.reduceComputed?");
11179
- case 'function':
11180
- return this.options.initialValue();
11181
- default:
11182
- return this.options.initialValue;
11324
+ if (typeof this.options.initialValue === 'function') {
11325
+ return this.options.initialValue();
11326
+ }
11327
+ else {
11328
+ return this.options.initialValue;
11183
11329
  }
11184
11330
  };
11185
11331
 
@@ -11202,25 +11348,25 @@ ReduceComputedProperty.prototype.clearItemPropertyKeys = function (dependentArra
11202
11348
  ReduceComputedProperty.prototype.property = function () {
11203
11349
  var cp = this,
11204
11350
  args = a_slice.call(arguments),
11205
- propertyArgs = [],
11351
+ propertyArgs = new Ember.Set(),
11206
11352
  match,
11207
11353
  dependentArrayKey,
11208
11354
  itemPropertyKey;
11209
11355
 
11210
11356
  forEach(a_slice.call(arguments), function (dependentKey) {
11211
11357
  if (doubleEachPropertyPattern.test(dependentKey)) {
11212
- throw new Error("Nested @each properties not supported: " + dependentKey);
11358
+ throw new Ember.Error("Nested @each properties not supported: " + dependentKey);
11213
11359
  } else if (match = eachPropertyPattern.exec(dependentKey)) {
11214
11360
  dependentArrayKey = match[1];
11215
11361
  itemPropertyKey = match[2];
11216
11362
  cp.itemPropertyKey(dependentArrayKey, itemPropertyKey);
11217
- propertyArgs.push(dependentArrayKey);
11363
+ propertyArgs.add(dependentArrayKey);
11218
11364
  } else {
11219
- propertyArgs.push(dependentKey);
11365
+ propertyArgs.add(dependentKey);
11220
11366
  }
11221
11367
  });
11222
11368
 
11223
- return ComputedProperty.prototype.property.apply(this, propertyArgs);
11369
+ return ComputedProperty.prototype.property.apply(this, propertyArgs.toArray());
11224
11370
  };
11225
11371
 
11226
11372
  /**
@@ -11232,7 +11378,7 @@ ReduceComputedProperty.prototype.property = function () {
11232
11378
  If there are more than one arguments the first arguments are
11233
11379
  considered to be dependent property keys. The last argument is
11234
11380
  required to be an options object. The options object can have the
11235
- following four properties.
11381
+ following four properties:
11236
11382
 
11237
11383
  `initialValue` - A value or function that will be used as the initial
11238
11384
  value for the computed. If this property is a function the result of calling
@@ -11313,6 +11459,12 @@ ReduceComputedProperty.prototype.property = function () {
11313
11459
  to invalidate the computation. This is generally not a good idea for
11314
11460
  arrayComputed but it's used in eg max and min.
11315
11461
 
11462
+ Note that observers will be fired if either of these functions return a value
11463
+ that differs from the accumulated value. When returning an object that
11464
+ mutates in response to array changes, for example an array that maps
11465
+ everything from some other array (see `Ember.computed.map`), it is usually
11466
+ important that the *same* array be returned to avoid accidentally triggering observers.
11467
+
11316
11468
  Example
11317
11469
 
11318
11470
  ```javascript
@@ -11337,7 +11489,7 @@ ReduceComputedProperty.prototype.property = function () {
11337
11489
  @for Ember
11338
11490
  @param {String} [dependentKeys*]
11339
11491
  @param {Object} options
11340
- @returns {Ember.ComputedProperty}
11492
+ @return {Ember.ComputedProperty}
11341
11493
  */
11342
11494
  Ember.reduceComputed = function (options) {
11343
11495
  var args;
@@ -11348,11 +11500,11 @@ Ember.reduceComputed = function (options) {
11348
11500
  }
11349
11501
 
11350
11502
  if (typeof options !== "object") {
11351
- throw new Error("Reduce Computed Property declared without an options hash");
11503
+ throw new Ember.Error("Reduce Computed Property declared without an options hash");
11352
11504
  }
11353
11505
 
11354
- if (!options.initialValue) {
11355
- throw new Error("Reduce Computed Property declared without an initial value");
11506
+ if (!('initialValue' in options)) {
11507
+ throw new Ember.Error("Reduce Computed Property declared without an initial value");
11356
11508
  }
11357
11509
 
11358
11510
  var cp = new ReduceComputedProperty(options);
@@ -11520,7 +11672,7 @@ ArrayComputedProperty.prototype.resetValue = function (array) {
11520
11672
  @for Ember
11521
11673
  @param {String} [dependentKeys*]
11522
11674
  @param {Object} options
11523
- @returns {Ember.ComputedProperty}
11675
+ @return {Ember.ComputedProperty}
11524
11676
  */
11525
11677
  Ember.arrayComputed = function (options) {
11526
11678
  var args;
@@ -11531,7 +11683,7 @@ Ember.arrayComputed = function (options) {
11531
11683
  }
11532
11684
 
11533
11685
  if (typeof options !== "object") {
11534
- throw new Error("Array Computed Property declared without an options hash");
11686
+ throw new Ember.Error("Array Computed Property declared without an options hash");
11535
11687
  }
11536
11688
 
11537
11689
  var cp = new ArrayComputedProperty(options);
@@ -11678,7 +11830,7 @@ Ember.computed.min = function (dependentKey) {
11678
11830
  Ember.computed.map = function(dependentKey, callback) {
11679
11831
  var options = {
11680
11832
  addedItem: function(array, item, changeMeta, instanceMeta) {
11681
- var mapped = callback(item);
11833
+ var mapped = callback.call(this, item);
11682
11834
  array.insertAt(changeMeta.index, mapped);
11683
11835
  return array;
11684
11836
  },
@@ -11698,16 +11850,15 @@ Ember.computed.map = function(dependentKey, callback) {
11698
11850
 
11699
11851
  ```javascript
11700
11852
  App.Person = Ember.Object.extend({
11701
- childAges: Ember.computed.mapBy('children', 'age'),
11702
- minChildAge: Ember.computed.min('childAges')
11853
+ childAges: Ember.computed.mapBy('children', 'age')
11703
11854
  });
11704
11855
 
11705
11856
  var lordByron = App.Person.create({children: []});
11706
- lordByron.get('childAge'); // []
11857
+ lordByron.get('childAges'); // []
11707
11858
  lordByron.get('children').pushObject({name: 'Augusta Ada Byron', age: 7});
11708
- lordByron.get('childAge'); // [7]
11859
+ lordByron.get('childAges'); // [7]
11709
11860
  lordByron.get('children').pushObjects([{name: 'Allegra Byron', age: 5}, {name: 'Elizabeth Medora Leigh', age: 8}]);
11710
- lordByron.get('childAge'); // [7, 5, 8]
11861
+ lordByron.get('childAges'); // [7, 5, 8]
11711
11862
  ```
11712
11863
 
11713
11864
  @method computed.mapBy
@@ -11771,7 +11922,7 @@ Ember.computed.filter = function(dependentKey, callback) {
11771
11922
  },
11772
11923
 
11773
11924
  addedItem: function(array, item, changeMeta, instanceMeta) {
11774
- var match = !!callback(item),
11925
+ var match = !!callback.call(this, item),
11775
11926
  filterIndex = instanceMeta.filteredArrayIndexes.addItem(changeMeta.index, match);
11776
11927
 
11777
11928
  if (match) {
@@ -12020,7 +12171,7 @@ Ember.computed.intersect = function () {
12020
12171
  */
12021
12172
  Ember.computed.setDiff = function (setAProperty, setBProperty) {
12022
12173
  if (arguments.length !== 2) {
12023
- throw new Error("setDiff requires exactly two dependent arrays.");
12174
+ throw new Ember.Error("setDiff requires exactly two dependent arrays.");
12024
12175
  }
12025
12176
  return Ember.arrayComputed.call(null, setAProperty, setBProperty, {
12026
12177
  addedItem: function (array, item, changeMeta, instanceMeta) {
@@ -12135,7 +12286,7 @@ function binarySearch(array, item, low, high) {
12135
12286
  ]});
12136
12287
 
12137
12288
  todoList.get('sortedTodos'); // [{name:'Documentation', priority:3}, {name:'Release', priority:1}, {name:'Unit Test', priority:2}]
12138
- todoList.get('priroityTodos'); // [{name:'Release', priority:1}, {name:'Unit Test', priority:2}, {name:'Documentation', priority:3}]
12289
+ todoList.get('priorityTodos'); // [{name:'Release', priority:1}, {name:'Unit Test', priority:2}, {name:'Documentation', priority:3}]
12139
12290
  ```
12140
12291
 
12141
12292
  @method computed.sort
@@ -12275,7 +12426,7 @@ Ember.RSVP = requireModule('rsvp');
12275
12426
 
12276
12427
  var STRING_DASHERIZE_REGEXP = (/[ _]/g);
12277
12428
  var STRING_DASHERIZE_CACHE = {};
12278
- var STRING_DECAMELIZE_REGEXP = (/([a-z])([A-Z])/g);
12429
+ var STRING_DECAMELIZE_REGEXP = (/([a-z\d])([A-Z])/g);
12279
12430
  var STRING_CAMELIZE_REGEXP = (/(\-|_|\.|\s)+(.)?/g);
12280
12431
  var STRING_UNDERSCORE_REGEXP_1 = (/([a-z\d])([A-Z]+)/g);
12281
12432
  var STRING_UNDERSCORE_REGEXP_2 = (/\-|\s+/g);
@@ -12942,7 +13093,7 @@ Ember.Copyable = Ember.Mixin.create(/** @scope Ember.Copyable.prototype */ {
12942
13093
  if (Ember.Freezable && Ember.Freezable.detect(this)) {
12943
13094
  return get(this, 'isFrozen') ? this : this.copy().freeze();
12944
13095
  } else {
12945
- throw new Error(Ember.String.fmt("%@ does not support freezing", [this]));
13096
+ throw new Ember.Error(Ember.String.fmt("%@ does not support freezing", [this]));
12946
13097
  }
12947
13098
  }
12948
13099
  });
@@ -13251,7 +13402,7 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,/**
13251
13402
  @return this
13252
13403
  */
13253
13404
  insertAt: function(idx, object) {
13254
- if (idx > get(this, 'length')) throw new Error(OUT_OF_RANGE_EXCEPTION) ;
13405
+ if (idx > get(this, 'length')) throw new Ember.Error(OUT_OF_RANGE_EXCEPTION) ;
13255
13406
  this.replace(idx, 0, [object]) ;
13256
13407
  return this ;
13257
13408
  },
@@ -13279,7 +13430,7 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,/**
13279
13430
  if ('number' === typeof start) {
13280
13431
 
13281
13432
  if ((start < 0) || (start >= get(this, 'length'))) {
13282
- throw new Error(OUT_OF_RANGE_EXCEPTION);
13433
+ throw new Ember.Error(OUT_OF_RANGE_EXCEPTION);
13283
13434
  }
13284
13435
 
13285
13436
  // fast case
@@ -14092,18 +14243,29 @@ Ember.TargetActionSupport = Ember.Mixin.create({
14092
14243
  */
14093
14244
  triggerAction: function(opts) {
14094
14245
  opts = opts || {};
14095
- var action = opts['action'] || get(this, 'action'),
14096
- target = opts['target'] || get(this, 'targetObject'),
14097
- actionContext = opts['actionContext'] || get(this, 'actionContextObject') || this;
14246
+ var action = opts.action || get(this, 'action'),
14247
+ target = opts.target || get(this, 'targetObject'),
14248
+ actionContext = opts.actionContext;
14249
+
14250
+ function args(options, actionName) {
14251
+ var ret = [];
14252
+ if (actionName) { ret.push(actionName); }
14253
+
14254
+ return ret.concat(options);
14255
+ }
14256
+
14257
+ if (typeof actionContext === 'undefined') {
14258
+ actionContext = get(this, 'actionContextObject') || this;
14259
+ }
14098
14260
 
14099
14261
  if (target && action) {
14100
14262
  var ret;
14101
14263
 
14102
14264
  if (target.send) {
14103
- ret = target.send.apply(target, [action, actionContext]);
14265
+ ret = target.send.apply(target, args(actionContext, action));
14104
14266
  } else {
14105
14267
 
14106
- ret = target[action].apply(target, [actionContext]);
14268
+ ret = target[action].apply(target, args(actionContext));
14107
14269
  }
14108
14270
 
14109
14271
  if (ret !== false) ret = true;
@@ -14494,6 +14656,7 @@ function installPromise(proxy, promise) {
14494
14656
 
14495
14657
  If the controller is backing a template, the attributes are
14496
14658
  bindable from within that template
14659
+
14497
14660
  ```handlebars
14498
14661
  {{#if isPending}}
14499
14662
  loading...
@@ -14517,7 +14680,7 @@ Ember.PromiseProxyMixin = Ember.Mixin.create({
14517
14680
  installPromise(this, promise);
14518
14681
  return promise;
14519
14682
  } else {
14520
- throw new Error("PromiseProxy's promise must be set");
14683
+ throw new Ember.Error("PromiseProxy's promise must be set");
14521
14684
  }
14522
14685
  }),
14523
14686
 
@@ -14560,9 +14723,9 @@ Ember.TrackedArray = function (items) {
14560
14723
  var length = get(items, 'length');
14561
14724
 
14562
14725
  if (length) {
14563
- this._content = [new ArrayOperation(RETAIN, length, items)];
14726
+ this._operations = [new ArrayOperation(RETAIN, length, items)];
14564
14727
  } else {
14565
- this._content = [];
14728
+ this._operations = [];
14566
14729
  }
14567
14730
  };
14568
14731
 
@@ -14580,8 +14743,10 @@ Ember.TrackedArray.prototype = {
14580
14743
  @param newItems
14581
14744
  */
14582
14745
  addItems: function (index, newItems) {
14583
- var count = get(newItems, 'length'),
14584
- match = this._findArrayOperation(index),
14746
+ var count = get(newItems, 'length');
14747
+ if (count < 1) { return; }
14748
+
14749
+ var match = this._findArrayOperation(index),
14585
14750
  arrayOperation = match.operation,
14586
14751
  arrayOperationIndex = match.index,
14587
14752
  arrayOperationRangeStart = match.rangeStart,
@@ -14596,7 +14761,7 @@ Ember.TrackedArray.prototype = {
14596
14761
  if (arrayOperation) {
14597
14762
  if (!match.split) {
14598
14763
  // insert left of arrayOperation
14599
- this._content.splice(arrayOperationIndex, 0, newArrayOperation);
14764
+ this._operations.splice(arrayOperationIndex, 0, newArrayOperation);
14600
14765
  composeIndex = arrayOperationIndex;
14601
14766
  } else {
14602
14767
  this._split(arrayOperationIndex, index - arrayOperationRangeStart, newArrayOperation);
@@ -14604,7 +14769,7 @@ Ember.TrackedArray.prototype = {
14604
14769
  }
14605
14770
  } else {
14606
14771
  // insert at end
14607
- this._content.push(newArrayOperation);
14772
+ this._operations.push(newArrayOperation);
14608
14773
  composeIndex = arrayOperationIndex;
14609
14774
  }
14610
14775
 
@@ -14619,6 +14784,8 @@ Ember.TrackedArray.prototype = {
14619
14784
  @param count
14620
14785
  */
14621
14786
  removeItems: function (index, count) {
14787
+ if (count < 1) { return; }
14788
+
14622
14789
  var match = this._findArrayOperation(index),
14623
14790
  arrayOperation = match.operation,
14624
14791
  arrayOperationIndex = match.index,
@@ -14629,7 +14796,7 @@ Ember.TrackedArray.prototype = {
14629
14796
  newArrayOperation = new ArrayOperation(DELETE, count);
14630
14797
  if (!match.split) {
14631
14798
  // insert left of arrayOperation
14632
- this._content.splice(arrayOperationIndex, 0, newArrayOperation);
14799
+ this._operations.splice(arrayOperationIndex, 0, newArrayOperation);
14633
14800
  composeIndex = arrayOperationIndex;
14634
14801
  } else {
14635
14802
  this._split(arrayOperationIndex, index - arrayOperationRangeStart, newArrayOperation);
@@ -14644,30 +14811,29 @@ Ember.TrackedArray.prototype = {
14644
14811
  items in the array.
14645
14812
 
14646
14813
  `callback` will be called for each operation and will be passed the following arguments:
14647
- - {array} items The items for the given operation
14648
- - {number} offset The computed offset of the items, ie the index in the
14649
- array of the first item for this operation.
14650
- - {string} operation The type of the operation. One of
14651
- `Ember.TrackedArray.{RETAIN, DELETE, INSERT}`
14814
+ * {array} items The items for the given operation
14815
+ * {number} offset The computed offset of the items, ie the index in the
14816
+ array of the first item for this operation.
14817
+ * {string} operation The type of the operation. One of
14818
+ `Ember.TrackedArray.{RETAIN, DELETE, INSERT}`
14652
14819
 
14653
14820
  @method apply
14654
-
14655
14821
  @param {function} callback
14656
14822
  */
14657
14823
  apply: function (callback) {
14658
14824
  var items = [],
14659
14825
  offset = 0;
14660
14826
 
14661
- forEach(this._content, function (arrayOperation) {
14662
- callback(arrayOperation.items, offset, arrayOperation.operation);
14827
+ forEach(this._operations, function (arrayOperation) {
14828
+ callback(arrayOperation.items, offset, arrayOperation.type);
14663
14829
 
14664
- if (arrayOperation.operation !== DELETE) {
14830
+ if (arrayOperation.type !== DELETE) {
14665
14831
  offset += arrayOperation.count;
14666
14832
  items = items.concat(arrayOperation.items);
14667
14833
  }
14668
14834
  });
14669
14835
 
14670
- this._content = [new ArrayOperation(RETAIN, items.length, items)];
14836
+ this._operations = [new ArrayOperation(RETAIN, items.length, items)];
14671
14837
  },
14672
14838
 
14673
14839
  /**
@@ -14689,10 +14855,10 @@ Ember.TrackedArray.prototype = {
14689
14855
 
14690
14856
  // OPTIMIZE: we could search these faster if we kept a balanced tree.
14691
14857
  // find leftmost arrayOperation to the right of `index`
14692
- for (arrayOperationIndex = arrayOperationRangeStart = 0, len = this._content.length; arrayOperationIndex < len; ++arrayOperationIndex) {
14693
- arrayOperation = this._content[arrayOperationIndex];
14858
+ for (arrayOperationIndex = arrayOperationRangeStart = 0, len = this._operations.length; arrayOperationIndex < len; ++arrayOperationIndex) {
14859
+ arrayOperation = this._operations[arrayOperationIndex];
14694
14860
 
14695
- if (arrayOperation.operation === DELETE) { continue; }
14861
+ if (arrayOperation.type === DELETE) { continue; }
14696
14862
 
14697
14863
  arrayOperationRangeEnd = arrayOperationRangeStart + arrayOperation.count - 1;
14698
14864
 
@@ -14710,25 +14876,24 @@ Ember.TrackedArray.prototype = {
14710
14876
  },
14711
14877
 
14712
14878
  _split: function (arrayOperationIndex, splitIndex, newArrayOperation) {
14713
- var arrayOperation = this._content[arrayOperationIndex],
14879
+ var arrayOperation = this._operations[arrayOperationIndex],
14714
14880
  splitItems = arrayOperation.items.slice(splitIndex),
14715
- splitArrayOperation = new ArrayOperation(arrayOperation.operation, splitItems.length, splitItems);
14881
+ splitArrayOperation = new ArrayOperation(arrayOperation.type, splitItems.length, splitItems);
14716
14882
 
14717
14883
  // truncate LHS
14718
14884
  arrayOperation.count = splitIndex;
14719
14885
  arrayOperation.items = arrayOperation.items.slice(0, splitIndex);
14720
14886
 
14721
- this._content.splice(arrayOperationIndex + 1, 0, newArrayOperation, splitArrayOperation);
14887
+ this._operations.splice(arrayOperationIndex + 1, 0, newArrayOperation, splitArrayOperation);
14722
14888
  },
14723
14889
 
14724
- // TODO: unify _composeInsert, _composeDelete
14725
14890
  // see SubArray for a better implementation.
14726
14891
  _composeInsert: function (index) {
14727
- var newArrayOperation = this._content[index],
14728
- leftArrayOperation = this._content[index-1], // may be undefined
14729
- rightArrayOperation = this._content[index+1], // may be undefined
14730
- leftOp = leftArrayOperation && leftArrayOperation.operation,
14731
- rightOp = rightArrayOperation && rightArrayOperation.operation;
14892
+ var newArrayOperation = this._operations[index],
14893
+ leftArrayOperation = this._operations[index-1], // may be undefined
14894
+ rightArrayOperation = this._operations[index+1], // may be undefined
14895
+ leftOp = leftArrayOperation && leftArrayOperation.type,
14896
+ rightOp = rightArrayOperation && rightArrayOperation.type;
14732
14897
 
14733
14898
  if (leftOp === INSERT) {
14734
14899
  // merge left
@@ -14736,30 +14901,31 @@ Ember.TrackedArray.prototype = {
14736
14901
  leftArrayOperation.items = leftArrayOperation.items.concat(newArrayOperation.items);
14737
14902
 
14738
14903
  if (rightOp === INSERT) {
14739
- // also merge right
14904
+ // also merge right (we have split an insert with an insert)
14740
14905
  leftArrayOperation.count += rightArrayOperation.count;
14741
14906
  leftArrayOperation.items = leftArrayOperation.items.concat(rightArrayOperation.items);
14742
- this._content.splice(index, 2);
14907
+ this._operations.splice(index, 2);
14743
14908
  } else {
14744
14909
  // only merge left
14745
- this._content.splice(index, 1);
14910
+ this._operations.splice(index, 1);
14746
14911
  }
14747
14912
  } else if (rightOp === INSERT) {
14748
14913
  // merge right
14749
14914
  newArrayOperation.count += rightArrayOperation.count;
14750
14915
  newArrayOperation.items = newArrayOperation.items.concat(rightArrayOperation.items);
14751
- this._content.splice(index + 1, 1);
14916
+ this._operations.splice(index + 1, 1);
14752
14917
  }
14753
14918
  },
14754
14919
 
14755
14920
  _composeDelete: function (index) {
14756
- var arrayOperation = this._content[index],
14921
+ var arrayOperation = this._operations[index],
14757
14922
  deletesToGo = arrayOperation.count,
14758
- leftArrayOperation = this._content[index-1], // may be undefined
14759
- leftOp = leftArrayOperation && leftArrayOperation.operation,
14923
+ leftArrayOperation = this._operations[index-1], // may be undefined
14924
+ leftOp = leftArrayOperation && leftArrayOperation.type,
14760
14925
  nextArrayOperation,
14761
14926
  nextOp,
14762
14927
  nextCount,
14928
+ removeNewAndNextOp = false,
14763
14929
  removedItems = [];
14764
14930
 
14765
14931
  if (leftOp === DELETE) {
@@ -14768,8 +14934,8 @@ Ember.TrackedArray.prototype = {
14768
14934
  }
14769
14935
 
14770
14936
  for (var i = index + 1; deletesToGo > 0; ++i) {
14771
- nextArrayOperation = this._content[i];
14772
- nextOp = nextArrayOperation.operation;
14937
+ nextArrayOperation = this._operations[i];
14938
+ nextOp = nextArrayOperation.type;
14773
14939
  nextCount = nextArrayOperation.count;
14774
14940
 
14775
14941
  if (nextOp === DELETE) {
@@ -14778,6 +14944,7 @@ Ember.TrackedArray.prototype = {
14778
14944
  }
14779
14945
 
14780
14946
  if (nextCount > deletesToGo) {
14947
+ // d:2 {r,i}:5 we reduce the retain or insert, but it stays
14781
14948
  removedItems = removedItems.concat(nextArrayOperation.items.splice(0, deletesToGo));
14782
14949
  nextArrayOperation.count -= deletesToGo;
14783
14950
 
@@ -14789,29 +14956,57 @@ Ember.TrackedArray.prototype = {
14789
14956
 
14790
14957
  deletesToGo = 0;
14791
14958
  } else {
14959
+ if (nextCount === deletesToGo) {
14960
+ // Handle edge case of d:2 i:2 in which case both operations go away
14961
+ // during composition.
14962
+ removeNewAndNextOp = true;
14963
+ }
14792
14964
  removedItems = removedItems.concat(nextArrayOperation.items);
14793
14965
  deletesToGo -= nextCount;
14794
14966
  }
14795
14967
 
14796
14968
  if (nextOp === INSERT) {
14969
+ // d:2 i:3 will result in delete going away
14797
14970
  arrayOperation.count -= nextCount;
14798
14971
  }
14799
14972
  }
14800
14973
 
14801
14974
  if (arrayOperation.count > 0) {
14802
- this._content.splice(index+1, i-1-index);
14975
+ // compose our new delete with possibly several operations to the right of
14976
+ // disparate types
14977
+ this._operations.splice(index+1, i-1-index);
14803
14978
  } else {
14804
14979
  // The delete operation can go away; it has merely reduced some other
14805
- // operation, as in D:3 I:4
14806
- this._content.splice(index, 1);
14980
+ // operation, as in d:3 i:4; it may also have eliminated that operation,
14981
+ // as in d:3 i:3.
14982
+ this._operations.splice(index, removeNewAndNextOp ? 2 : 1);
14807
14983
  }
14808
14984
 
14809
14985
  return removedItems;
14986
+ },
14987
+
14988
+ toString: function () {
14989
+ var str = "";
14990
+ forEach(this._operations, function (operation) {
14991
+ str += " " + operation.type + ":" + operation.count;
14992
+ });
14993
+ return str.substring(1);
14810
14994
  }
14811
14995
  };
14812
14996
 
14997
+ /**
14998
+ Internal data structure to represent an array operation.
14999
+
15000
+ @method ArrayOperation
15001
+ @private
15002
+ @property {string} type The type of the operation. One of
15003
+ `Ember.TrackedArray.{RETAIN, INSERT, DELETE}`
15004
+ @property {number} count The number of items in this operation.
15005
+ @property {array} items The items of the operation, if included. RETAIN and
15006
+ INSERT include their items, DELETE does not.
15007
+ */
14813
15008
  function ArrayOperation (operation, count, items) {
14814
- this.operation = operation; // RETAIN | INSERT | DELETE
15009
+ this.type = operation; // RETAIN | INSERT | DELETE
14815
15010
  this.count = count;
14816
15011
  this.items = items;
14817
15012
  }
@@ -14879,7 +15074,7 @@ Ember.SubArray.prototype = {
14879
15074
  @param {number} index The index of the item in the tracked array.
14880
15075
  @param {boolean} match `true` iff the item is included in the subarray.
14881
15076
 
14882
- @returns {number} The index of the item in the subarray.
15077
+ @return {number} The index of the item in the subarray.
14883
15078
  */
14884
15079
  addItem: function(index, match) {
14885
15080
  var returnValue = -1,
@@ -14931,7 +15126,7 @@ Ember.SubArray.prototype = {
14931
15126
 
14932
15127
  @param {number} index The index of the item in the tracked array.
14933
15128
 
14934
- @returns {number} The index of the item in the subarray, or `-1` if the item
15129
+ @return {number} The index of the item in the subarray, or `-1` if the item
14935
15130
  was not in the subarray.
14936
15131
  */
14937
15132
  removeItem: function(index) {
@@ -14949,6 +15144,8 @@ Ember.SubArray.prototype = {
14949
15144
  self._operations.splice(operationIndex, 1);
14950
15145
  self._composeAt(operationIndex);
14951
15146
  }
15147
+ }, function() {
15148
+ throw new Ember.Error("Can't remove an item that has never been added.");
14952
15149
  });
14953
15150
 
14954
15151
  return returnValue;
@@ -14995,6 +15192,7 @@ Ember.SubArray.prototype = {
14995
15192
  if (otherOp.type === op.type) {
14996
15193
  op.count += otherOp.count;
14997
15194
  this._operations.splice(index-1, 1);
15195
+ --index;
14998
15196
  }
14999
15197
  }
15000
15198
 
@@ -15090,7 +15288,14 @@ function makeCtor() {
15090
15288
  var properties = props[i];
15091
15289
 
15092
15290
 
15093
- for (var keyName in properties) {
15291
+ if (properties === null || typeof properties !== 'object') {
15292
+
15293
+ continue;
15294
+ }
15295
+
15296
+ var keyNames = Ember.keys(properties);
15297
+ for (var j = 0, ll = keyNames.length; j < ll; j++) {
15298
+ var keyName = keyNames[j];
15094
15299
  if (!properties.hasOwnProperty(keyName)) { continue; }
15095
15300
 
15096
15301
  var value = properties[keyName],
@@ -15275,7 +15480,10 @@ CoreObject.PrototypeMixin = Mixin.create({
15275
15480
  are also concatenated, in addition to `classNames`.
15276
15481
 
15277
15482
  This feature is available for you to use throughout the Ember object model,
15278
- although typical app developers are likely to use it infrequently.
15483
+ although typical app developers are likely to use it infrequently. Since
15484
+ it changes expectations about behavior of properties, you should properly
15485
+ document its usage in each individual concatenated property (to not
15486
+ mislead your users to think they can override the property in a subclass).
15279
15487
 
15280
15488
  @property concatenatedProperties
15281
15489
  @type Array
@@ -15415,6 +15623,86 @@ var ClassMixin = Mixin.create({
15415
15623
 
15416
15624
  isMethod: false,
15417
15625
 
15626
+ /**
15627
+ Creates a new subclass.
15628
+
15629
+ ```javascript
15630
+ App.Person = Ember.Object.extend({
15631
+ say: function(thing) {
15632
+ alert(thing);
15633
+ }
15634
+ });
15635
+ ```
15636
+
15637
+ This defines a new subclass of Ember.Object: `App.Person`. It contains one method: `say()`.
15638
+
15639
+ 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:
15640
+
15641
+ ```javascript
15642
+ App.PersonView = Ember.View.extend({
15643
+ tagName: 'li',
15644
+ classNameBindings: ['isAdministrator']
15645
+ });
15646
+ ```
15647
+
15648
+ When defining a subclass, you can override methods but still access the implementation of your parent class by calling the special `_super()` method:
15649
+
15650
+ ```javascript
15651
+ App.Person = Ember.Object.extend({
15652
+ say: function(thing) {
15653
+ var name = this.get('name');
15654
+ alert(name + ' says: ' + thing);
15655
+ }
15656
+ });
15657
+
15658
+ App.Soldier = App.Person.extend({
15659
+ say: function(thing) {
15660
+ this._super(thing + ", sir!");
15661
+ },
15662
+ march: function(numberOfHours) {
15663
+ alert(this.get('name') + ' marches for ' + numberOfHours + ' hours.')
15664
+ }
15665
+ });
15666
+
15667
+ var yehuda = App.Soldier.create({
15668
+ name: "Yehuda Katz"
15669
+ });
15670
+
15671
+ yehuda.say("Yes"); // alerts "Yehuda Katz says: Yes, sir!"
15672
+ ```
15673
+
15674
+ 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.
15675
+
15676
+ You can also pass `Ember.Mixin` classes to add additional properties to the subclass.
15677
+
15678
+ ```javascript
15679
+ App.Person = Ember.Object.extend({
15680
+ say: function(thing) {
15681
+ alert(this.get('name') + ' says: ' + thing);
15682
+ }
15683
+ });
15684
+
15685
+ App.SingingMixin = Ember.Mixin.create({
15686
+ sing: function(thing){
15687
+ alert(this.get('name') + ' sings: la la la ' + thing);
15688
+ }
15689
+ });
15690
+
15691
+ App.BroadwayStar = App.Person.extend(App.SingingMixin, {
15692
+ dance: function() {
15693
+ alert(this.get('name') + ' dances: tap tap tap tap ');
15694
+ }
15695
+ });
15696
+ ```
15697
+
15698
+ The `App.BroadwayStar` class contains three methods: `say()`, `sing()`, and `dance()`.
15699
+
15700
+ @method extend
15701
+ @static
15702
+
15703
+ @param {Ember.Mixin} [mixins]* One or more Ember.Mixin classes
15704
+ @param {Object} [arguments]* Object containing values to use within the new class
15705
+ */
15418
15706
  extend: function() {
15419
15707
  var Class = makeCtor(), proto;
15420
15708
  Class.ClassMixin = Mixin.create(this.ClassMixin);
@@ -15495,10 +15783,10 @@ var ClassMixin = Mixin.create({
15495
15783
  },
15496
15784
 
15497
15785
  /**
15498
-
15786
+
15499
15787
  Augments a constructor's prototype with additional
15500
15788
  properties and functions:
15501
-
15789
+
15502
15790
  ```javascript
15503
15791
  MyObject = Ember.Object.extend({
15504
15792
  name: 'an object'
@@ -15518,7 +15806,7 @@ var ClassMixin = Mixin.create({
15518
15806
 
15519
15807
  o.say("goodbye"); // logs "goodbye"
15520
15808
  ```
15521
-
15809
+
15522
15810
  To add functions and properties to the constructor itself,
15523
15811
  see `reopenClass`
15524
15812
 
@@ -15532,7 +15820,7 @@ var ClassMixin = Mixin.create({
15532
15820
 
15533
15821
  /**
15534
15822
  Augments a constructor's own properties and functions:
15535
-
15823
+
15536
15824
  ```javascript
15537
15825
  MyObject = Ember.Object.extend({
15538
15826
  name: 'an object'
@@ -15542,17 +15830,50 @@ var ClassMixin = Mixin.create({
15542
15830
  MyObject.reopenClass({
15543
15831
  canBuild: false
15544
15832
  });
15545
-
15833
+
15546
15834
  MyObject.canBuild; // false
15547
15835
  o = MyObject.create();
15548
15836
  ```
15549
-
15837
+
15838
+ In other words, this creates static properties and functions for the class. These are only available on the class
15839
+ and not on any instance of that class.
15840
+
15841
+ ```javascript
15842
+ App.Person = Ember.Object.extend({
15843
+ name : "",
15844
+ sayHello : function(){
15845
+ alert("Hello. My name is " + this.get('name'));
15846
+ }
15847
+ });
15848
+
15849
+ App.Person.reopenClass({
15850
+ species : "Homo sapiens",
15851
+ createPerson: function(newPersonsName){
15852
+ return App.Person.create({
15853
+ name:newPersonsName
15854
+ });
15855
+ }
15856
+ });
15857
+
15858
+ var tom = App.Person.create({
15859
+ name : "Tom Dale"
15860
+ });
15861
+ var yehuda = App.Person.createPerson("Yehuda Katz");
15862
+
15863
+ tom.sayHello(); // "Hello. My name is Tom Dale"
15864
+ yehuda.sayHello(); // "Hello. My name is Yehuda Katz"
15865
+ alert(App.Person.species); // "Homo sapiens"
15866
+ ```
15867
+
15868
+ Note that `species` and `createPerson` are *not* valid on the `tom` and `yehuda`
15869
+ variables. They are only valid on `App.Person`.
15870
+
15550
15871
  To add functions and properties to instances of
15551
15872
  a constructor by extending the constructor's prototype
15552
15873
  see `reopen`
15553
-
15874
+
15554
15875
  @method reopenClass
15555
- */
15876
+ */
15556
15877
  reopenClass: function() {
15557
15878
  reopen.apply(this.ClassMixin, arguments);
15558
15879
  applyMixin(this, arguments, false);
@@ -16108,7 +16429,7 @@ Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,/** @scope Ember.Array
16108
16429
  },
16109
16430
 
16110
16431
  _insertAt: function(idx, object) {
16111
- if (idx > get(this, 'content.length')) throw new Error(OUT_OF_RANGE_EXCEPTION);
16432
+ if (idx > get(this, 'content.length')) throw new Ember.Error(OUT_OF_RANGE_EXCEPTION);
16112
16433
  this._replace(idx, 0, [object]);
16113
16434
  return this;
16114
16435
  },
@@ -16128,7 +16449,7 @@ Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,/** @scope Ember.Array
16128
16449
  indices = [], i;
16129
16450
 
16130
16451
  if ((start < 0) || (start >= get(this, 'length'))) {
16131
- throw new Error(OUT_OF_RANGE_EXCEPTION);
16452
+ throw new Ember.Error(OUT_OF_RANGE_EXCEPTION);
16132
16453
  }
16133
16454
 
16134
16455
  if (len === undefined) len = 1;
@@ -16895,7 +17216,7 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
16895
17216
  @return {Ember.Set} An empty Set
16896
17217
  */
16897
17218
  clear: function() {
16898
- if (this.isFrozen) { throw new Error(Ember.FROZEN_ERROR); }
17219
+ if (this.isFrozen) { throw new Ember.Error(Ember.FROZEN_ERROR); }
16899
17220
 
16900
17221
  var len = get(this, 'length');
16901
17222
  if (len === 0) { return this; }
@@ -17005,7 +17326,7 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
17005
17326
  @return {Object} The removed object from the set or null.
17006
17327
  */
17007
17328
  pop: function() {
17008
- if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
17329
+ if (get(this, 'isFrozen')) throw new Ember.Error(Ember.FROZEN_ERROR);
17009
17330
  var obj = this.length > 0 ? this[this.length-1] : null;
17010
17331
  this.remove(obj);
17011
17332
  return obj;
@@ -17122,7 +17443,7 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
17122
17443
 
17123
17444
  // implements Ember.MutableEnumerable
17124
17445
  addObject: function(obj) {
17125
- if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
17446
+ if (get(this, 'isFrozen')) throw new Ember.Error(Ember.FROZEN_ERROR);
17126
17447
  if (isNone(obj)) return this; // nothing to do
17127
17448
 
17128
17449
  var guid = guidFor(obj),
@@ -17150,7 +17471,7 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
17150
17471
 
17151
17472
  // implements Ember.MutableEnumerable
17152
17473
  removeObject: function(obj) {
17153
- if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
17474
+ if (get(this, 'isFrozen')) throw new Ember.Error(Ember.FROZEN_ERROR);
17154
17475
  if (isNone(obj)) return this; // nothing to do
17155
17476
 
17156
17477
  var guid = guidFor(obj),
@@ -17856,7 +18177,7 @@ Ember.ArrayController = Ember.ArrayProxy.extend(Ember.ControllerMixin,
17856
18177
  fullName = "controller:" + controllerClass;
17857
18178
 
17858
18179
  if (!container.has(fullName)) {
17859
- throw new Error('Could not resolve itemController: "' + controllerClass + '"');
18180
+ throw new Ember.Error('Could not resolve itemController: "' + controllerClass + '"');
17860
18181
  }
17861
18182
 
17862
18183
  subController = container.lookupFactory(fullName).create({
@@ -18178,6 +18499,19 @@ function escapeAttribute(value) {
18178
18499
  return string.replace(BAD_CHARS_REGEXP, escapeChar);
18179
18500
  }
18180
18501
 
18502
+ // IE 6/7 have bugs arond setting names on inputs during creation.
18503
+ // From http://msdn.microsoft.com/en-us/library/ie/ms536389(v=vs.85).aspx:
18504
+ // "To include the NAME attribute at run time on objects created with the createElement method, use the eTag."
18505
+ var canSetNameOnInputs = (function() {
18506
+ var div = document.createElement('div'),
18507
+ el = document.createElement('input');
18508
+
18509
+ el.setAttribute('name', 'foo');
18510
+ div.appendChild(el);
18511
+
18512
+ return !!div.innerHTML.match('foo');
18513
+ })();
18514
+
18181
18515
  /**
18182
18516
  `Ember.RenderBuffer` gathers information regarding the a view and generates the
18183
18517
  final representation. `Ember.RenderBuffer` will generate HTML which can be pushed
@@ -18537,14 +18871,22 @@ Ember._RenderBuffer.prototype =
18537
18871
 
18538
18872
  generateElement: function() {
18539
18873
  var tagName = this.tagNames.pop(), // pop since we don't need to close
18540
- element = document.createElement(tagName),
18541
- $element = Ember.$(element),
18542
18874
  id = this.elementId,
18543
18875
  classes = this.classes,
18544
18876
  attrs = this.elementAttributes,
18545
18877
  props = this.elementProperties,
18546
18878
  style = this.elementStyle,
18547
- styleBuffer = '', attr, prop;
18879
+ styleBuffer = '', attr, prop, tagString;
18880
+
18881
+ if (attrs && attrs.name && !canSetNameOnInputs) {
18882
+ // IE allows passing a tag to createElement. See note on `canSetNameOnInputs` above as well.
18883
+ tagString = '<'+stripTagName(tagName)+' name="'+escapeAttribute(attrs.name)+'">';
18884
+ } else {
18885
+ tagString = tagName;
18886
+ }
18887
+
18888
+ var element = document.createElement(tagString),
18889
+ $element = Ember.$(element);
18548
18890
 
18549
18891
  if (id) {
18550
18892
  $element.attr('id', id);
@@ -18937,6 +19279,7 @@ var get = Ember.get, set = Ember.set;
18937
19279
  var guidFor = Ember.guidFor;
18938
19280
  var a_forEach = Ember.EnumerableUtils.forEach;
18939
19281
  var a_addObject = Ember.EnumerableUtils.addObject;
19282
+ var meta = Ember.meta;
18940
19283
 
18941
19284
  var childViewsProperty = Ember.computed(function() {
18942
19285
  var childViews = this._childViews, ret = Ember.A(), view = this;
@@ -18957,7 +19300,7 @@ var childViewsProperty = Ember.computed(function() {
18957
19300
 
18958
19301
  return view.replace(idx, removedCount, addedViews);
18959
19302
  }
18960
- throw new Error("childViews is immutable");
19303
+ throw new Ember.Error("childViews is immutable");
18961
19304
  };
18962
19305
 
18963
19306
  return ret;
@@ -20643,8 +20986,8 @@ Ember.View = Ember.CoreView.extend(
20643
20986
  If you write a `willDestroyElement()` handler, you can assume that your
20644
20987
  `didInsertElement()` handler was called earlier for the same element.
20645
20988
 
20646
- Normally you will not call or override this method yourself, but you may
20647
- want to implement the above callbacks when it is run.
20989
+ You should not call or override this method yourself, but you may
20990
+ want to implement the above callbacks.
20648
20991
 
20649
20992
  @method destroyElement
20650
20993
  @return {Ember.View} receiver
@@ -20681,12 +21024,6 @@ Ember.View = Ember.CoreView.extend(
20681
21024
  return viewCollection;
20682
21025
  },
20683
21026
 
20684
- _elementWillChange: Ember.beforeObserver(function() {
20685
- this.forEachChildView(function(view) {
20686
- Ember.propertyWillChange(view, 'element');
20687
- });
20688
- }, 'element'),
20689
-
20690
21027
  /**
20691
21028
  @private
20692
21029
 
@@ -20698,7 +21035,7 @@ Ember.View = Ember.CoreView.extend(
20698
21035
  */
20699
21036
  _elementDidChange: Ember.observer(function() {
20700
21037
  this.forEachChildView(function(view) {
20701
- Ember.propertyDidChange(view, 'element');
21038
+ delete meta(view).cache.element;
20702
21039
  });
20703
21040
  }, 'element'),
20704
21041
 
@@ -21143,6 +21480,7 @@ Ember.View = Ember.CoreView.extend(
21143
21480
 
21144
21481
  if (priorState && priorState.exit) { priorState.exit(this); }
21145
21482
  if (currentState.enter) { currentState.enter(this); }
21483
+ if (state === 'inDOM') { delete Ember.meta(this).cache.element; }
21146
21484
 
21147
21485
  if (children !== false) {
21148
21486
  this.forEachChildView(function(view) {
@@ -21174,6 +21512,10 @@ Ember.View = Ember.CoreView.extend(
21174
21512
  target = null;
21175
21513
  }
21176
21514
 
21515
+ if (!root || typeof root !== 'object') {
21516
+ return;
21517
+ }
21518
+
21177
21519
  var view = this,
21178
21520
  stateCheckedObserver = function() {
21179
21521
  view.currentState.invokeObserver(this, observer);
@@ -21490,10 +21832,18 @@ Ember.merge(preRender, {
21490
21832
  var viewCollection = view.viewHierarchyCollection();
21491
21833
 
21492
21834
  viewCollection.trigger('willInsertElement');
21493
- // after createElement, the view will be in the hasElement state.
21835
+
21494
21836
  fn.call(view);
21495
- viewCollection.transitionTo('inDOM', false);
21496
- viewCollection.trigger('didInsertElement');
21837
+
21838
+ // We transition to `inDOM` if the element exists in the DOM
21839
+ var element = view.get('element');
21840
+ while (element = element.parentNode) {
21841
+ if (element === document) {
21842
+ viewCollection.transitionTo('inDOM', false);
21843
+ viewCollection.trigger('didInsertElement');
21844
+ }
21845
+ }
21846
+
21497
21847
  },
21498
21848
 
21499
21849
  renderToBufferIfNeeded: function(view, buffer) {
@@ -21702,7 +22052,7 @@ Ember.merge(inDOM, {
21702
22052
  }
21703
22053
 
21704
22054
  view.addBeforeObserver('elementId', function() {
21705
- throw new Error("Changing a view's elementId after creation is not allowed");
22055
+ throw new Ember.Error("Changing a view's elementId after creation is not allowed");
21706
22056
  });
21707
22057
  },
21708
22058
 
@@ -21942,30 +22292,6 @@ var ViewCollection = Ember._ViewCollection;
21942
22292
  or layout being rendered. The HTML contents of a `Ember.ContainerView`'s DOM
21943
22293
  representation will only be the rendered HTML of its child views.
21944
22294
 
21945
- ## Binding a View to Display
21946
-
21947
- If you would like to display a single view in your ContainerView, you can set
21948
- its `currentView` property. When the `currentView` property is set to a view
21949
- instance, it will be added to the ContainerView. If the `currentView` property
21950
- is later changed to a different view, the new view will replace the old view.
21951
- If `currentView` is set to `null`, the last `currentView` will be removed.
21952
-
21953
- This functionality is useful for cases where you want to bind the display of
21954
- a ContainerView to a controller or state manager. For example, you can bind
21955
- the `currentView` of a container to a controller like this:
21956
-
21957
- ```javascript
21958
- App.appController = Ember.Object.create({
21959
- view: Ember.View.create({
21960
- templateName: 'person_template'
21961
- })
21962
- });
21963
- ```
21964
-
21965
- ```handlebars
21966
- {{view Ember.ContainerView currentViewBinding="App.appController.view"}}
21967
- ```
21968
-
21969
22295
  @class ContainerView
21970
22296
  @namespace Ember
21971
22297
  @extends Ember.View
@@ -22150,7 +22476,7 @@ Ember.merge(states._default, {
22150
22476
 
22151
22477
  Ember.merge(states.inBuffer, {
22152
22478
  childViewsDidChange: function(parentView, views, start, added) {
22153
- throw new Error('You cannot modify child views while in the inBuffer state');
22479
+ throw new Ember.Error('You cannot modify child views while in the inBuffer state');
22154
22480
  }
22155
22481
  });
22156
22482
 
@@ -22641,7 +22967,9 @@ Ember.CollectionView.CONTAINER_MAP = {
22641
22967
 
22642
22968
 
22643
22969
  (function() {
22644
- var get = Ember.get, set = Ember.set, isNone = Ember.isNone;
22970
+ var get = Ember.get, set = Ember.set, isNone = Ember.isNone,
22971
+ a_slice = Array.prototype.slice;
22972
+
22645
22973
 
22646
22974
  /**
22647
22975
  @module ember
@@ -22699,8 +23027,10 @@ var get = Ember.get, set = Ember.set, isNone = Ember.isNone;
22699
23027
 
22700
23028
  ```javascript
22701
23029
  App.AppProfileComponent = Ember.Component.extend({
22702
- hello: function(name) {
22703
- console.log("Hello", name);
23030
+ actions: {
23031
+ hello: function(name) {
23032
+ console.log("Hello", name);
23033
+ }
22704
23034
  }
22705
23035
  });
22706
23036
  ```
@@ -22754,7 +23084,7 @@ Ember.Component = Ember.View.extend(Ember.TargetActionSupport, {
22754
23084
  isVirtual: true,
22755
23085
  tagName: '',
22756
23086
  _contextView: parentView,
22757
- template: get(this, 'template'),
23087
+ template: template,
22758
23088
  context: get(parentView, 'context'),
22759
23089
  controller: get(parentView, 'controller'),
22760
23090
  templateData: { keywords: parentView.cloneKeywords() }
@@ -22813,8 +23143,10 @@ Ember.Component = Ember.View.extend(Ember.TargetActionSupport, {
22813
23143
  });
22814
23144
 
22815
23145
  App.CategoriesController = Ember.Controller.extend({
22816
- didClickCategory: function(category) {
22817
- //Do something with the node/category that was clicked
23146
+ actions: {
23147
+ didClickCategory: function(category) {
23148
+ //Do something with the node/category that was clicked
23149
+ }
22818
23150
  }
22819
23151
  });
22820
23152
  ```
@@ -22828,8 +23160,9 @@ Ember.Component = Ember.View.extend(Ember.TargetActionSupport, {
22828
23160
  @param [action] {String} the action to trigger
22829
23161
  @param [context] {*} a context to send with the action
22830
23162
  */
22831
- sendAction: function(action, context) {
22832
- var actionName;
23163
+ sendAction: function(action) {
23164
+ var actionName,
23165
+ contexts = a_slice.call(arguments, 1);
22833
23166
 
22834
23167
  // Send the default action
22835
23168
  if (action === undefined) {
@@ -22845,7 +23178,7 @@ Ember.Component = Ember.View.extend(Ember.TargetActionSupport, {
22845
23178
 
22846
23179
  this.triggerAction({
22847
23180
  action: actionName,
22848
- actionContext: context
23181
+ actionContext: contexts
22849
23182
  });
22850
23183
  }
22851
23184
  });
@@ -23058,6 +23391,14 @@ define("metamorph",
23058
23391
  range.insertNode(fragment);
23059
23392
  };
23060
23393
 
23394
+ /**
23395
+ * @public
23396
+ *
23397
+ * Remove this object (including starting and ending
23398
+ * placeholders).
23399
+ *
23400
+ * @method remove
23401
+ */
23061
23402
  removeFunc = function() {
23062
23403
  // get a range for the current metamorph object including
23063
23404
  // the starting and ending placeholders.
@@ -23098,7 +23439,7 @@ define("metamorph",
23098
23439
  };
23099
23440
 
23100
23441
  } else {
23101
- /**
23442
+ /*
23102
23443
  * This code is mostly taken from jQuery, with one exception. In jQuery's case, we
23103
23444
  * have some HTML and we need to figure out how to convert it into some nodes.
23104
23445
  *
@@ -23152,12 +23493,12 @@ define("metamorph",
23152
23493
  }
23153
23494
  };
23154
23495
 
23155
- /**
23496
+ /*
23156
23497
  * Given a parent node and some HTML, generate a set of nodes. Return the first
23157
23498
  * node, which will allow us to traverse the rest using nextSibling.
23158
23499
  *
23159
23500
  * We need to do this because innerHTML in IE does not really parse the nodes.
23160
- **/
23501
+ */
23161
23502
  var firstNodeFor = function(parentNode, html) {
23162
23503
  var arr = wrapMap[parentNode.tagName.toLowerCase()] || wrapMap._default;
23163
23504
  var depth = arr[0], start = arr[1], end = arr[2];
@@ -23190,7 +23531,7 @@ define("metamorph",
23190
23531
  return element;
23191
23532
  };
23192
23533
 
23193
- /**
23534
+ /*
23194
23535
  * In some cases, Internet Explorer can create an anonymous node in
23195
23536
  * the hierarchy with no tagName. You can create this scenario via:
23196
23537
  *
@@ -23200,7 +23541,7 @@ define("metamorph",
23200
23541
  *
23201
23542
  * If our script markers are inside such a node, we need to find that
23202
23543
  * node and use *it* as the marker.
23203
- **/
23544
+ */
23204
23545
  var realNode = function(start) {
23205
23546
  while (start.parentNode.tagName === "") {
23206
23547
  start = start.parentNode;
@@ -23209,7 +23550,7 @@ define("metamorph",
23209
23550
  return start;
23210
23551
  };
23211
23552
 
23212
- /**
23553
+ /*
23213
23554
  * When automatically adding a tbody, Internet Explorer inserts the
23214
23555
  * tbody immediately before the first <tr>. Other browsers create it
23215
23556
  * before the first node, no matter what.
@@ -23236,7 +23577,8 @@ define("metamorph",
23236
23577
  *
23237
23578
  * This code reparents the first script tag by making it the tbody's
23238
23579
  * first child.
23239
- **/
23580
+ *
23581
+ */
23240
23582
  var fixParentage = function(start, end) {
23241
23583
  if (start.parentNode !== end.parentNode) {
23242
23584
  end.parentNode.insertBefore(start, end.parentNode.firstChild);
@@ -23434,20 +23776,6 @@ if (!Handlebars && typeof require === 'function') {
23434
23776
  */
23435
23777
  Ember.Handlebars = objectCreate(Handlebars);
23436
23778
 
23437
- function makeBindings(options) {
23438
- var hash = options.hash,
23439
- hashType = options.hashTypes;
23440
-
23441
- for (var prop in hash) {
23442
- if (hashType[prop] === 'ID') {
23443
- hash[prop + 'Binding'] = hash[prop];
23444
- hashType[prop + 'Binding'] = 'STRING';
23445
- delete hash[prop];
23446
- delete hashType[prop];
23447
- }
23448
- }
23449
- }
23450
-
23451
23779
  /**
23452
23780
  Register a bound helper or custom view helper.
23453
23781
 
@@ -23507,7 +23835,6 @@ Ember.Handlebars.helper = function(name, value) {
23507
23835
  if (Ember.View.detect(value)) {
23508
23836
  Ember.Handlebars.registerHelper(name, function(options) {
23509
23837
 
23510
- makeBindings(options);
23511
23838
  return Ember.Handlebars.helpers.view.call(this, value, options);
23512
23839
  });
23513
23840
  } else {
@@ -23555,7 +23882,6 @@ if (Handlebars.JavaScriptCompiler) {
23555
23882
 
23556
23883
  Ember.Handlebars.JavaScriptCompiler.prototype.namespace = "Ember.Handlebars";
23557
23884
 
23558
-
23559
23885
  Ember.Handlebars.JavaScriptCompiler.prototype.initializeBuffer = function() {
23560
23886
  return "''";
23561
23887
  };
@@ -23659,7 +23985,7 @@ if (Handlebars.compile) {
23659
23985
 
23660
23986
  var template = Ember.Handlebars.template(templateSpec);
23661
23987
  template.isMethod = false; //Make sure we don't wrap templates with ._super
23662
-
23988
+
23663
23989
  return template;
23664
23990
  };
23665
23991
  }
@@ -23927,7 +24253,8 @@ Ember.Handlebars.registerBoundHelper = function(name, fn) {
23927
24253
  data = options.data,
23928
24254
  hash = options.hash,
23929
24255
  view = data.view,
23930
- currentContext = (options.contexts && options.contexts[0]) || this,
24256
+ contexts = options.contexts,
24257
+ currentContext = (contexts && contexts.length) ? contexts[0] : this,
23931
24258
  prefixPathForDependentKeys = '',
23932
24259
  loc, len, hashOption,
23933
24260
  boundOption, property,
@@ -24051,7 +24378,7 @@ function evaluateUnboundHelper(context, fn, normalizedProperties, options) {
24051
24378
 
24052
24379
  for(loc = 0, len = normalizedProperties.length; loc < len; ++loc) {
24053
24380
  property = normalizedProperties[loc];
24054
- args.push(Ember.Handlebars.get(context, property.path, options));
24381
+ args.push(Ember.Handlebars.get(property.root, property.path, options));
24055
24382
  }
24056
24383
  args.push(options);
24057
24384
  return fn.apply(context, args);
@@ -24695,16 +25022,16 @@ function bind(property, options, preserveContext, shouldDisplay, valueNormalizer
24695
25022
  }
24696
25023
  }
24697
25024
 
24698
- function simpleBind(property, options) {
25025
+ function simpleBind(currentContext, property, options) {
24699
25026
  var data = options.data,
24700
25027
  view = data.view,
24701
- currentContext = this,
24702
- normalized, observer;
25028
+ normalized, observer, pathRoot, output;
24703
25029
 
24704
25030
  normalized = normalizePath(currentContext, property, data);
25031
+ pathRoot = normalized.root;
24705
25032
 
24706
25033
  // Set up observers for observable objects
24707
- if ('object' === typeof this) {
25034
+ if (pathRoot && ('object' === typeof pathRoot)) {
24708
25035
  if (data.insideGroup) {
24709
25036
  observer = function() {
24710
25037
  Ember.run.once(view, 'rerender');
@@ -24736,7 +25063,8 @@ function simpleBind(property, options) {
24736
25063
  } else {
24737
25064
  // The object is not observable, so just render it out and
24738
25065
  // be done with it.
24739
- data.buffer.push(handlebarsGet(currentContext, property, options));
25066
+ output = handlebarsGet(currentContext, property, options);
25067
+ data.buffer.push((output === null || typeof output === 'undefined') ? '' : output);
24740
25068
  }
24741
25069
  }
24742
25070
 
@@ -24793,10 +25121,10 @@ EmberHandlebars.registerHelper('_triageMustache', function(property, fn) {
24793
25121
  EmberHandlebars.registerHelper('bind', function(property, options) {
24794
25122
 
24795
25123
 
24796
- var context = (options.contexts && options.contexts[0]) || this;
25124
+ var context = (options.contexts && options.contexts.length) ? options.contexts[0] : this;
24797
25125
 
24798
25126
  if (!options.fn) {
24799
- return simpleBind.call(context, property, options);
25127
+ return simpleBind(context, property, options);
24800
25128
  }
24801
25129
 
24802
25130
  return bind.call(context, property, options, false, exists);
@@ -24821,7 +25149,7 @@ EmberHandlebars.registerHelper('bind', function(property, options) {
24821
25149
  @return {String} HTML string
24822
25150
  */
24823
25151
  EmberHandlebars.registerHelper('boundIf', function(property, fn) {
24824
- var context = (fn.contexts && fn.contexts[0]) || this;
25152
+ var context = (fn.contexts && fn.contexts.length) ? fn.contexts[0] : this;
24825
25153
  var func = function(result) {
24826
25154
  var truthy = result && get(result, 'isTruthy');
24827
25155
  if (typeof truthy === 'boolean') { return truthy; }
@@ -25265,6 +25593,35 @@ var EmberHandlebars = Ember.Handlebars;
25265
25593
  var LOWERCASE_A_Z = /^[a-z]/;
25266
25594
  var VIEW_PREFIX = /^view\./;
25267
25595
 
25596
+ function makeBindings(thisContext, options) {
25597
+ var hash = options.hash,
25598
+ hashType = options.hashTypes;
25599
+
25600
+ for (var prop in hash) {
25601
+ if (hashType[prop] === 'ID') {
25602
+
25603
+ var value = hash[prop];
25604
+
25605
+ if (Ember.IS_BINDING.test(prop)) {
25606
+
25607
+ } else {
25608
+ hash[prop + 'Binding'] = value;
25609
+ hashType[prop + 'Binding'] = 'STRING';
25610
+ delete hash[prop];
25611
+ delete hashType[prop];
25612
+ }
25613
+ }
25614
+ }
25615
+
25616
+ if (hash.hasOwnProperty('idBinding')) {
25617
+ // id can't be bound, so just perform one-time lookup.
25618
+ hash.id = EmberHandlebars.get(thisContext, hash.idBinding, options);
25619
+ hashType.id = 'STRING';
25620
+ delete hash.idBinding;
25621
+ delete hashType.idBinding;
25622
+ }
25623
+ }
25624
+
25268
25625
  EmberHandlebars.ViewHelper = Ember.Object.create({
25269
25626
 
25270
25627
  propertiesFromHTMLOptions: function(options, thisContext) {
@@ -25374,6 +25731,8 @@ EmberHandlebars.ViewHelper = Ember.Object.create({
25374
25731
  fn = options.fn,
25375
25732
  newView;
25376
25733
 
25734
+ makeBindings(thisContext, options);
25735
+
25377
25736
  if ('string' === typeof path) {
25378
25737
 
25379
25738
  // TODO: this is a lame conditional, this should likely change
@@ -25861,7 +26220,7 @@ Ember.Handlebars.registerHelper('unbound', function(property, fn) {
25861
26220
  return out;
25862
26221
  }
25863
26222
 
25864
- context = (fn.contexts && fn.contexts[0]) || this;
26223
+ context = (fn.contexts && fn.contexts.length) ? fn.contexts[0] : this;
25865
26224
  return handlebarsGet(context, property, fn);
25866
26225
  });
25867
26226
 
@@ -25891,7 +26250,7 @@ var handlebarsGet = Ember.Handlebars.get, normalizePath = Ember.Handlebars.norma
25891
26250
  @param {String} property
25892
26251
  */
25893
26252
  Ember.Handlebars.registerHelper('log', function(property, options) {
25894
- var context = (options.contexts && options.contexts[0]) || this,
26253
+ var context = (options.contexts && options.contexts.length) ? options.contexts[0] : this,
25895
26254
  normalized = normalizePath(context, property, options.data),
25896
26255
  pathRoot = normalized.root,
25897
26256
  path = normalized.path,
@@ -26446,7 +26805,6 @@ Ember.Handlebars.registerHelper('partial', function(name, options) {
26446
26805
  var get = Ember.get, set = Ember.set;
26447
26806
 
26448
26807
  /**
26449
-
26450
26808
  `{{yield}}` denotes an area of a template that will be rendered inside
26451
26809
  of another template. It has two main uses:
26452
26810
 
@@ -26505,11 +26863,11 @@ var get = Ember.get, set = Ember.set;
26505
26863
  <!-- application.hbs -->
26506
26864
  {{#labeled-textfield value=someProperty}}
26507
26865
  First name:
26508
- {{/my-component}}
26866
+ {{/labeled-textfield}}
26509
26867
  ```
26510
26868
 
26511
26869
  ```handlebars
26512
- <!-- components/my-component.hbs -->
26870
+ <!-- components/labeled-textfield.hbs -->
26513
26871
  <label>
26514
26872
  {{yield}} {{input value=value}}
26515
26873
  </label>
@@ -26706,7 +27064,7 @@ Ember.TextSupport = Ember.Mixin.create({
26706
27064
  Options are:
26707
27065
 
26708
27066
  * `enter`: the user pressed enter
26709
- * `keypress`: the user pressed a key
27067
+ * `keyPress`: the user pressed a key
26710
27068
 
26711
27069
  @property onEvent
26712
27070
  @type String
@@ -26749,7 +27107,7 @@ Ember.TextSupport = Ember.Mixin.create({
26749
27107
  Called by the `Ember.TextSupport` mixin on keyUp if keycode matches 13.
26750
27108
  Uses sendAction to send the `enter` action to the controller.
26751
27109
 
26752
- @method insertNewLine
27110
+ @method insertNewline
26753
27111
  @param {Event} event
26754
27112
  */
26755
27113
  insertNewline: function(event) {
@@ -26760,8 +27118,8 @@ Ember.TextSupport = Ember.Mixin.create({
26760
27118
  /**
26761
27119
  Called when the user hits escape.
26762
27120
 
26763
- Called by the `Ember.TextSupport` mixin on keyUp if keycode matches 13.
26764
- Uses sendAction to send the `enter` action to the controller.
27121
+ Called by the `Ember.TextSupport` mixin on keyUp if keycode matches 27.
27122
+ Uses sendAction to send the `escape-press` action to the controller.
26765
27123
 
26766
27124
  @method cancel
26767
27125
  @param {Event} event
@@ -26851,7 +27209,7 @@ var get = Ember.get, set = Ember.set;
26851
27209
  The internal class used to create text inputs when the `{{input}}`
26852
27210
  helper is used with `type` of `text`.
26853
27211
 
26854
- See Handlebars.helpers.input for usage details.
27212
+ See [handlebars.helpers.input](api/classes/Ember.Handlebars.helpers.html#method_input) for usage details.
26855
27213
 
26856
27214
  ## Layout and LayoutName properties
26857
27215
 
@@ -26861,7 +27219,7 @@ var get = Ember.get, set = Ember.set;
26861
27219
 
26862
27220
  @class TextField
26863
27221
  @namespace Ember
26864
- @extends Ember.View
27222
+ @extends Ember.Component
26865
27223
  @uses Ember.TextSupport
26866
27224
  */
26867
27225
  Ember.TextField = Ember.Component.extend(Ember.TextSupport,
@@ -27053,7 +27411,7 @@ var get = Ember.get, set = Ember.set;
27053
27411
  The internal class used to create textarea element when the `{{textarea}}`
27054
27412
  helper is used.
27055
27413
 
27056
- See handlebars.helpers.textarea for usage details.
27414
+ See [handlebars.helpers.textarea](/api/classes/Ember.Handlebars.helpers.html#method_textarea) for usage details.
27057
27415
 
27058
27416
  ## Layout and LayoutName properties
27059
27417
 
@@ -27063,7 +27421,7 @@ var get = Ember.get, set = Ember.set;
27063
27421
 
27064
27422
  @class TextArea
27065
27423
  @namespace Ember
27066
- @extends Ember.View
27424
+ @extends Ember.Component
27067
27425
  @uses Ember.TextSupport
27068
27426
  */
27069
27427
  Ember.TextArea = Ember.Component.extend(Ember.TextSupport, {
@@ -27182,7 +27540,7 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27182
27540
  `content` property. The underlying data object of the selected `<option>` is
27183
27541
  stored in the `Element.Select`'s `value` property.
27184
27542
 
27185
- ### `content` as an array of Strings
27543
+ ## The Content Property (array of strings)
27186
27544
 
27187
27545
  The simplest version of an `Ember.Select` takes an array of strings as its
27188
27546
  `content` property. The string will be used as both the `value` property and
@@ -27197,7 +27555,7 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27197
27555
  ```
27198
27556
 
27199
27557
  ```handlebars
27200
- {{view Ember.Select contentBinding="names"}}
27558
+ {{view Ember.Select content=names}}
27201
27559
  ```
27202
27560
 
27203
27561
  Would result in the following HTML:
@@ -27210,7 +27568,7 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27210
27568
  ```
27211
27569
 
27212
27570
  You can control which `<option>` is selected through the `Ember.Select`'s
27213
- `value` property directly or as a binding:
27571
+ `value` property:
27214
27572
 
27215
27573
  ```javascript
27216
27574
  App.ApplicationController = Ember.Controller.extend({
@@ -27221,8 +27579,8 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27221
27579
 
27222
27580
  ```handlebars
27223
27581
  {{view Ember.Select
27224
- contentBinding="names"
27225
- valueBinding="selectedName"
27582
+ content=names
27583
+ value=selectedName
27226
27584
  }}
27227
27585
  ```
27228
27586
 
@@ -27238,7 +27596,7 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27238
27596
  A user interacting with the rendered `<select>` to choose "Yehuda" would
27239
27597
  update the value of `selectedName` to "Yehuda".
27240
27598
 
27241
- ### `content` as an Array of Objects
27599
+ ## The Content Property (array of Objects)
27242
27600
 
27243
27601
  An `Ember.Select` can also take an array of JavaScript or Ember objects as
27244
27602
  its `content` property.
@@ -27263,7 +27621,7 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27263
27621
 
27264
27622
  ```handlebars
27265
27623
  {{view Ember.Select
27266
- contentBinding="programmers"
27624
+ content=programmers
27267
27625
  optionValuePath="content.id"
27268
27626
  optionLabelPath="content.firstName"}}
27269
27627
  ```
@@ -27278,8 +27636,7 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27278
27636
  ```
27279
27637
 
27280
27638
  The `value` attribute of the selected `<option>` within an `Ember.Select`
27281
- can be bound to a property on another object by providing a
27282
- `valueBinding` option:
27639
+ can be bound to a property on another object:
27283
27640
 
27284
27641
  ```javascript
27285
27642
  App.ApplicationController = Ember.Controller.extend({
@@ -27295,10 +27652,10 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27295
27652
 
27296
27653
  ```handlebars
27297
27654
  {{view Ember.Select
27298
- contentBinding="programmers"
27655
+ content=programmers
27299
27656
  optionValuePath="content.id"
27300
27657
  optionLabelPath="content.firstName"
27301
- valueBinding="currentProgrammer.id"}}
27658
+ value=currentProgrammer.id}}
27302
27659
  ```
27303
27660
 
27304
27661
  Would result in the following HTML with a selected option:
@@ -27315,8 +27672,8 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27315
27672
  to match the `value` property of the newly selected `<option>`.
27316
27673
 
27317
27674
  Alternatively, you can control selection through the underlying objects
27318
- used to render each object providing a `selectionBinding`. When the selected
27319
- `<option>` is changed, the property path provided to `selectionBinding`
27675
+ used to render each object by binding the `selection` option. When the selected
27676
+ `<option>` is changed, the property path provided to `selection`
27320
27677
  will be updated to match the content object of the rendered `<option>`
27321
27678
  element:
27322
27679
 
@@ -27332,10 +27689,10 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27332
27689
 
27333
27690
  ```handlebars
27334
27691
  {{view Ember.Select
27335
- contentBinding="programmers"
27692
+ content=programmers
27336
27693
  optionValuePath="content.id"
27337
27694
  optionLabelPath="content.firstName"
27338
- selectionBinding="selectedPerson"}}
27695
+ selection=selectedPerson}}
27339
27696
  ```
27340
27697
 
27341
27698
  Would result in the following HTML with a selected option:
@@ -27348,11 +27705,11 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27348
27705
  ```
27349
27706
 
27350
27707
  Interacting with the rendered element by selecting the first option
27351
- ('Yehuda') will update the `selectedPerson` to match the object of
27708
+ ('Yehuda') will update the `selectedPerson` to match the object of
27352
27709
  the newly selected `<option>`. In this case it is the first object
27353
27710
  in the `programmers`
27354
27711
 
27355
- ### Supplying a Prompt
27712
+ ## Supplying a Prompt
27356
27713
 
27357
27714
  A `null` value for the `Ember.Select`'s `value` or `selection` property
27358
27715
  results in there being no `<option>` with a `selected` attribute:
@@ -27369,8 +27726,8 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27369
27726
 
27370
27727
  ``` handlebars
27371
27728
  {{view Ember.Select
27372
- contentBinding="programmers"
27373
- valueBinding="selectedProgrammer"
27729
+ content=programmers
27730
+ value=selectedProgrammer
27374
27731
  }}
27375
27732
  ```
27376
27733
 
@@ -27401,8 +27758,8 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
27401
27758
 
27402
27759
  ```handlebars
27403
27760
  {{view Ember.Select
27404
- contentBinding="programmers"
27405
- valueBinding="selectedProgrammer"
27761
+ content=programmers
27762
+ value=selectedProgrammer
27406
27763
  prompt="Please select a name"
27407
27764
  }}
27408
27765
  ```
@@ -27454,11 +27811,11 @@ function program3(depth0,data) {
27454
27811
  function program4(depth0,data) {
27455
27812
 
27456
27813
  var hashContexts, hashTypes;
27457
- hashContexts = {'contentBinding': depth0,'labelBinding': depth0};
27458
- hashTypes = {'contentBinding': "ID",'labelBinding': "ID"};
27814
+ hashContexts = {'content': depth0,'label': depth0};
27815
+ hashTypes = {'content': "ID",'label': "ID"};
27459
27816
  data.buffer.push(escapeExpression(helpers.view.call(depth0, "view.groupView", {hash:{
27460
- 'contentBinding': ("content"),
27461
- 'labelBinding': ("label")
27817
+ 'content': ("content"),
27818
+ 'label': ("label")
27462
27819
  },contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
27463
27820
  }
27464
27821
 
@@ -27474,10 +27831,10 @@ function program6(depth0,data) {
27474
27831
  function program7(depth0,data) {
27475
27832
 
27476
27833
  var hashContexts, hashTypes;
27477
- hashContexts = {'contentBinding': depth0};
27478
- hashTypes = {'contentBinding': "STRING"};
27834
+ hashContexts = {'content': depth0};
27835
+ hashTypes = {'content': "ID"};
27479
27836
  data.buffer.push(escapeExpression(helpers.view.call(depth0, "view.optionView", {hash:{
27480
- 'contentBinding': ("this")
27837
+ 'content': ("")
27481
27838
  },contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
27482
27839
  }
27483
27840
 
@@ -27508,7 +27865,7 @@ function program7(depth0,data) {
27508
27865
  The `disabled` attribute of the select element. Indicates whether
27509
27866
  the element is disabled from interactions.
27510
27867
 
27511
- @property multiple
27868
+ @property disabled
27512
27869
  @type Boolean
27513
27870
  @default false
27514
27871
  */
@@ -27617,8 +27974,9 @@ function program7(depth0,data) {
27617
27974
  groupedContent: Ember.computed(function() {
27618
27975
  var groupPath = get(this, 'optionGroupPath');
27619
27976
  var groupedContent = Ember.A();
27977
+ var content = get(this, 'content') || [];
27620
27978
 
27621
- forEach(get(this, 'content'), function(item) {
27979
+ forEach(content, function(item) {
27622
27980
  var label = get(item, groupPath);
27623
27981
 
27624
27982
  if (get(groupedContent, 'lastObject.label') !== label) {
@@ -27770,18 +28128,9 @@ function program7(depth0,data) {
27770
28128
  (function() {
27771
28129
  /**
27772
28130
  @module ember
27773
- @submodule ember-handlebars
28131
+ @submodule ember-handlebars-compiler
27774
28132
  */
27775
28133
 
27776
- function normalizeHash(hash, hashTypes) {
27777
- for (var prop in hash) {
27778
- if (hashTypes[prop] === 'ID') {
27779
- hash[prop + 'Binding'] = hash[prop];
27780
- delete hash[prop];
27781
- }
27782
- }
27783
- }
27784
-
27785
28134
  /**
27786
28135
 
27787
28136
  The `{{input}}` helper inserts an HTML `<input>` tag into the template,
@@ -27793,30 +28142,32 @@ function normalizeHash(hash, hashTypes) {
27793
28142
  An `{{input}}` with no `type` or a `type` of `text` will render an HTML text input.
27794
28143
  The following HTML attributes can be set via the helper:
27795
28144
 
27796
- * `value`
27797
- * `size`
27798
- * `name`
27799
- * `pattern`
27800
- * `placeholder`
27801
- * `disabled`
27802
- * `maxlength`
27803
- * `tabindex`
28145
+ * `value`
28146
+ * `size`
28147
+ * `name`
28148
+ * `pattern`
28149
+ * `placeholder`
28150
+ * `disabled`
28151
+ * `maxlength`
28152
+ * `tabindex`
28153
+
27804
28154
 
27805
28155
  When set to a quoted string, these values will be directly applied to the HTML
27806
28156
  element. When left unquoted, these values will be bound to a property on the
27807
28157
  template's current rendering context (most typically a controller instance).
27808
28158
 
27809
- Unbound:
28159
+ ## Unbound:
27810
28160
 
27811
28161
  ```handlebars
27812
28162
  {{input value="http://www.facebook.com"}}
27813
28163
  ```
27814
28164
 
28165
+
27815
28166
  ```html
27816
28167
  <input type="text" value="http://www.facebook.com"/>
27817
28168
  ```
27818
28169
 
27819
- Bound:
28170
+ ## Bound:
27820
28171
 
27821
28172
  ```javascript
27822
28173
  App.ApplicationController = Ember.Controller.extend({
@@ -27825,15 +28176,18 @@ function normalizeHash(hash, hashTypes) {
27825
28176
  });
27826
28177
  ```
27827
28178
 
28179
+
27828
28180
  ```handlebars
27829
28181
  {{input type="text" value=firstName disabled=entryNotAllowed size="50"}}
27830
28182
  ```
27831
28183
 
28184
+
27832
28185
  ```html
27833
28186
  <input type="text" value="Stanley" disabled="disabled" size="50"/>
27834
28187
  ```
27835
28188
 
27836
- ### Extension
28189
+ ## Extension
28190
+
27837
28191
  Internally, `{{input type="text"}}` creates an instance of `Ember.TextField`, passing
27838
28192
  arguments from the helper to `Ember.TextField`'s `create` method. You can extend the
27839
28193
  capablilties of text inputs in your applications by reopening this class. For example,
@@ -27846,21 +28200,29 @@ function normalizeHash(hash, hashTypes) {
27846
28200
  });
27847
28201
  ```
27848
28202
 
28203
+ Keep in mind when writing `Ember.TextField` subclasses that `Ember.TextField`
28204
+ itself extends `Ember.Component`, meaning that it does NOT inherit
28205
+ the `controller` of the parent view.
28206
+
28207
+ See more about [Ember components](api/classes/Ember.Component.html)
28208
+
28209
+
27849
28210
  ## Use as checkbox
28211
+
27850
28212
  An `{{input}}` with a `type` of `checkbox` will render an HTML checkbox input.
27851
28213
  The following HTML attributes can be set via the helper:
27852
28214
 
27853
- * `checked`
27854
- * `disabled`
27855
- * `tabindex`
27856
- * `indeterminate`
27857
- * `name`
28215
+ * `checked`
28216
+ * `disabled`
28217
+ * `tabindex`
28218
+ * `indeterminate`
28219
+ * `name`
27858
28220
 
27859
28221
  When set to a quoted string, these values will be directly applied to the HTML
27860
28222
  element. When left unquoted, these values will be bound to a property on the
27861
28223
  template's current rendering context (most typically a controller instance).
27862
28224
 
27863
- Unbound:
28225
+ ## Unbound:
27864
28226
 
27865
28227
  ```handlebars
27866
28228
  {{input type="checkbox" name="isAdmin"}}
@@ -27870,7 +28232,7 @@ function normalizeHash(hash, hashTypes) {
27870
28232
  <input type="checkbox" name="isAdmin" />
27871
28233
  ```
27872
28234
 
27873
- Bound:
28235
+ ## Bound:
27874
28236
 
27875
28237
  ```javascript
27876
28238
  App.ApplicationController = Ember.Controller.extend({
@@ -27878,15 +28240,18 @@ function normalizeHash(hash, hashTypes) {
27878
28240
  });
27879
28241
  ```
27880
28242
 
28243
+
27881
28244
  ```handlebars
27882
28245
  {{input type="checkbox" checked=isAdmin }}
27883
28246
  ```
27884
28247
 
28248
+
27885
28249
  ```html
27886
28250
  <input type="checkbox" checked="checked" />
27887
28251
  ```
27888
28252
 
27889
- ### Extension
28253
+ ## Extension
28254
+
27890
28255
  Internally, `{{input type="checkbox"}}` creates an instance of `Ember.Checkbox`, passing
27891
28256
  arguments from the helper to `Ember.Checkbox`'s `create` method. You can extend the
27892
28257
  capablilties of checkbox inputs in your applications by reopening this class. For example,
@@ -27898,6 +28263,7 @@ function normalizeHash(hash, hashTypes) {
27898
28263
  });
27899
28264
  ```
27900
28265
 
28266
+
27901
28267
  @method input
27902
28268
  @for Ember.Handlebars.helpers
27903
28269
  @param {Hash} options
@@ -27913,8 +28279,6 @@ Ember.Handlebars.registerHelper('input', function(options) {
27913
28279
  delete hash.type;
27914
28280
  delete hash.on;
27915
28281
 
27916
- normalizeHash(hash, types);
27917
-
27918
28282
  if (inputType === 'checkbox') {
27919
28283
  return Ember.Handlebars.helpers.view.call(this, Ember.Checkbox, options);
27920
28284
  } else {
@@ -28044,7 +28408,7 @@ Ember.Handlebars.registerHelper('input', function(options) {
28044
28408
  </textarea>
28045
28409
  ```
28046
28410
 
28047
- ### Extension
28411
+ ## Extension
28048
28412
 
28049
28413
  Internally, `{{textarea}}` creates an instance of `Ember.TextArea`, passing
28050
28414
  arguments from the helper to `Ember.TextArea`'s `create` method. You can
@@ -28061,6 +28425,12 @@ Ember.Handlebars.registerHelper('input', function(options) {
28061
28425
  });
28062
28426
  ```
28063
28427
 
28428
+ Keep in mind when writing `Ember.TextArea` subclasses that `Ember.TextArea`
28429
+ itself extends `Ember.Component`, meaning that it does NOT inherit
28430
+ the `controller` of the parent view.
28431
+
28432
+ See more about [Ember components](api/classes/Ember.Component.html)
28433
+
28064
28434
  @method textarea
28065
28435
  @for Ember.Handlebars.helpers
28066
28436
  @param {Hash} options
@@ -28071,7 +28441,6 @@ Ember.Handlebars.registerHelper('textarea', function(options) {
28071
28441
  var hash = options.hash,
28072
28442
  types = options.hashTypes;
28073
28443
 
28074
- normalizeHash(hash, types);
28075
28444
  return Ember.Handlebars.helpers.view.call(this, Ember.TextArea, options);
28076
28445
  });
28077
28446
 
@@ -28122,7 +28491,7 @@ Ember.Handlebars.bootstrap = function(ctx) {
28122
28491
 
28123
28492
  // Check if template of same name already exists
28124
28493
  if (Ember.TEMPLATES[templateName] !== undefined) {
28125
- throw new Error('Template named "' + templateName + '" already exists.');
28494
+ throw new Ember.Error('Template named "' + templateName + '" already exists.');
28126
28495
  }
28127
28496
 
28128
28497
  // For templates which have a name, we save them and then remove them from the DOM
@@ -28152,13 +28521,14 @@ function registerComponents(container) {
28152
28521
  function registerComponent(container, name) {
28153
28522
 
28154
28523
 
28155
- container.injection('component:' + name, 'layout', 'template:components/' + name);
28156
-
28157
28524
  var fullName = 'component:' + name;
28525
+
28526
+ container.injection(fullName, 'layout', 'template:components/' + name);
28527
+
28158
28528
  var Component = container.lookupFactory(fullName);
28159
28529
 
28160
28530
  if (!Component) {
28161
- container.register('component:' + name, Ember.Component);
28531
+ container.register(fullName, Ember.Component);
28162
28532
  Component = container.lookupFactory(fullName);
28163
28533
  }
28164
28534
 
@@ -30174,8 +30544,12 @@ Ember.Router = Ember.Object.extend({
30174
30544
 
30175
30545
  if (name === 'application') {
30176
30546
  // Inject default `error` handler.
30177
- handler.events = handler.events || {};
30178
- handler.events.error = handler.events.error || Ember.Router._defaultErrorHandler;
30547
+ // Note: `events` is deprecated, but we'll let the
30548
+ // deprecation warnings be handled at event-handling time rather
30549
+ // than duplicating that logic here.
30550
+ var actions = handler._actions || handler.events;
30551
+ if (!actions) { actions = handler._actions = {}; }
30552
+ actions.error = actions.error || Ember.Router._defaultErrorHandler;
30179
30553
  }
30180
30554
 
30181
30555
  handler.routeName = name;
@@ -30241,8 +30615,10 @@ Ember.Router = Ember.Object.extend({
30241
30615
 
30242
30616
  transitionPromise.then(function(route) {
30243
30617
  self._transitionCompleted(route);
30244
- }, function(error){
30618
+ }, function(error) {
30619
+ if (error.name === "UnrecognizedURLError") {
30245
30620
 
30621
+ }
30246
30622
  });
30247
30623
 
30248
30624
  // We want to return the configurable promise object
@@ -30288,7 +30664,7 @@ function triggerEvent(handlerInfos, ignoreFailure, args) {
30288
30664
 
30289
30665
  if (!handlerInfos) {
30290
30666
  if (ignoreFailure) { return; }
30291
- throw new Error("Could not trigger event '" + name + "'. There are no active handlers");
30667
+ throw new Ember.Error("Could not trigger event '" + name + "'. There are no active handlers");
30292
30668
  }
30293
30669
 
30294
30670
  var eventWasHandled = false;
@@ -30314,7 +30690,7 @@ function triggerEvent(handlerInfos, ignoreFailure, args) {
30314
30690
  }
30315
30691
 
30316
30692
  if (!eventWasHandled && !ignoreFailure) {
30317
- throw new Error("Nothing handled the event '" + name + "'.");
30693
+ throw new Ember.Error("Nothing handled the event '" + name + "'.");
30318
30694
  }
30319
30695
  }
30320
30696
 
@@ -30633,6 +31009,7 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
30633
31009
  @deprecated
30634
31010
 
30635
31011
  Please use `actions` instead.
31012
+ @method events
30636
31013
  */
30637
31014
  events: null,
30638
31015
 
@@ -30655,11 +31032,13 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
30655
31032
  activate: Ember.K,
30656
31033
 
30657
31034
  /**
30658
- Transition into another route. Optionally supply a model for the
30659
- route in question. The model will be serialized into the URL
30660
- using the `serialize` hook.
31035
+ Transition into another route. Optionally supply model(s) for the
31036
+ route in question. If multiple models are supplied they will be applied
31037
+ last to first recursively up the resource tree (see Multiple Models Example
31038
+ below). The model(s) will be serialized into the URL using the appropriate
31039
+ route's `serialize` hook. See also 'replaceWith'.
30661
31040
 
30662
- Example
31041
+ Simple Transition Example
30663
31042
 
30664
31043
  ```javascript
30665
31044
  App.Router.map(function() {
@@ -30680,9 +31059,31 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
30680
31059
  });
30681
31060
  ```
30682
31061
 
31062
+ Multiple Models Example
31063
+
31064
+ ```javascript
31065
+ App.Router.map(function() {
31066
+ this.route("index");
31067
+ this.resource('breakfast', {path:':breakfastId'}, function(){
31068
+ this.resource('cereal', {path: ':cerealId'});
31069
+ });
31070
+ });
31071
+
31072
+ App.IndexRoute = Ember.Route.extend({
31073
+ actions: {
31074
+ moveToChocolateCereal: function(){
31075
+ var cereal = { cerealId: "ChocolateYumminess"},
31076
+ breakfast = {breakfastId: "CerealAndMilk"};
31077
+
31078
+ this.transitionTo('cereal', breakfast, cereal);
31079
+ }
31080
+ }
31081
+ });
31082
+
30683
31083
  @method transitionTo
30684
31084
  @param {String} name the name of the route
30685
- @param {...Object} models
31085
+ @param {...Object} models the model(s) to be used while transitioning
31086
+ to the route.
30686
31087
  */
30687
31088
  transitionTo: function(name, context) {
30688
31089
  var router = this.router;
@@ -30690,8 +31091,10 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
30690
31091
  },
30691
31092
 
30692
31093
  /**
30693
- Transition into another route while replacing the current URL if
30694
- possible. Identical to `transitionTo` in all other respects.
31094
+ Transition into another route while replacing the current URL, if possible.
31095
+ This will replace the current history entry instead of adding a new one.
31096
+ Beside that, it is identical to `transitionTo` in all other respects. See
31097
+ 'transitionTo' for additional information regarding multiple models.
30695
31098
 
30696
31099
  Example
30697
31100
 
@@ -30712,7 +31115,8 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
30712
31115
 
30713
31116
  @method replaceWith
30714
31117
  @param {String} name the name of the route
30715
- @param {...Object} models
31118
+ @param {...Object} models the model(s) to be used while transitioning
31119
+ to the route.
30716
31120
  */
30717
31121
  replaceWith: function() {
30718
31122
  var router = this.router;
@@ -30791,15 +31195,15 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
30791
31195
  },
30792
31196
 
30793
31197
  /**
30794
- @deprecated
30795
-
30796
31198
  A hook you can implement to optionally redirect to another route.
30797
31199
 
30798
31200
  If you call `this.transitionTo` from inside of this hook, this route
30799
31201
  will not be entered in favor of the other hook.
30800
31202
 
30801
- This hook is deprecated in favor of using the `afterModel` hook
30802
- for performing redirects after the model has resolved.
31203
+ Note that this hook is called by the default implementation of
31204
+ `afterModel`, so if you override `afterModel`, you must either
31205
+ explicitly call `redirect` or just put your redirecting
31206
+ `this.transitionTo()` call within `afterModel`.
30803
31207
 
30804
31208
  @method redirect
30805
31209
  @param {Object} model the model for this route
@@ -30893,7 +31297,7 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
30893
31297
  resolved.
30894
31298
 
30895
31299
  ```js
30896
- App.PostRoute = Ember.Route.extend({
31300
+ App.PostsRoute = Ember.Route.extend({
30897
31301
  afterModel: function(posts, transition) {
30898
31302
  if (posts.length === 1) {
30899
31303
  this.transitionTo('post.show', posts[0]);
@@ -31809,6 +32213,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
31809
32213
 
31810
32214
  This method is invoked by observers installed during `init` that fire
31811
32215
  whenever the helpers
32216
+ @method _paramsChanged
31812
32217
  */
31813
32218
  _paramsChanged: function() {
31814
32219
  this.notifyPropertyChange('resolvedParams');
@@ -31981,7 +32386,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
31981
32386
  @property href
31982
32387
  **/
31983
32388
  href: Ember.computed(function() {
31984
- if (get(this, 'tagName') !== 'a') { return false; }
32389
+ if (get(this, 'tagName') !== 'a') { return; }
31985
32390
 
31986
32391
  var router = get(this, 'router'),
31987
32392
  routeArgs = get(this, 'routeArgs');
@@ -32040,7 +32445,44 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32040
32445
 
32041
32446
  To override this option for your entire application, see
32042
32447
  "Overriding Application-wide Defaults".
32043
-
32448
+
32449
+ ### Disabling the `link-to` helper
32450
+ By default `{{link-to}}` is enabled.
32451
+ any passed value to `disabled` helper property will disable the `link-to` helper.
32452
+
32453
+ static use: the `disabled` option:
32454
+
32455
+ ```handlebars
32456
+ {{#link-to 'photoGallery' disabled=true}}
32457
+ Great Hamster Photos
32458
+ {{/link-to}}
32459
+ ```
32460
+
32461
+ dynamic use: the `disabledWhen` option:
32462
+
32463
+ ```handlebars
32464
+ {{#link-to 'photoGallery' disabledWhen=controller.someProperty}}
32465
+ Great Hamster Photos
32466
+ {{/link-to}}
32467
+ ```
32468
+
32469
+ any passed value to `disabled` will disable it except `undefined`.
32470
+ to ensure that only `true` disable the `link-to` helper you can
32471
+ override the global behaviour of `Ember.LinkView`.
32472
+
32473
+ ```javascript
32474
+ Ember.LinkView.reopen({
32475
+ disabled: Ember.computed(function(key, value) {
32476
+ if (value !== undefined) {
32477
+ this.set('_isDisabled', value === true);
32478
+ }
32479
+ return value === true ? get(this, 'disabledClass') : false;
32480
+ })
32481
+ });
32482
+ ```
32483
+
32484
+ see "Overriding Application-wide Defaults" for more.
32485
+
32044
32486
  ### Handling `href`
32045
32487
  `{{link-to}}` will use your application's Router to
32046
32488
  fill the element's `href` property with a url that
@@ -32096,7 +32538,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32096
32538
  ```javascript
32097
32539
  App.Router.map(function() {
32098
32540
  this.resource("photoGallery", {path: "hamster-photos/:photo_id"});
32099
- })
32541
+ });
32100
32542
  ```
32101
32543
 
32102
32544
  ```handlebars
@@ -32138,6 +32580,34 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32138
32580
  A+++ would snuggle again.
32139
32581
  </a>
32140
32582
  ```
32583
+
32584
+ ### Supplying an explicit dynamic segment value
32585
+ If you don't have a model object available to pass to `{{link-to}}`,
32586
+ an optional string or integer argument can be passed for routes whose
32587
+ paths contain dynamic segments. This argument will become the value
32588
+ of the dynamic segment:
32589
+
32590
+ ```javascript
32591
+ App.Router.map(function() {
32592
+ this.resource("photoGallery", {path: "hamster-photos/:photo_id"});
32593
+ });
32594
+ ```
32595
+
32596
+ ```handlebars
32597
+ {{#link-to 'photoGallery' aPhotoId}}
32598
+ {{aPhoto.title}}
32599
+ {{/link-to}}
32600
+ ```
32601
+
32602
+ ```html
32603
+ <a href="/hamster-photos/42">
32604
+ Tomster
32605
+ </a>
32606
+ ```
32607
+
32608
+ When transitioning into the linked route, the `model` hook will
32609
+ be triggered with parameters including this passed identifier.
32610
+
32141
32611
  ### Overriding attributes
32142
32612
  You can override any given property of the Ember.LinkView
32143
32613
  that is generated by the `{{link-to}}` helper by passing
@@ -32147,8 +32617,9 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32147
32617
  {{#link-to aPhoto tagName='li' title='Following this link will change your life' classNames=['pic', 'sweet']}}
32148
32618
  Uh-mazing!
32149
32619
  {{/link-to}}
32620
+ ```
32150
32621
 
32151
- See {{#crossLink "Ember.LinkView"}}{{/crossLink}} for a
32622
+ See [Ember.LinkView](/api/classes/Ember.LinkView.html) for a
32152
32623
  complete list of overrideable properties. Be sure to also
32153
32624
  check out inherited properties of `LinkView`.
32154
32625
 
@@ -32178,7 +32649,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32178
32649
  @for Ember.Handlebars.helpers
32179
32650
  @param {String} routeName
32180
32651
  @param {Object} [context]*
32181
- @param [options] {Object} Handlebars key/value pairs of options, you can over-ride any property of {{#crossLink "Ember.LinkView"}}{{/crossLink}}
32652
+ @param [options] {Object} Handlebars key/value pairs of options, you can override any property of Ember.LinkView
32182
32653
  @return {String} HTML string
32183
32654
  @see {Ember.LinkView}
32184
32655
  */
@@ -32199,7 +32670,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32199
32670
  });
32200
32671
 
32201
32672
  /**
32202
- See `link-to`
32673
+ See [link-to](/api/classes/Ember.Handlebars.helpers.html#method_link-to)
32203
32674
 
32204
32675
  @method linkTo
32205
32676
  @for Ember.Handlebars.helpers
@@ -32344,7 +32815,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32344
32815
  Example:
32345
32816
 
32346
32817
  ```javascript
32347
- App.NavigationController = Ember.Controller.extned({
32818
+ App.NavigationController = Ember.Controller.extend({
32348
32819
  who: "world"
32349
32820
  });
32350
32821
  ```
@@ -32502,6 +32973,10 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32502
32973
  return isSimpleClick(event);
32503
32974
  }
32504
32975
 
32976
+ if (allowedKeys.indexOf("any") >= 0) {
32977
+ return true;
32978
+ }
32979
+
32505
32980
  var allowed = true;
32506
32981
 
32507
32982
  forEach.call(keys, function(key) {
@@ -32555,16 +33030,16 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32555
33030
 
32556
33031
  /**
32557
33032
  The `{{action}}` helper registers an HTML element within a template for DOM
32558
- event handling and forwards that interaction to the view's controller
33033
+ event handling and forwards that interaction to the templates's controller
32559
33034
  or supplied `target` option (see 'Specifying a Target').
32560
33035
 
32561
- If the view's controller does not implement the event, the event is sent
33036
+ If the controller does not implement the event, the event is sent
32562
33037
  to the current route, and it bubbles up the route hierarchy from there.
32563
33038
 
32564
33039
  User interaction with that element will invoke the supplied action name on
32565
33040
  the appropriate target.
32566
33041
 
32567
- Given the following Handlebars template on the page
33042
+ Given the following application Handlebars template on the page
32568
33043
 
32569
33044
  ```handlebars
32570
33045
  <div {{action 'anActionName'}}>
@@ -32575,17 +33050,13 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32575
33050
  And application code
32576
33051
 
32577
33052
  ```javascript
32578
- AController = Ember.Controller.extend({
32579
- anActionName: function() {}
32580
- });
32581
-
32582
- AView = Ember.View.extend({
32583
- controller: AController.create(),
32584
- templateName: 'a-template'
33053
+ App.ApplicationController = Ember.Controller.extend({
33054
+ actions: {
33055
+ anActionName: function() {
33056
+
33057
+ }
33058
+ }
32585
33059
  });
32586
-
32587
- aView = AView.create();
32588
- aView.appendTo('body');
32589
33060
  ```
32590
33061
 
32591
33062
  Will result in the following rendered HTML
@@ -32598,8 +33069,8 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32598
33069
  </div>
32599
33070
  ```
32600
33071
 
32601
- Clicking "click me" will trigger the `anActionName` method of the
32602
- `AController`. In this case, no additional parameters will be passed.
33072
+ Clicking "click me" will trigger the `anActionName` action of the
33073
+ `App.ApplicationController`. In this case, no additional parameters will be passed.
32603
33074
 
32604
33075
  If you provide additional parameters to the helper:
32605
33076
 
@@ -32632,11 +33103,9 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32632
33103
  supply an `on` option to the helper to specify a different DOM event name:
32633
33104
 
32634
33105
  ```handlebars
32635
- <script type="text/x-handlebars" data-template-name='a-template'>
32636
- <div {{action 'anActionName' on="doubleClick"}}>
32637
- click me
32638
- </div>
32639
- </script>
33106
+ <div {{action "anActionName" on="doubleClick"}}>
33107
+ click me
33108
+ </div>
32640
33109
  ```
32641
33110
 
32642
33111
  See `Ember.View` 'Responding to Browser Events' for a list of
@@ -32654,15 +33123,21 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32654
33123
  keys. You can supply an `allowedKeys` option to specify which keys should not be ignored.
32655
33124
 
32656
33125
  ```handlebars
32657
- <script type="text/x-handlebars" data-template-name='a-template'>
32658
- <div {{action 'anActionName' allowedKeys="alt"}}>
32659
- click me
32660
- </div>
32661
- </script>
33126
+ <div {{action "anActionName" allowedKeys="alt"}}>
33127
+ click me
33128
+ </div>
32662
33129
  ```
32663
33130
 
32664
33131
  This way the `{{action}}` will fire when clicking with the alt key pressed down.
32665
33132
 
33133
+ Alternatively, supply "any" to the `allowedKeys` option to accept any combination of modifier keys.
33134
+
33135
+ ```handlebars
33136
+ <div {{action "anActionName" allowedKeys="any"}}>
33137
+ click me with any key pressed
33138
+ </div>
33139
+ ```
33140
+
32666
33141
  ### Specifying a Target
32667
33142
 
32668
33143
  There are several possible target objects for `{{action}}` helpers:
@@ -32676,43 +33151,21 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32676
33151
  to an object, accessible in the current context:
32677
33152
 
32678
33153
  ```handlebars
32679
- <script type="text/x-handlebars" data-template-name='a-template'>
32680
- <div {{action 'anActionName' target="MyApplication.someObject"}}>
32681
- click me
32682
- </div>
32683
- </script>
32684
- ```
32685
-
32686
- Clicking "click me" in the rendered HTML of the above template will trigger
32687
- the `anActionName` method of the object at `MyApplication.someObject`.
32688
-
32689
- If an action's target does not implement a method that matches the supplied
32690
- action name an error will be thrown.
32691
-
32692
- ```handlebars
32693
- <script type="text/x-handlebars" data-template-name='a-template'>
32694
- <div {{action 'aMethodNameThatIsMissing'}}>
32695
- click me
32696
- </div>
32697
- </script>
33154
+ {{! the application template }}
33155
+ <div {{action "anActionName" target=view}}>
33156
+ click me
33157
+ </div>
32698
33158
  ```
32699
33159
 
32700
- With the following application code
32701
-
32702
33160
  ```javascript
32703
- AView = Ember.View.extend({
32704
- templateName; 'a-template',
32705
- // note: no method 'aMethodNameThatIsMissing'
32706
- anActionName: function(event) {}
33161
+ App.ApplicationView = Ember.View.extend({
33162
+ actions: {
33163
+ anActionName: function(){}
33164
+ }
32707
33165
  });
32708
33166
 
32709
- aView = AView.create();
32710
- aView.appendTo('body');
32711
33167
  ```
32712
33168
 
32713
- Will throw `Uncaught TypeError: Cannot call method 'call' of undefined` when
32714
- "click me" is clicked.
32715
-
32716
33169
  ### Additional Parameters
32717
33170
 
32718
33171
  You may specify additional parameters to the `{{action}}` helper. These
@@ -32720,17 +33173,15 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
32720
33173
  implementing the action.
32721
33174
 
32722
33175
  ```handlebars
32723
- <script type="text/x-handlebars" data-template-name='a-template'>
32724
- {{#each person in people}}
32725
- <div {{action 'edit' person}}>
32726
- click me
32727
- </div>
32728
- {{/each}}
32729
- </script>
33176
+ {{#each person in people}}
33177
+ <div {{action "edit" person}}>
33178
+ click me
33179
+ </div>
33180
+ {{/each}}
32730
33181
  ```
32731
33182
 
32732
- Clicking "click me" will trigger the `edit` method on the current view's
32733
- controller with the current person as a parameter.
33183
+ Clicking "click me" will trigger the `edit` method on the current controller
33184
+ with the value of `person` as a parameter.
32734
33185
 
32735
33186
  @method action
32736
33187
  @for Ember.Handlebars.helpers
@@ -32914,8 +33365,23 @@ Ember.ControllerMixin.reopen({
32914
33365
  aController.transitionToRoute('blogPost', aPost);
32915
33366
  ```
32916
33367
 
33368
+ Multiple models will be applied last to first recursively up the
33369
+ resource tree.
33370
+
33371
+ ```javascript
33372
+
33373
+ this.resource('blogPost', {path:':blogPostId'}, function(){
33374
+ this.resource('blogComment', {path: ':blogCommentId'});
33375
+ });
33376
+
33377
+ aController.transitionToRoute('blogComment', aPost, aComment);
33378
+ ```
33379
+
33380
+ See also 'replaceRoute'.
33381
+
32917
33382
  @param {String} name the name of the route
32918
- @param {...Object} models the
33383
+ @param {...Object} models the model(s) to be used while transitioning
33384
+ to the route.
32919
33385
  @for Ember.ControllerMixin
32920
33386
  @method transitionToRoute
32921
33387
  */
@@ -32937,8 +33403,9 @@ Ember.ControllerMixin.reopen({
32937
33403
  },
32938
33404
 
32939
33405
  /**
32940
- Alernative to `transitionToRoute`. Transition the application into another route. The route may
32941
- be either a single route or route path:
33406
+ Transition into another route while replacing the current URL, if possible.
33407
+ This will replace the current history entry instead of adding a new one.
33408
+ Beside that, it is identical to `transitionToRoute` in all other respects.
32942
33409
 
32943
33410
  ```javascript
32944
33411
  aController.replaceRoute('blogPosts');
@@ -32953,8 +33420,21 @@ Ember.ControllerMixin.reopen({
32953
33420
  aController.replaceRoute('blogPost', aPost);
32954
33421
  ```
32955
33422
 
33423
+ Multiple models will be applied last to first recursively up the
33424
+ resource tree.
33425
+
33426
+ ```javascript
33427
+
33428
+ this.resource('blogPost', {path:':blogPostId'}, function(){
33429
+ this.resource('blogComment', {path: ':blogCommentId'});
33430
+ });
33431
+
33432
+ aController.replaceRoute('blogComment', aPost, aComment);
33433
+ ```
33434
+
32956
33435
  @param {String} name the name of the route
32957
- @param {...Object} models the
33436
+ @param {...Object} models the model(s) to be used while transitioning
33437
+ to the route.
32958
33438
  @for Ember.ControllerMixin
32959
33439
  @method replaceRoute
32960
33440
  */
@@ -33757,7 +34237,7 @@ DAG.prototype.addEdge = function(fromName, toName) {
33757
34237
  }
33758
34238
  function checkCycle(vertex, path) {
33759
34239
  if (vertex.name === toName) {
33760
- throw new Error("cycle detected: " + toName + " <- " + path.join(" <- "));
34240
+ throw new Ember.Error("cycle detected: " + toName + " <- " + path.join(" <- "));
33761
34241
  }
33762
34242
  }
33763
34243
  visit(from, checkCycle);
@@ -33825,11 +34305,11 @@ var get = Ember.get,
33825
34305
  container lookups before consulting the container for registered
33826
34306
  items:
33827
34307
 
33828
- * templates are looked up on `Ember.TEMPLATES`
33829
- * other names are looked up on the application after converting
33830
- the name. For example, `controller:post` looks up
33831
- `App.PostController` by default.
33832
- * there are some nuances (see examples below)
34308
+ * templates are looked up on `Ember.TEMPLATES`
34309
+ * other names are looked up on the application after converting
34310
+ the name. For example, `controller:post` looks up
34311
+ `App.PostController` by default.
34312
+ * there are some nuances (see examples below)
33833
34313
 
33834
34314
  ### How Resolving Works
33835
34315
 
@@ -34195,16 +34675,15 @@ DeprecatedContainer.prototype = {
34195
34675
  example, the `keypress` event causes the `keyPress` method on the view to be
34196
34676
  called, the `dblclick` event causes `doubleClick` to be called, and so on.
34197
34677
 
34198
- If there is a browser event that Ember does not listen for by default, you
34199
- can specify custom events and their corresponding view method names by
34200
- setting the application's `customEvents` property:
34678
+ If there is a bubbling browser event that Ember does not listen for by
34679
+ default, you can specify custom events and their corresponding view method
34680
+ names by setting the application's `customEvents` property:
34201
34681
 
34202
34682
  ```javascript
34203
34683
  App = Ember.Application.create({
34204
34684
  customEvents: {
34205
- // add support for the loadedmetadata media
34206
- // player event
34207
- 'loadedmetadata': "loadedMetadata"
34685
+ // add support for the paste event
34686
+ 'paste: "paste"
34208
34687
  }
34209
34688
  });
34210
34689
  ```
@@ -34317,7 +34796,7 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
34317
34796
  `keyup`, and delegates them to your application's `Ember.View`
34318
34797
  instances.
34319
34798
 
34320
- If you would like additional events to be delegated to your
34799
+ If you would like additional bubbling events to be delegated to your
34321
34800
  views, set your `Ember.Application`'s `customEvents` property
34322
34801
  to a hash containing the DOM event name as the key and the
34323
34802
  corresponding view method name as the value. For example:
@@ -34325,9 +34804,8 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
34325
34804
  ```javascript
34326
34805
  App = Ember.Application.create({
34327
34806
  customEvents: {
34328
- // add support for the loadedmetadata media
34329
- // player event
34330
- 'loadedmetadata': "loadedMetadata"
34807
+ // add support for the paste event
34808
+ 'paste: "paste"
34331
34809
  }
34332
34810
  });
34333
34811
  ```
@@ -34353,12 +34831,17 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
34353
34831
 
34354
34832
  this.scheduleInitialize();
34355
34833
 
34356
- if (Ember.LOG_VERSION) {
34357
- Ember.LOG_VERSION = false; // we only need to see this once per Application#init
34358
-
34834
+ Ember.libraries.registerCoreLibrary('Handlebars', Ember.Handlebars.VERSION);
34835
+ Ember.libraries.registerCoreLibrary('jQuery', Ember.$().jquery);
34359
34836
 
34837
+ if ( Ember.LOG_VERSION ) {
34838
+ Ember.LOG_VERSION = false; // we only need to see this once per Application#init
34839
+ var maxNameLength = Math.max.apply(this, Ember.A(Ember.libraries).mapBy("name.length"));
34360
34840
 
34841
+ Ember.libraries.each(function(name, version) {
34842
+ var spaces = new Array(maxNameLength - name.length + 1).join(" ");
34361
34843
 
34844
+ });
34362
34845
 
34363
34846
  }
34364
34847
  },
@@ -34492,19 +34975,20 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
34492
34975
  ```javascript
34493
34976
  App = Ember.Application.create();
34494
34977
 
34495
- App.Person = Ember.Object.extend({});
34496
- App.Orange = Ember.Object.extend({});
34497
- App.Email = Ember.Object.extend({});
34978
+ App.Person = Ember.Object.extend({});
34979
+ App.Orange = Ember.Object.extend({});
34980
+ App.Email = Ember.Object.extend({});
34981
+ App.Session = Ember.Object.create({});
34498
34982
 
34499
34983
  App.register('model:user', App.Person, {singleton: false });
34500
34984
  App.register('fruit:favorite', App.Orange);
34501
34985
  App.register('communication:main', App.Email, {singleton: false});
34986
+ App.register('session', App.Session, {instantiate: false});
34502
34987
  ```
34503
34988
 
34504
34989
  @method register
34505
- @param type {String}
34506
- @param name {String}
34507
- @param factory {String}
34990
+ @param fullName {String} type:name (e.g., 'model:user')
34991
+ @param factory {Function} (e.g., App.Person)
34508
34992
  @param options {String} (optional)
34509
34993
  **/
34510
34994
  register: function() {
@@ -34561,7 +35045,9 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
34561
35045
  if (this.isDestroyed) { return; }
34562
35046
 
34563
35047
  // At this point, the App.Router must already be assigned
34564
- this.register('router:main', this.Router);
35048
+ if (this.Router) {
35049
+ this.register('router:main', this.Router);
35050
+ }
34565
35051
 
34566
35052
  this.runInitializers();
34567
35053
  Ember.runLoadHooks('application', this);
@@ -34671,10 +35157,10 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
34671
35157
  container = this.__container__,
34672
35158
  graph = new Ember.DAG(),
34673
35159
  namespace = this,
34674
- i, initializer;
35160
+ name, initializer;
34675
35161
 
34676
- for (i=0; i<initializers.length; i++) {
34677
- initializer = initializers[i];
35162
+ for (name in initializers) {
35163
+ initializer = initializers[name];
34678
35164
  graph.addEdges(initializer.name, initializer.initialize, initializer.before, initializer.after);
34679
35165
  }
34680
35166
 
@@ -34724,8 +35210,8 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
34724
35210
  /**
34725
35211
  @private
34726
35212
 
34727
- If the application has a router, use it to route to the current URL, and
34728
35213
  trigger a new call to `route` whenever the URL changes.
35214
+ If the application has a router, use it to route to the current URL, and
34729
35215
 
34730
35216
  @method startRouting
34731
35217
  @property router {Ember.Router}
@@ -34752,10 +35238,10 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
34752
35238
  ready: Ember.K,
34753
35239
 
34754
35240
  /**
34755
-
34756
35241
  @deprecated Use 'Resolver' instead
34757
35242
  Set this to provide an alternate class to `Ember.DefaultResolver`
34758
35243
 
35244
+
34759
35245
  @property resolver
34760
35246
  */
34761
35247
  resolver: null,
@@ -34779,15 +35265,22 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
34779
35265
  });
34780
35266
 
34781
35267
  Ember.Application.reopenClass({
34782
- concatenatedProperties: ['initializers'],
34783
- initializers: Ember.A(),
35268
+ initializers: {},
34784
35269
  initializer: function(initializer) {
34785
- var initializers = get(this, 'initializers');
35270
+ // If this is the first initializer being added to a subclass, we are going to reopen the class
35271
+ // to make sure we have a new `initializers` object, which extends from the parent class' using
35272
+ // prototypal inheritance. Without this, attempting to add initializers to the subclass would
35273
+ // pollute the parent class as well as other subclasses.
35274
+ if (this.superclass.initializers !== undefined && this.superclass.initializers === this.initializers) {
35275
+ this.reopenClass({
35276
+ initializers: Ember.create(this.initializers)
35277
+ });
35278
+ }
34786
35279
 
34787
35280
 
34788
35281
 
34789
35282
 
34790
- initializers.push(initializer);
35283
+ this.initializers[initializer.name] = initializer;
34791
35284
  },
34792
35285
 
34793
35286
  /**
@@ -34976,6 +35469,8 @@ Ember.ControllerMixin.reopen({
34976
35469
  length = get(needs, 'length');
34977
35470
 
34978
35471
  if (length > 0) {
35472
+
35473
+
34979
35474
  verifyNeedsDependencies(this, this.container, needs);
34980
35475
 
34981
35476
  // if needs then initialize controllers proxy
@@ -34985,6 +35480,11 @@ Ember.ControllerMixin.reopen({
34985
35480
  this._super.apply(this, arguments);
34986
35481
  },
34987
35482
 
35483
+ /**
35484
+ @method controllerFor
35485
+ @see {Ember.Route#controllerFor}
35486
+ @deprecated Use `needs` instead
35487
+ */
34988
35488
  controllerFor: function(controllerName) {
34989
35489
 
34990
35490
  return Ember.controllerFor(get(this, 'container'), controllerName);