ember-source 2.1.0.beta.1 → 2.1.0.beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6f9cb78ab289bef4b21a2365d166d7183872d41d
4
- data.tar.gz: 17f6a12bf1ece2899c2bbc3356b6e00a2214f404
3
+ metadata.gz: f2284a5b71f00658d9db7799a1e917e600f5045b
4
+ data.tar.gz: b7cf04882c51e5e4ef9aa0f356427c2dd102aeee
5
5
  SHA512:
6
- metadata.gz: 2bac0642a221c467d6ebe10378e638fa41d3cac939792ecfd8ff7dd6d6fb18fe2a20f5f393459be9a3112a6bd04b78f118c0d977e682c9caee3fb4bd82f11b59
7
- data.tar.gz: edd837b7f89eabbc82ff5333bc47b28e29350780c4bbba77a93a4aa653103be018852703cbd64f34a287cc798d6b07ed673f50478d36a528020fb0e695e2d648
6
+ metadata.gz: 7463bcbdf2343c68bf167edf5b47a1296688914010e83e125201f46c47a26c2cc67aec80cf7f2219f2534b25790af50f48f52c1b4f86b0d89cba9aa16b7b1ac9
7
+ data.tar.gz: ffa2f4f6dcc0a4be0ac41f1a462989d4764d66aab2d3fe1dc1816ec3455b8967442b371e45cbf9e38ccad4e398afa374100d3fe0fb3e7b386fb6d634e1b360ae
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.1.0-beta.1
1
+ 2.1.0-beta.3
@@ -5,7 +5,7 @@
5
5
  * Portions Copyright 2008-2011 Apple Inc. All rights reserved.
6
6
  * @license Licensed under MIT license
7
7
  * See https://raw.github.com/emberjs/ember.js/master/LICENSE
8
- * @version 2.1.0-beta.1
8
+ * @version 2.1.0-beta.3
9
9
  */
10
10
 
11
11
  (function() {
@@ -2897,1303 +2897,1314 @@ enifed('ember-metal/chains', ['exports', 'ember-metal/core', 'ember-metal/proper
2897
2897
  exports.ChainNode = ChainNode;
2898
2898
  });
2899
2899
  // warn, assert, etc;
2900
- enifed('ember-metal/computed', ['exports', 'ember-metal/core', 'ember-metal/property_set', 'ember-metal/utils', 'ember-metal/meta', 'ember-metal/expand_properties', 'ember-metal/error', 'ember-metal/properties', 'ember-metal/property_events', 'ember-metal/dependent_keys'], function (exports, _emberMetalCore, _emberMetalProperty_set, _emberMetalUtils, _emberMetalMeta, _emberMetalExpand_properties, _emberMetalError, _emberMetalProperties, _emberMetalProperty_events, _emberMetalDependent_keys) {
2900
+ enifed('ember-metal/computed_macros', ['exports', 'ember-metal/core', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/computed', 'ember-metal/is_empty', 'ember-metal/is_none', 'ember-metal/alias'], function (exports, _emberMetalCore, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalComputed, _emberMetalIs_empty, _emberMetalIs_none, _emberMetalAlias) {
2901
2901
  'use strict';
2902
2902
 
2903
- exports.default = computed;
2903
+ exports.empty = empty;
2904
+ exports.notEmpty = notEmpty;
2905
+ exports.none = none;
2906
+ exports.not = not;
2907
+ exports.bool = bool;
2908
+ exports.match = match;
2909
+ exports.equal = equal;
2910
+ exports.gt = gt;
2911
+ exports.gte = gte;
2912
+ exports.lt = lt;
2913
+ exports.lte = lte;
2914
+ exports.oneWay = oneWay;
2915
+ exports.readOnly = readOnly;
2916
+ exports.deprecatingAlias = deprecatingAlias;
2904
2917
 
2905
2918
  /**
2906
2919
  @module ember
2907
2920
  @submodule ember-metal
2908
2921
  */
2909
2922
 
2910
- var metaFor = _emberMetalMeta.meta;
2923
+ function getProperties(self, propertyNames) {
2924
+ var ret = {};
2925
+ for (var i = 0; i < propertyNames.length; i++) {
2926
+ ret[propertyNames[i]] = _emberMetalProperty_get.get(self, propertyNames[i]);
2927
+ }
2928
+ return ret;
2929
+ }
2911
2930
 
2912
- function UNDEFINED() {}
2931
+ function generateComputedWithProperties(macro) {
2932
+ return function () {
2933
+ for (var _len = arguments.length, properties = Array(_len), _key = 0; _key < _len; _key++) {
2934
+ properties[_key] = arguments[_key];
2935
+ }
2913
2936
 
2914
- // ..........................................................
2915
- // COMPUTED PROPERTY
2916
- //
2937
+ var computedFunc = _emberMetalComputed.computed(function () {
2938
+ return macro.apply(this, [getProperties(this, properties)]);
2939
+ });
2940
+
2941
+ return computedFunc.property.apply(computedFunc, properties);
2942
+ };
2943
+ }
2917
2944
 
2918
2945
  /**
2919
- A computed property transforms an object's function into a property.
2920
-
2921
- By default the function backing the computed property will only be called
2922
- once and the result will be cached. You can specify various properties
2923
- that your computed property depends on. This will force the cached
2924
- result to be recomputed if the dependencies are modified.
2946
+ A computed property that returns true if the value of the dependent
2947
+ property is null, an empty string, empty array, or empty function.
2925
2948
 
2926
- In the following example we declare a computed property (by calling
2927
- `.property()` on the fullName function) and setup the property
2928
- dependencies (depending on firstName and lastName). The fullName function
2929
- will be called once (regardless of how many times it is accessed) as long
2930
- as its dependencies have not changed. Once firstName or lastName are updated
2931
- any future calls (or anything bound) to fullName will incorporate the new
2932
- values.
2949
+ Example
2933
2950
 
2934
2951
  ```javascript
2935
- var Person = Ember.Object.extend({
2936
- // these will be supplied by `create`
2937
- firstName: null,
2938
- lastName: null,
2939
-
2940
- fullName: function() {
2941
- var firstName = this.get('firstName');
2942
- var lastName = this.get('lastName');
2943
-
2944
- return firstName + ' ' + lastName;
2945
- }.property('firstName', 'lastName')
2952
+ var ToDoList = Ember.Object.extend({
2953
+ isDone: Ember.computed.empty('todos')
2946
2954
  });
2947
2955
 
2948
- var tom = Person.create({
2949
- firstName: 'Tom',
2950
- lastName: 'Dale'
2956
+ var todoList = ToDoList.create({
2957
+ todos: ['Unit Test', 'Documentation', 'Release']
2951
2958
  });
2952
2959
 
2953
- tom.get('fullName') // 'Tom Dale'
2960
+ todoList.get('isDone'); // false
2961
+ todoList.get('todos').clear();
2962
+ todoList.get('isDone'); // true
2954
2963
  ```
2955
2964
 
2956
- You can also define what Ember should do when setting a computed property.
2957
- If you try to set a computed property, it will be invoked with the key and
2958
- value you want to set it to. You can also accept the previous value as the
2959
- third parameter.
2960
-
2961
- ```javascript
2962
- var Person = Ember.Object.extend({
2963
- // these will be supplied by `create`
2964
- firstName: null,
2965
- lastName: null,
2966
-
2967
- fullName: function(key, value, oldValue) {
2968
- // getter
2969
- if (arguments.length === 1) {
2970
- var firstName = this.get('firstName');
2971
- var lastName = this.get('lastName');
2972
-
2973
- return firstName + ' ' + lastName;
2974
-
2975
- // setter
2976
- } else {
2977
- var name = value.split(' ');
2965
+ @since 1.6.0
2966
+ @method empty
2967
+ @for Ember.computed
2968
+ @param {String} dependentKey
2969
+ @return {Ember.ComputedProperty} computed property which negate
2970
+ the original value for property
2971
+ @public
2972
+ */
2973
+
2974
+ function empty(dependentKey) {
2975
+ return _emberMetalComputed.computed(dependentKey + '.length', function () {
2976
+ return _emberMetalIs_empty.default(_emberMetalProperty_get.get(this, dependentKey));
2977
+ });
2978
+ }
2979
+
2980
+ /**
2981
+ A computed property that returns true if the value of the dependent
2982
+ property is NOT null, an empty string, empty array, or empty function.
2978
2983
 
2979
- this.set('firstName', name[0]);
2980
- this.set('lastName', name[1]);
2984
+ Example
2981
2985
 
2982
- return value;
2983
- }
2984
- }.property('firstName', 'lastName')
2986
+ ```javascript
2987
+ var Hamster = Ember.Object.extend({
2988
+ hasStuff: Ember.computed.notEmpty('backpack')
2985
2989
  });
2986
2990
 
2987
- var person = Person.create();
2991
+ var hamster = Hamster.create({ backpack: ['Food', 'Sleeping Bag', 'Tent'] });
2988
2992
 
2989
- person.set('fullName', 'Peter Wagenet');
2990
- person.get('firstName'); // 'Peter'
2991
- person.get('lastName'); // 'Wagenet'
2993
+ hamster.get('hasStuff'); // true
2994
+ hamster.get('backpack').clear(); // []
2995
+ hamster.get('hasStuff'); // false
2992
2996
  ```
2993
2997
 
2994
- @class ComputedProperty
2995
- @namespace Ember
2996
- @constructor
2998
+ @method notEmpty
2999
+ @for Ember.computed
3000
+ @param {String} dependentKey
3001
+ @return {Ember.ComputedProperty} computed property which returns true if
3002
+ original value for property is not empty.
2997
3003
  @public
2998
3004
  */
2999
- function ComputedProperty(config, opts) {
3000
- this.isDescriptor = true;
3001
- if (typeof config === 'function') {
3002
- this._getter = config;
3003
- } else {
3004
- this._getter = config.get;
3005
- this._setter = config.set;
3006
- }
3007
- this._dependentKeys = undefined;
3008
- this._suspended = undefined;
3009
- this._meta = undefined;
3010
- this._volatile = false;
3011
- this._dependentKeys = opts && opts.dependentKeys;
3012
- this._readOnly = false;
3013
- }
3014
-
3015
- ComputedProperty.prototype = new _emberMetalProperties.Descriptor();
3016
3005
 
3017
- var ComputedPropertyPrototype = ComputedProperty.prototype;
3006
+ function notEmpty(dependentKey) {
3007
+ return _emberMetalComputed.computed(dependentKey + '.length', function () {
3008
+ return !_emberMetalIs_empty.default(_emberMetalProperty_get.get(this, dependentKey));
3009
+ });
3010
+ }
3018
3011
 
3019
3012
  /**
3020
- Call on a computed property to set it into non-cached mode. When in this
3021
- mode the computed property will not automatically cache the return value.
3022
-
3023
- It also does not automatically fire any change events. You must manually notify
3024
- any changes if you want to observe this property.
3013
+ A computed property that returns true if the value of the dependent
3014
+ property is null or undefined. This avoids errors from JSLint complaining
3015
+ about use of ==, which can be technically confusing.
3025
3016
 
3026
- Dependency keys have no effect on volatile properties as they are for cache
3027
- invalidation and notification when cached value is invalidated.
3017
+ Example
3028
3018
 
3029
3019
  ```javascript
3030
- var outsideService = Ember.Object.extend({
3031
- value: function() {
3032
- return OutsideService.getValue();
3033
- }.property().volatile()
3034
- }).create();
3020
+ var Hamster = Ember.Object.extend({
3021
+ isHungry: Ember.computed.none('food')
3022
+ });
3023
+
3024
+ var hamster = Hamster.create();
3025
+
3026
+ hamster.get('isHungry'); // true
3027
+ hamster.set('food', 'Banana');
3028
+ hamster.get('isHungry'); // false
3029
+ hamster.set('food', null);
3030
+ hamster.get('isHungry'); // true
3035
3031
  ```
3036
3032
 
3037
- @method volatile
3038
- @return {Ember.ComputedProperty} this
3039
- @chainable
3033
+ @method none
3034
+ @for Ember.computed
3035
+ @param {String} dependentKey
3036
+ @return {Ember.ComputedProperty} computed property which
3037
+ returns true if original value for property is null or undefined.
3040
3038
  @public
3041
3039
  */
3042
- ComputedPropertyPrototype.volatile = function () {
3043
- this._volatile = true;
3044
- return this;
3045
- };
3040
+
3041
+ function none(dependentKey) {
3042
+ return _emberMetalComputed.computed(dependentKey, function () {
3043
+ return _emberMetalIs_none.default(_emberMetalProperty_get.get(this, dependentKey));
3044
+ });
3045
+ }
3046
3046
 
3047
3047
  /**
3048
- Call on a computed property to set it into read-only mode. When in this
3049
- mode the computed property will throw an error when set.
3048
+ A computed property that returns the inverse boolean value
3049
+ of the original value for the dependent property.
3050
+
3051
+ Example
3050
3052
 
3051
3053
  ```javascript
3052
- var Person = Ember.Object.extend({
3053
- guid: function() {
3054
- return 'guid-guid-guid';
3055
- }.property().readOnly()
3054
+ var User = Ember.Object.extend({
3055
+ isAnonymous: Ember.computed.not('loggedIn')
3056
3056
  });
3057
3057
 
3058
- var person = Person.create();
3058
+ var user = User.create({loggedIn: false});
3059
3059
 
3060
- person.set('guid', 'new-guid'); // will throw an exception
3060
+ user.get('isAnonymous'); // true
3061
+ user.set('loggedIn', true);
3062
+ user.get('isAnonymous'); // false
3061
3063
  ```
3062
3064
 
3063
- @method readOnly
3064
- @return {Ember.ComputedProperty} this
3065
- @chainable
3065
+ @method not
3066
+ @for Ember.computed
3067
+ @param {String} dependentKey
3068
+ @return {Ember.ComputedProperty} computed property which returns
3069
+ inverse of the original value for property
3066
3070
  @public
3067
3071
  */
3068
- ComputedPropertyPrototype.readOnly = function () {
3069
- this._readOnly = true;
3070
- _emberMetalCore.default.assert('Computed properties that define a setter using the new syntax cannot be read-only', !(this._readOnly && this._setter && this._setter !== this._getter));
3071
- return this;
3072
- };
3072
+
3073
+ function not(dependentKey) {
3074
+ return _emberMetalComputed.computed(dependentKey, function () {
3075
+ return !_emberMetalProperty_get.get(this, dependentKey);
3076
+ });
3077
+ }
3073
3078
 
3074
3079
  /**
3075
- Sets the dependent keys on this computed property. Pass any number of
3076
- arguments containing key paths that this computed property depends on.
3080
+ A computed property that converts the provided dependent property
3081
+ into a boolean value.
3077
3082
 
3078
3083
  ```javascript
3079
- var President = Ember.Object.extend({
3080
- fullName: computed(function() {
3081
- return this.get('firstName') + ' ' + this.get('lastName');
3082
-
3083
- // Tell Ember that this computed property depends on firstName
3084
- // and lastName
3085
- }).property('firstName', 'lastName')
3084
+ var Hamster = Ember.Object.extend({
3085
+ hasBananas: Ember.computed.bool('numBananas')
3086
3086
  });
3087
3087
 
3088
- var president = President.create({
3089
- firstName: 'Barack',
3090
- lastName: 'Obama'
3091
- });
3088
+ var hamster = Hamster.create();
3092
3089
 
3093
- president.get('fullName'); // 'Barack Obama'
3090
+ hamster.get('hasBananas'); // false
3091
+ hamster.set('numBananas', 0);
3092
+ hamster.get('hasBananas'); // false
3093
+ hamster.set('numBananas', 1);
3094
+ hamster.get('hasBananas'); // true
3095
+ hamster.set('numBananas', null);
3096
+ hamster.get('hasBananas'); // false
3094
3097
  ```
3095
3098
 
3096
- @method property
3097
- @param {String} path* zero or more property paths
3098
- @return {Ember.ComputedProperty} this
3099
- @chainable
3099
+ @method bool
3100
+ @for Ember.computed
3101
+ @param {String} dependentKey
3102
+ @return {Ember.ComputedProperty} computed property which converts
3103
+ to boolean the original value for property
3100
3104
  @public
3101
3105
  */
3102
- ComputedPropertyPrototype.property = function () {
3103
- var args;
3104
-
3105
- var addArg = function (property) {
3106
- _emberMetalCore.default.assert('Depending on arrays using a dependent key ending with `@each` is no longer supported. ' + ('Please refactor from `Ember.computed(\'' + property + '\', function() {});` to `Ember.computed(\'' + property.slice(0, -6) + '.[]\', function() {})`.'), property.slice(-5) !== '@each');
3107
- args.push(property);
3108
- };
3109
-
3110
- args = [];
3111
- for (var i = 0, l = arguments.length; i < l; i++) {
3112
- _emberMetalExpand_properties.default(arguments[i], addArg);
3113
- }
3114
3106
 
3115
- this._dependentKeys = args;
3116
- return this;
3117
- };
3107
+ function bool(dependentKey) {
3108
+ return _emberMetalComputed.computed(dependentKey, function () {
3109
+ return !!_emberMetalProperty_get.get(this, dependentKey);
3110
+ });
3111
+ }
3118
3112
 
3119
3113
  /**
3120
- In some cases, you may want to annotate computed properties with additional
3121
- metadata about how they function or what values they operate on. For example,
3122
- computed property functions may close over variables that are then no longer
3123
- available for introspection.
3114
+ A computed property which matches the original value for the
3115
+ dependent property against a given RegExp, returning `true`
3116
+ if they values matches the RegExp and `false` if it does not.
3124
3117
 
3125
- You can pass a hash of these values to a computed property like this:
3118
+ Example
3126
3119
 
3127
- ```
3128
- person: function() {
3129
- var personId = this.get('personId');
3130
- return App.Person.create({ id: personId });
3131
- }.property().meta({ type: App.Person })
3132
- ```
3120
+ ```javascript
3121
+ var User = Ember.Object.extend({
3122
+ hasValidEmail: Ember.computed.match('email', /^.+@.+\..+$/)
3123
+ });
3133
3124
 
3134
- The hash that you pass to the `meta()` function will be saved on the
3135
- computed property descriptor under the `_meta` key. Ember runtime
3136
- exposes a public API for retrieving these values from classes,
3137
- via the `metaForProperty()` function.
3125
+ var user = User.create({loggedIn: false});
3138
3126
 
3139
- @method meta
3140
- @param {Object} meta
3141
- @chainable
3127
+ user.get('hasValidEmail'); // false
3128
+ user.set('email', '');
3129
+ user.get('hasValidEmail'); // false
3130
+ user.set('email', 'ember_hamster@example.com');
3131
+ user.get('hasValidEmail'); // true
3132
+ ```
3133
+
3134
+ @method match
3135
+ @for Ember.computed
3136
+ @param {String} dependentKey
3137
+ @param {RegExp} regexp
3138
+ @return {Ember.ComputedProperty} computed property which match
3139
+ the original value for property against a given RegExp
3142
3140
  @public
3143
3141
  */
3144
3142
 
3145
- ComputedPropertyPrototype.meta = function (meta) {
3146
- if (arguments.length === 0) {
3147
- return this._meta || {};
3148
- } else {
3149
- this._meta = meta;
3150
- return this;
3151
- }
3152
- };
3153
-
3154
- // invalidate cache when CP key changes
3155
- ComputedPropertyPrototype.didChange = function (obj, keyName) {
3156
- // _suspended is set via a CP.set to ensure we don't clear
3157
- // the cached value set by the setter
3158
- if (this._volatile || this._suspended === obj) {
3159
- return;
3160
- }
3161
-
3162
- // don't create objects just to invalidate
3163
- var meta = obj.__ember_meta__;
3164
- if (!meta || meta.source !== obj) {
3165
- return;
3166
- }
3143
+ function match(dependentKey, regexp) {
3144
+ return _emberMetalComputed.computed(dependentKey, function () {
3145
+ var value = _emberMetalProperty_get.get(this, dependentKey);
3167
3146
 
3168
- var cache = meta.readableCache();
3169
- if (cache && cache[keyName] !== undefined) {
3170
- cache[keyName] = undefined;
3171
- _emberMetalDependent_keys.removeDependentKeys(this, obj, keyName, meta);
3172
- }
3173
- };
3147
+ return typeof value === 'string' ? regexp.test(value) : false;
3148
+ });
3149
+ }
3174
3150
 
3175
3151
  /**
3176
- Access the value of the function backing the computed property.
3177
- If this property has already been cached, return the cached result.
3178
- Otherwise, call the function passing the property name as an argument.
3152
+ A computed property that returns true if the provided dependent property
3153
+ is equal to the given value.
3154
+
3155
+ Example
3179
3156
 
3180
3157
  ```javascript
3181
- var Person = Ember.Object.extend({
3182
- fullName: function(keyName) {
3183
- // the keyName parameter is 'fullName' in this case.
3184
- return this.get('firstName') + ' ' + this.get('lastName');
3185
- }.property('firstName', 'lastName')
3158
+ var Hamster = Ember.Object.extend({
3159
+ napTime: Ember.computed.equal('state', 'sleepy')
3186
3160
  });
3187
3161
 
3162
+ var hamster = Hamster.create();
3188
3163
 
3189
- var tom = Person.create({
3190
- firstName: 'Tom',
3191
- lastName: 'Dale'
3192
- });
3193
-
3194
- tom.get('fullName') // 'Tom Dale'
3164
+ hamster.get('napTime'); // false
3165
+ hamster.set('state', 'sleepy');
3166
+ hamster.get('napTime'); // true
3167
+ hamster.set('state', 'hungry');
3168
+ hamster.get('napTime'); // false
3195
3169
  ```
3196
3170
 
3197
- @method get
3198
- @param {String} keyName The key being accessed.
3199
- @return {Object} The return value of the function backing the CP.
3171
+ @method equal
3172
+ @for Ember.computed
3173
+ @param {String} dependentKey
3174
+ @param {String|Number|Object} value
3175
+ @return {Ember.ComputedProperty} computed property which returns true if
3176
+ the original value for property is equal to the given value.
3200
3177
  @public
3201
3178
  */
3202
- ComputedPropertyPrototype.get = function (obj, keyName) {
3203
- if (this._volatile) {
3204
- return this._getter.call(obj, keyName);
3205
- }
3206
-
3207
- var meta = metaFor(obj);
3208
- var cache = meta.writableCache();
3209
-
3210
- var result = cache[keyName];
3211
- if (result === UNDEFINED) {
3212
- return undefined;
3213
- } else if (result !== undefined) {
3214
- return result;
3215
- }
3216
-
3217
- var ret = this._getter.call(obj, keyName);
3218
- if (ret === undefined) {
3219
- cache[keyName] = UNDEFINED;
3220
- } else {
3221
- cache[keyName] = ret;
3222
- }
3223
-
3224
- var chainWatchers = meta.readableChainWatchers();
3225
- if (chainWatchers) {
3226
- chainWatchers.revalidate(keyName);
3227
- }
3228
- _emberMetalDependent_keys.addDependentKeys(this, obj, keyName, meta);
3229
3179
 
3230
- return ret;
3231
- };
3180
+ function equal(dependentKey, value) {
3181
+ return _emberMetalComputed.computed(dependentKey, function () {
3182
+ return _emberMetalProperty_get.get(this, dependentKey) === value;
3183
+ });
3184
+ }
3232
3185
 
3233
3186
  /**
3234
- Set the value of a computed property. If the function that backs your
3235
- computed property does not accept arguments then the default action for
3236
- setting would be to define the property on the current object, and set
3237
- the value of the property to the value being set.
3187
+ A computed property that returns true if the provided dependent property
3188
+ is greater than the provided value.
3238
3189
 
3239
- Generally speaking if you intend for your computed property to be set
3240
- your backing function should accept either two or three arguments.
3190
+ Example
3241
3191
 
3242
3192
  ```javascript
3243
- var Person = Ember.Object.extend({
3244
- // these will be supplied by `create`
3245
- firstName: null,
3246
- lastName: null,
3247
-
3248
- fullName: function(key, value, oldValue) {
3249
- // getter
3250
- if (arguments.length === 1) {
3251
- var firstName = this.get('firstName');
3252
- var lastName = this.get('lastName');
3253
-
3254
- return firstName + ' ' + lastName;
3255
-
3256
- // setter
3257
- } else {
3258
- var name = value.split(' ');
3259
-
3260
- this.set('firstName', name[0]);
3261
- this.set('lastName', name[1]);
3262
-
3263
- return value;
3264
- }
3265
- }.property('firstName', 'lastName')
3193
+ var Hamster = Ember.Object.extend({
3194
+ hasTooManyBananas: Ember.computed.gt('numBananas', 10)
3266
3195
  });
3267
3196
 
3268
- var person = Person.create();
3197
+ var hamster = Hamster.create();
3269
3198
 
3270
- person.set('fullName', 'Peter Wagenet');
3271
- person.get('firstName'); // 'Peter'
3272
- person.get('lastName'); // 'Wagenet'
3199
+ hamster.get('hasTooManyBananas'); // false
3200
+ hamster.set('numBananas', 3);
3201
+ hamster.get('hasTooManyBananas'); // false
3202
+ hamster.set('numBananas', 11);
3203
+ hamster.get('hasTooManyBananas'); // true
3273
3204
  ```
3274
3205
 
3275
- @method set
3276
- @param {String} keyName The key being accessed.
3277
- @param {Object} newValue The new value being assigned.
3278
- @param {String} oldValue The old value being replaced.
3279
- @return {Object} The return value of the function backing the CP.
3206
+ @method gt
3207
+ @for Ember.computed
3208
+ @param {String} dependentKey
3209
+ @param {Number} value
3210
+ @return {Ember.ComputedProperty} computed property which returns true if
3211
+ the original value for property is greater than given value.
3280
3212
  @public
3281
3213
  */
3282
- ComputedPropertyPrototype.set = function computedPropertySetEntry(obj, keyName, value) {
3283
- if (this._readOnly) {
3284
- this._throwReadOnlyError(obj, keyName);
3285
- }
3286
-
3287
- if (!this._setter) {
3288
- return this.clobberSet(obj, keyName, value);
3289
- }
3290
3214
 
3291
- if (this._volatile) {
3292
- return this.volatileSet(obj, keyName, value);
3293
- }
3294
-
3295
- return this.setWithSuspend(obj, keyName, value);
3296
- };
3297
-
3298
- ComputedPropertyPrototype._throwReadOnlyError = function computedPropertyThrowReadOnlyError(obj, keyName) {
3299
- throw new _emberMetalError.default('Cannot set read-only property "' + keyName + '" on object: ' + _emberMetalUtils.inspect(obj));
3300
- };
3301
-
3302
- ComputedPropertyPrototype.clobberSet = function computedPropertyClobberSet(obj, keyName, value) {
3303
- var cachedValue = cacheFor(obj, keyName);
3304
- _emberMetalProperties.defineProperty(obj, keyName, null, cachedValue);
3305
- _emberMetalProperty_set.set(obj, keyName, value);
3306
- return value;
3307
- };
3308
-
3309
- ComputedPropertyPrototype.volatileSet = function computedPropertyVolatileSet(obj, keyName, value) {
3310
- return this._setter.call(obj, keyName, value);
3311
- };
3312
-
3313
- ComputedPropertyPrototype.setWithSuspend = function computedPropertySetWithSuspend(obj, keyName, value) {
3314
- var oldSuspended = this._suspended;
3315
- this._suspended = obj;
3316
- try {
3317
- return this._set(obj, keyName, value);
3318
- } finally {
3319
- this._suspended = oldSuspended;
3320
- }
3321
- };
3322
-
3323
- ComputedPropertyPrototype._set = function computedPropertySet(obj, keyName, value) {
3324
- // cache requires own meta
3325
- var meta = metaFor(obj);
3326
- // either there is a writable cache or we need one to update
3327
- var cache = meta.writableCache();
3328
- var hadCachedValue = false;
3329
- var cachedValue = undefined;
3330
- if (cache[keyName] !== undefined) {
3331
- if (cache[keyName] !== UNDEFINED) {
3332
- cachedValue = cache[keyName];
3333
- }
3334
- hadCachedValue = true;
3335
- }
3336
-
3337
- var ret = this._setter.call(obj, keyName, value, cachedValue);
3338
-
3339
- // allows setter to return the same value that is cached already
3340
- if (hadCachedValue && cachedValue === ret) {
3341
- return ret;
3342
- }
3343
-
3344
- var watched = meta.peekWatching(keyName);
3345
- if (watched) {
3346
- _emberMetalProperty_events.propertyWillChange(obj, keyName);
3347
- }
3348
-
3349
- if (hadCachedValue) {
3350
- cache[keyName] = undefined;
3351
- }
3352
-
3353
- if (!hadCachedValue) {
3354
- _emberMetalDependent_keys.addDependentKeys(this, obj, keyName, meta);
3355
- }
3356
-
3357
- if (ret === undefined) {
3358
- cache[keyName] = UNDEFINED;
3359
- } else {
3360
- cache[keyName] = ret;
3361
- }
3362
-
3363
- if (watched) {
3364
- _emberMetalProperty_events.propertyDidChange(obj, keyName);
3365
- }
3366
-
3367
- return ret;
3368
- };
3369
-
3370
- /* called before property is overridden */
3371
- ComputedPropertyPrototype.teardown = function (obj, keyName) {
3372
- if (this._volatile) {
3373
- return;
3374
- }
3375
- var meta = metaFor(obj);
3376
- var cache = meta.readableCache();
3377
- if (cache && cache[keyName] !== undefined) {
3378
- _emberMetalDependent_keys.removeDependentKeys(this, obj, keyName, meta);
3379
- cache[keyName] = undefined;
3380
- }
3381
- };
3215
+ function gt(dependentKey, value) {
3216
+ return _emberMetalComputed.computed(dependentKey, function () {
3217
+ return _emberMetalProperty_get.get(this, dependentKey) > value;
3218
+ });
3219
+ }
3382
3220
 
3383
3221
  /**
3384
- This helper returns a new property descriptor that wraps the passed
3385
- computed property function. You can use this helper to define properties
3386
- with mixins or via `Ember.defineProperty()`.
3387
-
3388
- The function you pass will be used to both get and set property values.
3389
- The function should accept two parameters, key and value. If value is not
3390
- undefined you should set the value first. In either case return the
3391
- current value of the property.
3392
-
3393
- A computed property defined in this way might look like this:
3222
+ A computed property that returns true if the provided dependent property
3223
+ is greater than or equal to the provided value.
3394
3224
 
3395
- ```js
3396
- var Person = Ember.Object.extend({
3397
- firstName: 'Betty',
3398
- lastName: 'Jones',
3225
+ Example
3399
3226
 
3400
- fullName: Ember.computed('firstName', 'lastName', function(key, value) {
3401
- return this.get('firstName') + ' ' + this.get('lastName');
3402
- })
3227
+ ```javascript
3228
+ var Hamster = Ember.Object.extend({
3229
+ hasTooManyBananas: Ember.computed.gte('numBananas', 10)
3403
3230
  });
3404
3231
 
3405
- var client = Person.create();
3406
-
3407
- client.get('fullName'); // 'Betty Jones'
3408
-
3409
- client.set('lastName', 'Fuller');
3410
- client.get('fullName'); // 'Betty Fuller'
3411
- ```
3412
-
3413
- _Note: This is the preferred way to define computed properties when writing third-party
3414
- libraries that depend on or use Ember, since there is no guarantee that the user
3415
- will have prototype extensions enabled._
3416
-
3417
- You might use this method if you disabled
3418
- [Prototype Extensions](http://emberjs.com/guides/configuring-ember/disabling-prototype-extensions/).
3419
- The alternative syntax might look like this
3420
- (if prototype extensions are enabled, which is the default behavior):
3232
+ var hamster = Hamster.create();
3421
3233
 
3422
- ```js
3423
- fullName: function () {
3424
- return this.get('firstName') + ' ' + this.get('lastName');
3425
- }.property('firstName', 'lastName')
3234
+ hamster.get('hasTooManyBananas'); // false
3235
+ hamster.set('numBananas', 3);
3236
+ hamster.get('hasTooManyBananas'); // false
3237
+ hamster.set('numBananas', 10);
3238
+ hamster.get('hasTooManyBananas'); // true
3426
3239
  ```
3427
3240
 
3428
- @class computed
3429
- @namespace Ember
3430
- @constructor
3431
- @static
3432
- @param {String} [dependentKeys*] Optional dependent keys that trigger this computed property.
3433
- @param {Function} func The computed property function.
3434
- @return {Ember.ComputedProperty} property descriptor instance
3241
+ @method gte
3242
+ @for Ember.computed
3243
+ @param {String} dependentKey
3244
+ @param {Number} value
3245
+ @return {Ember.ComputedProperty} computed property which returns true if
3246
+ the original value for property is greater or equal then given value.
3435
3247
  @public
3436
3248
  */
3437
3249
 
3438
- function computed(func) {
3439
- var args;
3440
-
3441
- if (arguments.length > 1) {
3442
- args = [].slice.call(arguments);
3443
- func = args.pop();
3444
- }
3445
-
3446
- var cp = new ComputedProperty(func);
3447
-
3448
- if (args) {
3449
- cp.property.apply(cp, args);
3450
- }
3451
-
3452
- return cp;
3250
+ function gte(dependentKey, value) {
3251
+ return _emberMetalComputed.computed(dependentKey, function () {
3252
+ return _emberMetalProperty_get.get(this, dependentKey) >= value;
3253
+ });
3453
3254
  }
3454
3255
 
3455
3256
  /**
3456
- Returns the cached value for a property, if one exists.
3457
- This can be useful for peeking at the value of a computed
3458
- property that is generated lazily, without accidentally causing
3459
- it to be created.
3257
+ A computed property that returns true if the provided dependent property
3258
+ is less than the provided value.
3460
3259
 
3461
- @method cacheFor
3462
- @for Ember
3463
- @param {Object} obj the object whose property you want to check
3464
- @param {String} key the name of the property whose cached value you want
3465
- to return
3466
- @return {Object} the cached value
3260
+ Example
3261
+
3262
+ ```javascript
3263
+ var Hamster = Ember.Object.extend({
3264
+ needsMoreBananas: Ember.computed.lt('numBananas', 3)
3265
+ });
3266
+
3267
+ var hamster = Hamster.create();
3268
+
3269
+ hamster.get('needsMoreBananas'); // true
3270
+ hamster.set('numBananas', 3);
3271
+ hamster.get('needsMoreBananas'); // false
3272
+ hamster.set('numBananas', 2);
3273
+ hamster.get('needsMoreBananas'); // true
3274
+ ```
3275
+
3276
+ @method lt
3277
+ @for Ember.computed
3278
+ @param {String} dependentKey
3279
+ @param {Number} value
3280
+ @return {Ember.ComputedProperty} computed property which returns true if
3281
+ the original value for property is less then given value.
3467
3282
  @public
3468
3283
  */
3469
- function cacheFor(obj, key) {
3470
- var meta = obj.__ember_meta__;
3471
- var cache = meta && meta.source === obj && meta.readableCache();
3472
- var ret = cache && cache[key];
3473
3284
 
3474
- if (ret === UNDEFINED) {
3475
- return undefined;
3476
- }
3477
- return ret;
3478
- }
3479
-
3480
- cacheFor.set = function (cache, key, value) {
3481
- if (value === undefined) {
3482
- cache[key] = UNDEFINED;
3483
- } else {
3484
- cache[key] = value;
3485
- }
3486
- };
3487
-
3488
- cacheFor.get = function (cache, key) {
3489
- var ret = cache[key];
3490
- if (ret === UNDEFINED) {
3491
- return undefined;
3492
- }
3493
- return ret;
3494
- };
3495
-
3496
- cacheFor.remove = function (cache, key) {
3497
- cache[key] = undefined;
3498
- };
3499
-
3500
- exports.ComputedProperty = ComputedProperty;
3501
- exports.computed = computed;
3502
- exports.cacheFor = cacheFor;
3503
- });
3504
- enifed('ember-metal/computed_macros', ['exports', 'ember-metal/core', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/computed', 'ember-metal/is_empty', 'ember-metal/is_none', 'ember-metal/alias'], function (exports, _emberMetalCore, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalComputed, _emberMetalIs_empty, _emberMetalIs_none, _emberMetalAlias) {
3505
- 'use strict';
3506
-
3507
- exports.empty = empty;
3508
- exports.notEmpty = notEmpty;
3509
- exports.none = none;
3510
- exports.not = not;
3511
- exports.bool = bool;
3512
- exports.match = match;
3513
- exports.equal = equal;
3514
- exports.gt = gt;
3515
- exports.gte = gte;
3516
- exports.lt = lt;
3517
- exports.lte = lte;
3518
- exports.oneWay = oneWay;
3519
- exports.readOnly = readOnly;
3520
- exports.deprecatingAlias = deprecatingAlias;
3521
-
3522
- /**
3523
- @module ember
3524
- @submodule ember-metal
3525
- */
3526
-
3527
- function getProperties(self, propertyNames) {
3528
- var ret = {};
3529
- for (var i = 0; i < propertyNames.length; i++) {
3530
- ret[propertyNames[i]] = _emberMetalProperty_get.get(self, propertyNames[i]);
3531
- }
3532
- return ret;
3533
- }
3534
-
3535
- function generateComputedWithProperties(macro) {
3536
- return function () {
3537
- for (var _len = arguments.length, properties = Array(_len), _key = 0; _key < _len; _key++) {
3538
- properties[_key] = arguments[_key];
3539
- }
3540
-
3541
- var computedFunc = _emberMetalComputed.computed(function () {
3542
- return macro.apply(this, [getProperties(this, properties)]);
3543
- });
3544
-
3545
- return computedFunc.property.apply(computedFunc, properties);
3546
- };
3285
+ function lt(dependentKey, value) {
3286
+ return _emberMetalComputed.computed(dependentKey, function () {
3287
+ return _emberMetalProperty_get.get(this, dependentKey) < value;
3288
+ });
3547
3289
  }
3548
3290
 
3549
3291
  /**
3550
- A computed property that returns true if the value of the dependent
3551
- property is null, an empty string, empty array, or empty function.
3292
+ A computed property that returns true if the provided dependent property
3293
+ is less than or equal to the provided value.
3552
3294
 
3553
3295
  Example
3554
3296
 
3555
3297
  ```javascript
3556
- var ToDoList = Ember.Object.extend({
3557
- isDone: Ember.computed.empty('todos')
3298
+ var Hamster = Ember.Object.extend({
3299
+ needsMoreBananas: Ember.computed.lte('numBananas', 3)
3558
3300
  });
3559
3301
 
3560
- var todoList = ToDoList.create({
3561
- todos: ['Unit Test', 'Documentation', 'Release']
3562
- });
3302
+ var hamster = Hamster.create();
3563
3303
 
3564
- todoList.get('isDone'); // false
3565
- todoList.get('todos').clear();
3566
- todoList.get('isDone'); // true
3304
+ hamster.get('needsMoreBananas'); // true
3305
+ hamster.set('numBananas', 5);
3306
+ hamster.get('needsMoreBananas'); // false
3307
+ hamster.set('numBananas', 3);
3308
+ hamster.get('needsMoreBananas'); // true
3567
3309
  ```
3568
3310
 
3569
- @since 1.6.0
3570
- @method empty
3311
+ @method lte
3571
3312
  @for Ember.computed
3572
3313
  @param {String} dependentKey
3573
- @return {Ember.ComputedProperty} computed property which negate
3574
- the original value for property
3314
+ @param {Number} value
3315
+ @return {Ember.ComputedProperty} computed property which returns true if
3316
+ the original value for property is less or equal than given value.
3575
3317
  @public
3576
3318
  */
3577
3319
 
3578
- function empty(dependentKey) {
3579
- return _emberMetalComputed.computed(dependentKey + '.length', function () {
3580
- return _emberMetalIs_empty.default(_emberMetalProperty_get.get(this, dependentKey));
3320
+ function lte(dependentKey, value) {
3321
+ return _emberMetalComputed.computed(dependentKey, function () {
3322
+ return _emberMetalProperty_get.get(this, dependentKey) <= value;
3581
3323
  });
3582
3324
  }
3583
3325
 
3584
3326
  /**
3585
- A computed property that returns true if the value of the dependent
3586
- property is NOT null, an empty string, empty array, or empty function.
3327
+ A computed property that performs a logical `and` on the
3328
+ original values for the provided dependent properties.
3587
3329
 
3588
3330
  Example
3589
3331
 
3590
3332
  ```javascript
3591
3333
  var Hamster = Ember.Object.extend({
3592
- hasStuff: Ember.computed.notEmpty('backpack')
3334
+ readyForCamp: Ember.computed.and('hasTent', 'hasBackpack')
3593
3335
  });
3594
3336
 
3595
- var hamster = Hamster.create({ backpack: ['Food', 'Sleeping Bag', 'Tent'] });
3337
+ var hamster = Hamster.create();
3596
3338
 
3597
- hamster.get('hasStuff'); // true
3598
- hamster.get('backpack').clear(); // []
3599
- hamster.get('hasStuff'); // false
3339
+ hamster.get('readyForCamp'); // false
3340
+ hamster.set('hasTent', true);
3341
+ hamster.get('readyForCamp'); // false
3342
+ hamster.set('hasBackpack', true);
3343
+ hamster.get('readyForCamp'); // true
3344
+ hamster.set('hasBackpack', 'Yes');
3345
+ hamster.get('readyForCamp'); // 'Yes'
3600
3346
  ```
3601
3347
 
3602
- @method notEmpty
3348
+ @method and
3603
3349
  @for Ember.computed
3604
- @param {String} dependentKey
3605
- @return {Ember.ComputedProperty} computed property which returns true if
3606
- original value for property is not empty.
3350
+ @param {String} dependentKey*
3351
+ @return {Ember.ComputedProperty} computed property which performs
3352
+ a logical `and` on the values of all the original values for properties.
3607
3353
  @public
3608
3354
  */
3355
+ var and = generateComputedWithProperties(function (properties) {
3356
+ var value;
3357
+ for (var key in properties) {
3358
+ value = properties[key];
3359
+ if (properties.hasOwnProperty(key) && !value) {
3360
+ return false;
3361
+ }
3362
+ }
3363
+ return value;
3364
+ });
3609
3365
 
3610
- function notEmpty(dependentKey) {
3611
- return _emberMetalComputed.computed(dependentKey + '.length', function () {
3612
- return !_emberMetalIs_empty.default(_emberMetalProperty_get.get(this, dependentKey));
3613
- });
3614
- }
3615
-
3366
+ exports.and = and;
3616
3367
  /**
3617
- A computed property that returns true if the value of the dependent
3618
- property is null or undefined. This avoids errors from JSLint complaining
3619
- about use of ==, which can be technically confusing.
3368
+ A computed property which performs a logical `or` on the
3369
+ original values for the provided dependent properties.
3620
3370
 
3621
3371
  Example
3622
3372
 
3623
3373
  ```javascript
3624
3374
  var Hamster = Ember.Object.extend({
3625
- isHungry: Ember.computed.none('food')
3375
+ readyForRain: Ember.computed.or('hasJacket', 'hasUmbrella')
3626
3376
  });
3627
3377
 
3628
3378
  var hamster = Hamster.create();
3629
3379
 
3630
- hamster.get('isHungry'); // true
3631
- hamster.set('food', 'Banana');
3632
- hamster.get('isHungry'); // false
3633
- hamster.set('food', null);
3634
- hamster.get('isHungry'); // true
3380
+ hamster.get('readyForRain'); // false
3381
+ hamster.set('hasUmbrella', true);
3382
+ hamster.get('readyForRain'); // true
3383
+ hamster.set('hasJacket', 'Yes');
3384
+ hamster.get('readyForRain'); // 'Yes'
3635
3385
  ```
3636
3386
 
3637
- @method none
3387
+ @method or
3638
3388
  @for Ember.computed
3639
- @param {String} dependentKey
3640
- @return {Ember.ComputedProperty} computed property which
3641
- returns true if original value for property is null or undefined.
3389
+ @param {String} dependentKey*
3390
+ @return {Ember.ComputedProperty} computed property which performs
3391
+ a logical `or` on the values of all the original values for properties.
3642
3392
  @public
3643
3393
  */
3394
+ var or = generateComputedWithProperties(function (properties) {
3395
+ var value;
3396
+ for (var key in properties) {
3397
+ value = properties[key];
3398
+ if (properties.hasOwnProperty(key) && value) {
3399
+ return value;
3400
+ }
3401
+ }
3402
+ return value;
3403
+ });
3644
3404
 
3645
- function none(dependentKey) {
3646
- return _emberMetalComputed.computed(dependentKey, function () {
3647
- return _emberMetalIs_none.default(_emberMetalProperty_get.get(this, dependentKey));
3648
- });
3649
- }
3650
-
3405
+ exports.or = or;
3651
3406
  /**
3652
- A computed property that returns the inverse boolean value
3653
- of the original value for the dependent property.
3407
+ A computed property that returns the array of values
3408
+ for the provided dependent properties.
3654
3409
 
3655
3410
  Example
3656
3411
 
3657
3412
  ```javascript
3658
- var User = Ember.Object.extend({
3659
- isAnonymous: Ember.computed.not('loggedIn')
3413
+ var Hamster = Ember.Object.extend({
3414
+ clothes: Ember.computed.collect('hat', 'shirt')
3660
3415
  });
3661
3416
 
3662
- var user = User.create({loggedIn: false});
3417
+ var hamster = Hamster.create();
3663
3418
 
3664
- user.get('isAnonymous'); // true
3665
- user.set('loggedIn', true);
3666
- user.get('isAnonymous'); // false
3419
+ hamster.get('clothes'); // [null, null]
3420
+ hamster.set('hat', 'Camp Hat');
3421
+ hamster.set('shirt', 'Camp Shirt');
3422
+ hamster.get('clothes'); // ['Camp Hat', 'Camp Shirt']
3667
3423
  ```
3668
3424
 
3669
- @method not
3425
+ @method collect
3670
3426
  @for Ember.computed
3671
- @param {String} dependentKey
3672
- @return {Ember.ComputedProperty} computed property which returns
3673
- inverse of the original value for property
3427
+ @param {String} dependentKey*
3428
+ @return {Ember.ComputedProperty} computed property which maps
3429
+ values of all passed in properties to an array.
3674
3430
  @public
3675
3431
  */
3432
+ var collect = generateComputedWithProperties(function (properties) {
3433
+ var res = _emberMetalCore.default.A();
3434
+ for (var key in properties) {
3435
+ if (properties.hasOwnProperty(key)) {
3436
+ if (_emberMetalIs_none.default(properties[key])) {
3437
+ res.push(null);
3438
+ } else {
3439
+ res.push(properties[key]);
3440
+ }
3441
+ }
3442
+ }
3443
+ return res;
3444
+ });
3676
3445
 
3677
- function not(dependentKey) {
3678
- return _emberMetalComputed.computed(dependentKey, function () {
3679
- return !_emberMetalProperty_get.get(this, dependentKey);
3680
- });
3681
- }
3682
-
3446
+ exports.collect = collect;
3683
3447
  /**
3684
- A computed property that converts the provided dependent property
3685
- into a boolean value.
3448
+ Creates a new property that is an alias for another property
3449
+ on an object. Calls to `get` or `set` this property behave as
3450
+ though they were called on the original property.
3686
3451
 
3687
3452
  ```javascript
3688
- var Hamster = Ember.Object.extend({
3689
- hasBananas: Ember.computed.bool('numBananas')
3453
+ var Person = Ember.Object.extend({
3454
+ name: 'Alex Matchneer',
3455
+ nomen: Ember.computed.alias('name')
3690
3456
  });
3691
3457
 
3692
- var hamster = Hamster.create();
3458
+ var alex = Person.create();
3693
3459
 
3694
- hamster.get('hasBananas'); // false
3695
- hamster.set('numBananas', 0);
3696
- hamster.get('hasBananas'); // false
3697
- hamster.set('numBananas', 1);
3698
- hamster.get('hasBananas'); // true
3699
- hamster.set('numBananas', null);
3700
- hamster.get('hasBananas'); // false
3460
+ alex.get('nomen'); // 'Alex Matchneer'
3461
+ alex.get('name'); // 'Alex Matchneer'
3462
+
3463
+ alex.set('nomen', '@machty');
3464
+ alex.get('name'); // '@machty'
3701
3465
  ```
3702
3466
 
3703
- @method bool
3467
+ @method alias
3704
3468
  @for Ember.computed
3705
3469
  @param {String} dependentKey
3706
- @return {Ember.ComputedProperty} computed property which converts
3707
- to boolean the original value for property
3470
+ @return {Ember.ComputedProperty} computed property which creates an
3471
+ alias to the original value for property.
3708
3472
  @public
3709
3473
  */
3710
3474
 
3711
- function bool(dependentKey) {
3712
- return _emberMetalComputed.computed(dependentKey, function () {
3713
- return !!_emberMetalProperty_get.get(this, dependentKey);
3714
- });
3715
- }
3716
-
3717
3475
  /**
3718
- A computed property which matches the original value for the
3719
- dependent property against a given RegExp, returning `true`
3720
- if they values matches the RegExp and `false` if it does not.
3476
+ Where `computed.alias` aliases `get` and `set`, and allows for bidirectional
3477
+ data flow, `computed.oneWay` only provides an aliased `get`. The `set` will
3478
+ not mutate the upstream property, rather causes the current property to
3479
+ become the value set. This causes the downstream property to permanently
3480
+ diverge from the upstream property.
3721
3481
 
3722
3482
  Example
3723
3483
 
3724
3484
  ```javascript
3725
3485
  var User = Ember.Object.extend({
3726
- hasValidEmail: Ember.computed.match('email', /^.+@.+\..+$/)
3486
+ firstName: null,
3487
+ lastName: null,
3488
+ nickName: Ember.computed.oneWay('firstName')
3727
3489
  });
3728
3490
 
3729
- var user = User.create({loggedIn: false});
3491
+ var teddy = User.create({
3492
+ firstName: 'Teddy',
3493
+ lastName: 'Zeenny'
3494
+ });
3730
3495
 
3731
- user.get('hasValidEmail'); // false
3732
- user.set('email', '');
3733
- user.get('hasValidEmail'); // false
3734
- user.set('email', 'ember_hamster@example.com');
3735
- user.get('hasValidEmail'); // true
3496
+ teddy.get('nickName'); // 'Teddy'
3497
+ teddy.set('nickName', 'TeddyBear'); // 'TeddyBear'
3498
+ teddy.get('firstName'); // 'Teddy'
3736
3499
  ```
3737
3500
 
3738
- @method match
3501
+ @method oneWay
3739
3502
  @for Ember.computed
3740
3503
  @param {String} dependentKey
3741
- @param {RegExp} regexp
3742
- @return {Ember.ComputedProperty} computed property which match
3743
- the original value for property against a given RegExp
3504
+ @return {Ember.ComputedProperty} computed property which creates a
3505
+ one way computed property to the original value for property.
3744
3506
  @public
3745
3507
  */
3746
3508
 
3747
- function match(dependentKey, regexp) {
3748
- return _emberMetalComputed.computed(dependentKey, function () {
3749
- var value = _emberMetalProperty_get.get(this, dependentKey);
3750
-
3751
- return typeof value === 'string' ? regexp.test(value) : false;
3752
- });
3509
+ function oneWay(dependentKey) {
3510
+ return _emberMetalAlias.default(dependentKey).oneWay();
3753
3511
  }
3754
3512
 
3755
3513
  /**
3756
- A computed property that returns true if the provided dependent property
3757
- is equal to the given value.
3514
+ This is a more semantically meaningful alias of `computed.oneWay`,
3515
+ whose name is somewhat ambiguous as to which direction the data flows.
3516
+
3517
+ @method reads
3518
+ @for Ember.computed
3519
+ @param {String} dependentKey
3520
+ @return {Ember.ComputedProperty} computed property which creates a
3521
+ one way computed property to the original value for property.
3522
+ @public
3523
+ */
3524
+
3525
+ /**
3526
+ Where `computed.oneWay` provides oneWay bindings, `computed.readOnly` provides
3527
+ a readOnly one way binding. Very often when using `computed.oneWay` one does
3528
+ not also want changes to propagate back up, as they will replace the value.
3529
+
3530
+ This prevents the reverse flow, and also throws an exception when it occurs.
3758
3531
 
3759
3532
  Example
3760
3533
 
3761
3534
  ```javascript
3762
- var Hamster = Ember.Object.extend({
3763
- napTime: Ember.computed.equal('state', 'sleepy')
3535
+ var User = Ember.Object.extend({
3536
+ firstName: null,
3537
+ lastName: null,
3538
+ nickName: Ember.computed.readOnly('firstName')
3764
3539
  });
3765
3540
 
3766
- var hamster = Hamster.create();
3541
+ var teddy = User.create({
3542
+ firstName: 'Teddy',
3543
+ lastName: 'Zeenny'
3544
+ });
3767
3545
 
3768
- hamster.get('napTime'); // false
3769
- hamster.set('state', 'sleepy');
3770
- hamster.get('napTime'); // true
3771
- hamster.set('state', 'hungry');
3772
- hamster.get('napTime'); // false
3546
+ teddy.get('nickName'); // 'Teddy'
3547
+ teddy.set('nickName', 'TeddyBear'); // throws Exception
3548
+ // throw new Ember.Error('Cannot Set: nickName on: <User:ember27288>' );`
3549
+ teddy.get('firstName'); // 'Teddy'
3773
3550
  ```
3774
3551
 
3775
- @method equal
3552
+ @method readOnly
3776
3553
  @for Ember.computed
3777
3554
  @param {String} dependentKey
3778
- @param {String|Number|Object} value
3779
- @return {Ember.ComputedProperty} computed property which returns true if
3780
- the original value for property is equal to the given value.
3555
+ @return {Ember.ComputedProperty} computed property which creates a
3556
+ one way computed property to the original value for property.
3557
+ @since 1.5.0
3781
3558
  @public
3782
3559
  */
3783
3560
 
3784
- function equal(dependentKey, value) {
3785
- return _emberMetalComputed.computed(dependentKey, function () {
3786
- return _emberMetalProperty_get.get(this, dependentKey) === value;
3787
- });
3561
+ function readOnly(dependentKey) {
3562
+ return _emberMetalAlias.default(dependentKey).readOnly();
3788
3563
  }
3789
3564
 
3790
3565
  /**
3791
- A computed property that returns true if the provided dependent property
3792
- is greater than the provided value.
3793
-
3794
- Example
3795
-
3796
- ```javascript
3797
- var Hamster = Ember.Object.extend({
3798
- hasTooManyBananas: Ember.computed.gt('numBananas', 10)
3799
- });
3800
-
3801
- var hamster = Hamster.create();
3802
-
3803
- hamster.get('hasTooManyBananas'); // false
3804
- hamster.set('numBananas', 3);
3805
- hamster.get('hasTooManyBananas'); // false
3806
- hamster.set('numBananas', 11);
3807
- hamster.get('hasTooManyBananas'); // true
3808
- ```
3566
+ Creates a new property that is an alias for another property
3567
+ on an object. Calls to `get` or `set` this property behave as
3568
+ though they were called on the original property, but also
3569
+ print a deprecation warning.
3809
3570
 
3810
- @method gt
3571
+ @method deprecatingAlias
3811
3572
  @for Ember.computed
3812
3573
  @param {String} dependentKey
3813
- @param {Number} value
3814
- @return {Ember.ComputedProperty} computed property which returns true if
3815
- the original value for property is greater than given value.
3574
+ @return {Ember.ComputedProperty} computed property which creates an
3575
+ alias with a deprecation to the original value for property.
3576
+ @since 1.7.0
3816
3577
  @public
3817
3578
  */
3818
3579
 
3819
- function gt(dependentKey, value) {
3820
- return _emberMetalComputed.computed(dependentKey, function () {
3821
- return _emberMetalProperty_get.get(this, dependentKey) > value;
3580
+ function deprecatingAlias(dependentKey, options) {
3581
+ return _emberMetalComputed.computed(dependentKey, {
3582
+ get: function (key) {
3583
+ _emberMetalCore.default.deprecate('Usage of `' + key + '` is deprecated, use `' + dependentKey + '` instead.', false, options);
3584
+ return _emberMetalProperty_get.get(this, dependentKey);
3585
+ },
3586
+ set: function (key, value) {
3587
+ _emberMetalCore.default.deprecate('Usage of `' + key + '` is deprecated, use `' + dependentKey + '` instead.', false, options);
3588
+ _emberMetalProperty_set.set(this, dependentKey, value);
3589
+ return value;
3590
+ }
3822
3591
  });
3823
3592
  }
3593
+ });
3594
+ enifed('ember-metal/computed', ['exports', 'ember-metal/core', 'ember-metal/property_set', 'ember-metal/utils', 'ember-metal/meta', 'ember-metal/expand_properties', 'ember-metal/error', 'ember-metal/properties', 'ember-metal/property_events', 'ember-metal/dependent_keys'], function (exports, _emberMetalCore, _emberMetalProperty_set, _emberMetalUtils, _emberMetalMeta, _emberMetalExpand_properties, _emberMetalError, _emberMetalProperties, _emberMetalProperty_events, _emberMetalDependent_keys) {
3595
+ 'use strict';
3596
+
3597
+ exports.default = computed;
3824
3598
 
3825
3599
  /**
3826
- A computed property that returns true if the provided dependent property
3827
- is greater than or equal to the provided value.
3600
+ @module ember
3601
+ @submodule ember-metal
3602
+ */
3603
+
3604
+ var metaFor = _emberMetalMeta.meta;
3605
+
3606
+ function UNDEFINED() {}
3607
+
3608
+ // ..........................................................
3609
+ // COMPUTED PROPERTY
3610
+ //
3611
+
3612
+ /**
3613
+ A computed property transforms an object's function into a property.
3828
3614
 
3829
- Example
3615
+ By default the function backing the computed property will only be called
3616
+ once and the result will be cached. You can specify various properties
3617
+ that your computed property depends on. This will force the cached
3618
+ result to be recomputed if the dependencies are modified.
3619
+
3620
+ In the following example we declare a computed property (by calling
3621
+ `.property()` on the fullName function) and setup the property
3622
+ dependencies (depending on firstName and lastName). The fullName function
3623
+ will be called once (regardless of how many times it is accessed) as long
3624
+ as its dependencies have not changed. Once firstName or lastName are updated
3625
+ any future calls (or anything bound) to fullName will incorporate the new
3626
+ values.
3830
3627
 
3831
3628
  ```javascript
3832
- var Hamster = Ember.Object.extend({
3833
- hasTooManyBananas: Ember.computed.gte('numBananas', 10)
3834
- });
3629
+ var Person = Ember.Object.extend({
3630
+ // these will be supplied by `create`
3631
+ firstName: null,
3632
+ lastName: null,
3835
3633
 
3836
- var hamster = Hamster.create();
3634
+ fullName: function() {
3635
+ var firstName = this.get('firstName');
3636
+ var lastName = this.get('lastName');
3837
3637
 
3838
- hamster.get('hasTooManyBananas'); // false
3839
- hamster.set('numBananas', 3);
3840
- hamster.get('hasTooManyBananas'); // false
3841
- hamster.set('numBananas', 10);
3842
- hamster.get('hasTooManyBananas'); // true
3843
- ```
3638
+ return firstName + ' ' + lastName;
3639
+ }.property('firstName', 'lastName')
3640
+ });
3844
3641
 
3845
- @method gte
3846
- @for Ember.computed
3847
- @param {String} dependentKey
3848
- @param {Number} value
3849
- @return {Ember.ComputedProperty} computed property which returns true if
3850
- the original value for property is greater or equal then given value.
3851
- @public
3852
- */
3853
-
3854
- function gte(dependentKey, value) {
3855
- return _emberMetalComputed.computed(dependentKey, function () {
3856
- return _emberMetalProperty_get.get(this, dependentKey) >= value;
3642
+ var tom = Person.create({
3643
+ firstName: 'Tom',
3644
+ lastName: 'Dale'
3857
3645
  });
3858
- }
3859
-
3860
- /**
3861
- A computed property that returns true if the provided dependent property
3862
- is less than the provided value.
3863
3646
 
3864
- Example
3647
+ tom.get('fullName') // 'Tom Dale'
3648
+ ```
3649
+
3650
+ You can also define what Ember should do when setting a computed property.
3651
+ If you try to set a computed property, it will be invoked with the key and
3652
+ value you want to set it to. You can also accept the previous value as the
3653
+ third parameter.
3865
3654
 
3866
3655
  ```javascript
3867
- var Hamster = Ember.Object.extend({
3868
- needsMoreBananas: Ember.computed.lt('numBananas', 3)
3656
+ var Person = Ember.Object.extend({
3657
+ // these will be supplied by `create`
3658
+ firstName: null,
3659
+ lastName: null,
3660
+
3661
+ fullName: function(key, value, oldValue) {
3662
+ // getter
3663
+ if (arguments.length === 1) {
3664
+ var firstName = this.get('firstName');
3665
+ var lastName = this.get('lastName');
3666
+
3667
+ return firstName + ' ' + lastName;
3668
+
3669
+ // setter
3670
+ } else {
3671
+ var name = value.split(' ');
3672
+
3673
+ this.set('firstName', name[0]);
3674
+ this.set('lastName', name[1]);
3675
+
3676
+ return value;
3677
+ }
3678
+ }.property('firstName', 'lastName')
3869
3679
  });
3870
3680
 
3871
- var hamster = Hamster.create();
3681
+ var person = Person.create();
3872
3682
 
3873
- hamster.get('needsMoreBananas'); // true
3874
- hamster.set('numBananas', 3);
3875
- hamster.get('needsMoreBananas'); // false
3876
- hamster.set('numBananas', 2);
3877
- hamster.get('needsMoreBananas'); // true
3683
+ person.set('fullName', 'Peter Wagenet');
3684
+ person.get('firstName'); // 'Peter'
3685
+ person.get('lastName'); // 'Wagenet'
3878
3686
  ```
3879
3687
 
3880
- @method lt
3881
- @for Ember.computed
3882
- @param {String} dependentKey
3883
- @param {Number} value
3884
- @return {Ember.ComputedProperty} computed property which returns true if
3885
- the original value for property is less then given value.
3688
+ @class ComputedProperty
3689
+ @namespace Ember
3690
+ @constructor
3886
3691
  @public
3887
3692
  */
3888
-
3889
- function lt(dependentKey, value) {
3890
- return _emberMetalComputed.computed(dependentKey, function () {
3891
- return _emberMetalProperty_get.get(this, dependentKey) < value;
3892
- });
3693
+ function ComputedProperty(config, opts) {
3694
+ this.isDescriptor = true;
3695
+ if (typeof config === 'function') {
3696
+ this._getter = config;
3697
+ } else {
3698
+ _emberMetalCore.default.assert('Ember.computed expects a function or an object as last argument.', typeof config === 'object' && !Array.isArray(config));
3699
+ _emberMetalCore.default.assert('Config object pased to a Ember.computed can only contain `get` or `set` keys.', (function () {
3700
+ var keys = Object.keys(config);
3701
+ for (var i = 0; i < keys.length; i++) {
3702
+ if (keys[i] !== 'get' && keys[i] !== 'set') {
3703
+ return false;
3704
+ }
3705
+ }
3706
+ return true;
3707
+ })());
3708
+ this._getter = config.get;
3709
+ this._setter = config.set;
3710
+ }
3711
+ _emberMetalCore.default.assert('Computed properties must receive a getter or a setter, you passed none.', !!this._getter || !!this._setter);
3712
+ this._dependentKeys = undefined;
3713
+ this._suspended = undefined;
3714
+ this._meta = undefined;
3715
+ this._volatile = false;
3716
+ this._dependentKeys = opts && opts.dependentKeys;
3717
+ this._readOnly = false;
3893
3718
  }
3894
3719
 
3720
+ ComputedProperty.prototype = new _emberMetalProperties.Descriptor();
3721
+
3722
+ var ComputedPropertyPrototype = ComputedProperty.prototype;
3723
+
3724
+ /**
3725
+ Call on a computed property to set it into non-cached mode. When in this
3726
+ mode the computed property will not automatically cache the return value.
3727
+
3728
+ It also does not automatically fire any change events. You must manually notify
3729
+ any changes if you want to observe this property.
3730
+
3731
+ Dependency keys have no effect on volatile properties as they are for cache
3732
+ invalidation and notification when cached value is invalidated.
3733
+
3734
+ ```javascript
3735
+ var outsideService = Ember.Object.extend({
3736
+ value: function() {
3737
+ return OutsideService.getValue();
3738
+ }.property().volatile()
3739
+ }).create();
3740
+ ```
3741
+
3742
+ @method volatile
3743
+ @return {Ember.ComputedProperty} this
3744
+ @chainable
3745
+ @public
3746
+ */
3747
+ ComputedPropertyPrototype.volatile = function () {
3748
+ this._volatile = true;
3749
+ return this;
3750
+ };
3751
+
3895
3752
  /**
3896
- A computed property that returns true if the provided dependent property
3897
- is less than or equal to the provided value.
3898
-
3899
- Example
3753
+ Call on a computed property to set it into read-only mode. When in this
3754
+ mode the computed property will throw an error when set.
3900
3755
 
3901
3756
  ```javascript
3902
- var Hamster = Ember.Object.extend({
3903
- needsMoreBananas: Ember.computed.lte('numBananas', 3)
3757
+ var Person = Ember.Object.extend({
3758
+ guid: function() {
3759
+ return 'guid-guid-guid';
3760
+ }.property().readOnly()
3904
3761
  });
3905
3762
 
3906
- var hamster = Hamster.create();
3763
+ var person = Person.create();
3907
3764
 
3908
- hamster.get('needsMoreBananas'); // true
3909
- hamster.set('numBananas', 5);
3910
- hamster.get('needsMoreBananas'); // false
3911
- hamster.set('numBananas', 3);
3912
- hamster.get('needsMoreBananas'); // true
3765
+ person.set('guid', 'new-guid'); // will throw an exception
3913
3766
  ```
3914
3767
 
3915
- @method lte
3916
- @for Ember.computed
3917
- @param {String} dependentKey
3918
- @param {Number} value
3919
- @return {Ember.ComputedProperty} computed property which returns true if
3920
- the original value for property is less or equal than given value.
3768
+ @method readOnly
3769
+ @return {Ember.ComputedProperty} this
3770
+ @chainable
3921
3771
  @public
3922
3772
  */
3923
-
3924
- function lte(dependentKey, value) {
3925
- return _emberMetalComputed.computed(dependentKey, function () {
3926
- return _emberMetalProperty_get.get(this, dependentKey) <= value;
3927
- });
3928
- }
3773
+ ComputedPropertyPrototype.readOnly = function () {
3774
+ this._readOnly = true;
3775
+ _emberMetalCore.default.assert('Computed properties that define a setter using the new syntax cannot be read-only', !(this._readOnly && this._setter && this._setter !== this._getter));
3776
+ return this;
3777
+ };
3929
3778
 
3930
3779
  /**
3931
- A computed property that performs a logical `and` on the
3932
- original values for the provided dependent properties.
3933
-
3934
- Example
3780
+ Sets the dependent keys on this computed property. Pass any number of
3781
+ arguments containing key paths that this computed property depends on.
3935
3782
 
3936
3783
  ```javascript
3937
- var Hamster = Ember.Object.extend({
3938
- readyForCamp: Ember.computed.and('hasTent', 'hasBackpack')
3784
+ var President = Ember.Object.extend({
3785
+ fullName: computed(function() {
3786
+ return this.get('firstName') + ' ' + this.get('lastName');
3787
+
3788
+ // Tell Ember that this computed property depends on firstName
3789
+ // and lastName
3790
+ }).property('firstName', 'lastName')
3939
3791
  });
3940
3792
 
3941
- var hamster = Hamster.create();
3793
+ var president = President.create({
3794
+ firstName: 'Barack',
3795
+ lastName: 'Obama'
3796
+ });
3942
3797
 
3943
- hamster.get('readyForCamp'); // false
3944
- hamster.set('hasTent', true);
3945
- hamster.get('readyForCamp'); // false
3946
- hamster.set('hasBackpack', true);
3947
- hamster.get('readyForCamp'); // true
3948
- hamster.set('hasBackpack', 'Yes');
3949
- hamster.get('readyForCamp'); // 'Yes'
3798
+ president.get('fullName'); // 'Barack Obama'
3950
3799
  ```
3951
3800
 
3952
- @method and
3953
- @for Ember.computed
3954
- @param {String} dependentKey*
3955
- @return {Ember.ComputedProperty} computed property which performs
3956
- a logical `and` on the values of all the original values for properties.
3801
+ @method property
3802
+ @param {String} path* zero or more property paths
3803
+ @return {Ember.ComputedProperty} this
3804
+ @chainable
3957
3805
  @public
3958
3806
  */
3959
- var and = generateComputedWithProperties(function (properties) {
3960
- var value;
3961
- for (var key in properties) {
3962
- value = properties[key];
3963
- if (properties.hasOwnProperty(key) && !value) {
3964
- return false;
3965
- }
3807
+ ComputedPropertyPrototype.property = function () {
3808
+ var args;
3809
+
3810
+ var addArg = function (property) {
3811
+ _emberMetalCore.default.assert('Depending on arrays using a dependent key ending with `@each` is no longer supported. ' + ('Please refactor from `Ember.computed(\'' + property + '\', function() {});` to `Ember.computed(\'' + property.slice(0, -6) + '.[]\', function() {})`.'), property.slice(-5) !== '@each');
3812
+ args.push(property);
3813
+ };
3814
+
3815
+ args = [];
3816
+ for (var i = 0, l = arguments.length; i < l; i++) {
3817
+ _emberMetalExpand_properties.default(arguments[i], addArg);
3966
3818
  }
3967
- return value;
3968
- });
3969
3819
 
3970
- exports.and = and;
3820
+ this._dependentKeys = args;
3821
+ return this;
3822
+ };
3823
+
3971
3824
  /**
3972
- A computed property which performs a logical `or` on the
3973
- original values for the provided dependent properties.
3974
-
3975
- Example
3976
-
3977
- ```javascript
3978
- var Hamster = Ember.Object.extend({
3979
- readyForRain: Ember.computed.or('hasJacket', 'hasUmbrella')
3980
- });
3825
+ In some cases, you may want to annotate computed properties with additional
3826
+ metadata about how they function or what values they operate on. For example,
3827
+ computed property functions may close over variables that are then no longer
3828
+ available for introspection.
3981
3829
 
3982
- var hamster = Hamster.create();
3830
+ You can pass a hash of these values to a computed property like this:
3983
3831
 
3984
- hamster.get('readyForRain'); // false
3985
- hamster.set('hasUmbrella', true);
3986
- hamster.get('readyForRain'); // true
3987
- hamster.set('hasJacket', 'Yes');
3988
- hamster.get('readyForRain'); // 'Yes'
3832
+ ```
3833
+ person: function() {
3834
+ var personId = this.get('personId');
3835
+ return App.Person.create({ id: personId });
3836
+ }.property().meta({ type: App.Person })
3989
3837
  ```
3990
3838
 
3991
- @method or
3992
- @for Ember.computed
3993
- @param {String} dependentKey*
3994
- @return {Ember.ComputedProperty} computed property which performs
3995
- a logical `or` on the values of all the original values for properties.
3839
+ The hash that you pass to the `meta()` function will be saved on the
3840
+ computed property descriptor under the `_meta` key. Ember runtime
3841
+ exposes a public API for retrieving these values from classes,
3842
+ via the `metaForProperty()` function.
3843
+
3844
+ @method meta
3845
+ @param {Object} meta
3846
+ @chainable
3996
3847
  @public
3997
3848
  */
3998
- var or = generateComputedWithProperties(function (properties) {
3999
- var value;
4000
- for (var key in properties) {
4001
- value = properties[key];
4002
- if (properties.hasOwnProperty(key) && value) {
4003
- return value;
4004
- }
3849
+
3850
+ ComputedPropertyPrototype.meta = function (meta) {
3851
+ if (arguments.length === 0) {
3852
+ return this._meta || {};
3853
+ } else {
3854
+ this._meta = meta;
3855
+ return this;
4005
3856
  }
4006
- return value;
4007
- });
3857
+ };
3858
+
3859
+ // invalidate cache when CP key changes
3860
+ ComputedPropertyPrototype.didChange = function (obj, keyName) {
3861
+ // _suspended is set via a CP.set to ensure we don't clear
3862
+ // the cached value set by the setter
3863
+ if (this._volatile || this._suspended === obj) {
3864
+ return;
3865
+ }
3866
+
3867
+ // don't create objects just to invalidate
3868
+ var meta = obj.__ember_meta__;
3869
+ if (!meta || meta.source !== obj) {
3870
+ return;
3871
+ }
3872
+
3873
+ var cache = meta.readableCache();
3874
+ if (cache && cache[keyName] !== undefined) {
3875
+ cache[keyName] = undefined;
3876
+ _emberMetalDependent_keys.removeDependentKeys(this, obj, keyName, meta);
3877
+ }
3878
+ };
4008
3879
 
4009
- exports.or = or;
4010
3880
  /**
4011
- A computed property that returns the array of values
4012
- for the provided dependent properties.
4013
-
4014
- Example
3881
+ Access the value of the function backing the computed property.
3882
+ If this property has already been cached, return the cached result.
3883
+ Otherwise, call the function passing the property name as an argument.
4015
3884
 
4016
3885
  ```javascript
4017
- var Hamster = Ember.Object.extend({
4018
- clothes: Ember.computed.collect('hat', 'shirt')
3886
+ var Person = Ember.Object.extend({
3887
+ fullName: function(keyName) {
3888
+ // the keyName parameter is 'fullName' in this case.
3889
+ return this.get('firstName') + ' ' + this.get('lastName');
3890
+ }.property('firstName', 'lastName')
4019
3891
  });
4020
3892
 
4021
- var hamster = Hamster.create();
4022
3893
 
4023
- hamster.get('clothes'); // [null, null]
4024
- hamster.set('hat', 'Camp Hat');
4025
- hamster.set('shirt', 'Camp Shirt');
4026
- hamster.get('clothes'); // ['Camp Hat', 'Camp Shirt']
3894
+ var tom = Person.create({
3895
+ firstName: 'Tom',
3896
+ lastName: 'Dale'
3897
+ });
3898
+
3899
+ tom.get('fullName') // 'Tom Dale'
4027
3900
  ```
4028
3901
 
4029
- @method collect
4030
- @for Ember.computed
4031
- @param {String} dependentKey*
4032
- @return {Ember.ComputedProperty} computed property which maps
4033
- values of all passed in properties to an array.
3902
+ @method get
3903
+ @param {String} keyName The key being accessed.
3904
+ @return {Object} The return value of the function backing the CP.
4034
3905
  @public
4035
3906
  */
4036
- var collect = generateComputedWithProperties(function (properties) {
4037
- var res = _emberMetalCore.default.A();
4038
- for (var key in properties) {
4039
- if (properties.hasOwnProperty(key)) {
4040
- if (_emberMetalIs_none.default(properties[key])) {
4041
- res.push(null);
4042
- } else {
4043
- res.push(properties[key]);
4044
- }
4045
- }
3907
+ ComputedPropertyPrototype.get = function (obj, keyName) {
3908
+ if (this._volatile) {
3909
+ return this._getter.call(obj, keyName);
4046
3910
  }
4047
- return res;
4048
- });
4049
3911
 
4050
- exports.collect = collect;
3912
+ var meta = metaFor(obj);
3913
+ var cache = meta.writableCache();
3914
+
3915
+ var result = cache[keyName];
3916
+ if (result === UNDEFINED) {
3917
+ return undefined;
3918
+ } else if (result !== undefined) {
3919
+ return result;
3920
+ }
3921
+
3922
+ var ret = this._getter.call(obj, keyName);
3923
+ if (ret === undefined) {
3924
+ cache[keyName] = UNDEFINED;
3925
+ } else {
3926
+ cache[keyName] = ret;
3927
+ }
3928
+
3929
+ var chainWatchers = meta.readableChainWatchers();
3930
+ if (chainWatchers) {
3931
+ chainWatchers.revalidate(keyName);
3932
+ }
3933
+ _emberMetalDependent_keys.addDependentKeys(this, obj, keyName, meta);
3934
+
3935
+ return ret;
3936
+ };
3937
+
4051
3938
  /**
4052
- Creates a new property that is an alias for another property
4053
- on an object. Calls to `get` or `set` this property behave as
4054
- though they were called on the original property.
3939
+ Set the value of a computed property. If the function that backs your
3940
+ computed property does not accept arguments then the default action for
3941
+ setting would be to define the property on the current object, and set
3942
+ the value of the property to the value being set.
3943
+
3944
+ Generally speaking if you intend for your computed property to be set
3945
+ your backing function should accept either two or three arguments.
4055
3946
 
4056
3947
  ```javascript
4057
3948
  var Person = Ember.Object.extend({
4058
- name: 'Alex Matchneer',
4059
- nomen: Ember.computed.alias('name')
4060
- });
4061
-
4062
- var alex = Person.create();
3949
+ // these will be supplied by `create`
3950
+ firstName: null,
3951
+ lastName: null,
4063
3952
 
4064
- alex.get('nomen'); // 'Alex Matchneer'
4065
- alex.get('name'); // 'Alex Matchneer'
3953
+ fullName: function(key, value, oldValue) {
3954
+ // getter
3955
+ if (arguments.length === 1) {
3956
+ var firstName = this.get('firstName');
3957
+ var lastName = this.get('lastName');
4066
3958
 
4067
- alex.set('nomen', '@machty');
4068
- alex.get('name'); // '@machty'
4069
- ```
3959
+ return firstName + ' ' + lastName;
4070
3960
 
4071
- @method alias
4072
- @for Ember.computed
4073
- @param {String} dependentKey
4074
- @return {Ember.ComputedProperty} computed property which creates an
4075
- alias to the original value for property.
4076
- @public
4077
- */
4078
-
4079
- /**
4080
- Where `computed.alias` aliases `get` and `set`, and allows for bidirectional
4081
- data flow, `computed.oneWay` only provides an aliased `get`. The `set` will
4082
- not mutate the upstream property, rather causes the current property to
4083
- become the value set. This causes the downstream property to permanently
4084
- diverge from the upstream property.
3961
+ // setter
3962
+ } else {
3963
+ var name = value.split(' ');
4085
3964
 
4086
- Example
3965
+ this.set('firstName', name[0]);
3966
+ this.set('lastName', name[1]);
4087
3967
 
4088
- ```javascript
4089
- var User = Ember.Object.extend({
4090
- firstName: null,
4091
- lastName: null,
4092
- nickName: Ember.computed.oneWay('firstName')
3968
+ return value;
3969
+ }
3970
+ }.property('firstName', 'lastName')
4093
3971
  });
4094
3972
 
4095
- var teddy = User.create({
4096
- firstName: 'Teddy',
4097
- lastName: 'Zeenny'
4098
- });
3973
+ var person = Person.create();
4099
3974
 
4100
- teddy.get('nickName'); // 'Teddy'
4101
- teddy.set('nickName', 'TeddyBear'); // 'TeddyBear'
4102
- teddy.get('firstName'); // 'Teddy'
3975
+ person.set('fullName', 'Peter Wagenet');
3976
+ person.get('firstName'); // 'Peter'
3977
+ person.get('lastName'); // 'Wagenet'
4103
3978
  ```
4104
3979
 
4105
- @method oneWay
4106
- @for Ember.computed
4107
- @param {String} dependentKey
4108
- @return {Ember.ComputedProperty} computed property which creates a
4109
- one way computed property to the original value for property.
3980
+ @method set
3981
+ @param {String} keyName The key being accessed.
3982
+ @param {Object} newValue The new value being assigned.
3983
+ @param {String} oldValue The old value being replaced.
3984
+ @return {Object} The return value of the function backing the CP.
4110
3985
  @public
4111
3986
  */
3987
+ ComputedPropertyPrototype.set = function computedPropertySetEntry(obj, keyName, value) {
3988
+ if (this._readOnly) {
3989
+ this._throwReadOnlyError(obj, keyName);
3990
+ }
4112
3991
 
4113
- function oneWay(dependentKey) {
4114
- return _emberMetalAlias.default(dependentKey).oneWay();
4115
- }
3992
+ if (!this._setter) {
3993
+ return this.clobberSet(obj, keyName, value);
3994
+ }
4116
3995
 
4117
- /**
4118
- This is a more semantically meaningful alias of `computed.oneWay`,
4119
- whose name is somewhat ambiguous as to which direction the data flows.
4120
-
4121
- @method reads
4122
- @for Ember.computed
4123
- @param {String} dependentKey
4124
- @return {Ember.ComputedProperty} computed property which creates a
4125
- one way computed property to the original value for property.
4126
- @public
4127
- */
3996
+ if (this._volatile) {
3997
+ return this.volatileSet(obj, keyName, value);
3998
+ }
3999
+
4000
+ return this.setWithSuspend(obj, keyName, value);
4001
+ };
4002
+
4003
+ ComputedPropertyPrototype._throwReadOnlyError = function computedPropertyThrowReadOnlyError(obj, keyName) {
4004
+ throw new _emberMetalError.default('Cannot set read-only property "' + keyName + '" on object: ' + _emberMetalUtils.inspect(obj));
4005
+ };
4006
+
4007
+ ComputedPropertyPrototype.clobberSet = function computedPropertyClobberSet(obj, keyName, value) {
4008
+ var cachedValue = cacheFor(obj, keyName);
4009
+ _emberMetalProperties.defineProperty(obj, keyName, null, cachedValue);
4010
+ _emberMetalProperty_set.set(obj, keyName, value);
4011
+ return value;
4012
+ };
4013
+
4014
+ ComputedPropertyPrototype.volatileSet = function computedPropertyVolatileSet(obj, keyName, value) {
4015
+ return this._setter.call(obj, keyName, value);
4016
+ };
4017
+
4018
+ ComputedPropertyPrototype.setWithSuspend = function computedPropertySetWithSuspend(obj, keyName, value) {
4019
+ var oldSuspended = this._suspended;
4020
+ this._suspended = obj;
4021
+ try {
4022
+ return this._set(obj, keyName, value);
4023
+ } finally {
4024
+ this._suspended = oldSuspended;
4025
+ }
4026
+ };
4027
+
4028
+ ComputedPropertyPrototype._set = function computedPropertySet(obj, keyName, value) {
4029
+ // cache requires own meta
4030
+ var meta = metaFor(obj);
4031
+ // either there is a writable cache or we need one to update
4032
+ var cache = meta.writableCache();
4033
+ var hadCachedValue = false;
4034
+ var cachedValue = undefined;
4035
+ if (cache[keyName] !== undefined) {
4036
+ if (cache[keyName] !== UNDEFINED) {
4037
+ cachedValue = cache[keyName];
4038
+ }
4039
+ hadCachedValue = true;
4040
+ }
4041
+
4042
+ var ret = this._setter.call(obj, keyName, value, cachedValue);
4043
+
4044
+ // allows setter to return the same value that is cached already
4045
+ if (hadCachedValue && cachedValue === ret) {
4046
+ return ret;
4047
+ }
4048
+
4049
+ var watched = meta.peekWatching(keyName);
4050
+ if (watched) {
4051
+ _emberMetalProperty_events.propertyWillChange(obj, keyName);
4052
+ }
4053
+
4054
+ if (hadCachedValue) {
4055
+ cache[keyName] = undefined;
4056
+ }
4057
+
4058
+ if (!hadCachedValue) {
4059
+ _emberMetalDependent_keys.addDependentKeys(this, obj, keyName, meta);
4060
+ }
4061
+
4062
+ if (ret === undefined) {
4063
+ cache[keyName] = UNDEFINED;
4064
+ } else {
4065
+ cache[keyName] = ret;
4066
+ }
4067
+
4068
+ if (watched) {
4069
+ _emberMetalProperty_events.propertyDidChange(obj, keyName);
4070
+ }
4071
+
4072
+ return ret;
4073
+ };
4074
+
4075
+ /* called before property is overridden */
4076
+ ComputedPropertyPrototype.teardown = function (obj, keyName) {
4077
+ if (this._volatile) {
4078
+ return;
4079
+ }
4080
+ var meta = metaFor(obj);
4081
+ var cache = meta.readableCache();
4082
+ if (cache && cache[keyName] !== undefined) {
4083
+ _emberMetalDependent_keys.removeDependentKeys(this, obj, keyName, meta);
4084
+ cache[keyName] = undefined;
4085
+ }
4086
+ };
4128
4087
 
4129
4088
  /**
4130
- Where `computed.oneWay` provides oneWay bindings, `computed.readOnly` provides
4131
- a readOnly one way binding. Very often when using `computed.oneWay` one does
4132
- not also want changes to propagate back up, as they will replace the value.
4089
+ This helper returns a new property descriptor that wraps the passed
4090
+ computed property function. You can use this helper to define properties
4091
+ with mixins or via `Ember.defineProperty()`.
4133
4092
 
4134
- This prevents the reverse flow, and also throws an exception when it occurs.
4093
+ The function you pass will be used to both get and set property values.
4094
+ The function should accept two parameters, key and value. If value is not
4095
+ undefined you should set the value first. In either case return the
4096
+ current value of the property.
4135
4097
 
4136
- Example
4098
+ A computed property defined in this way might look like this:
4137
4099
 
4138
- ```javascript
4139
- var User = Ember.Object.extend({
4140
- firstName: null,
4141
- lastName: null,
4142
- nickName: Ember.computed.readOnly('firstName')
4143
- });
4100
+ ```js
4101
+ var Person = Ember.Object.extend({
4102
+ firstName: 'Betty',
4103
+ lastName: 'Jones',
4144
4104
 
4145
- var teddy = User.create({
4146
- firstName: 'Teddy',
4147
- lastName: 'Zeenny'
4105
+ fullName: Ember.computed('firstName', 'lastName', function(key, value) {
4106
+ return this.get('firstName') + ' ' + this.get('lastName');
4107
+ })
4148
4108
  });
4149
4109
 
4150
- teddy.get('nickName'); // 'Teddy'
4151
- teddy.set('nickName', 'TeddyBear'); // throws Exception
4152
- // throw new Ember.Error('Cannot Set: nickName on: <User:ember27288>' );`
4153
- teddy.get('firstName'); // 'Teddy'
4110
+ var client = Person.create();
4111
+
4112
+ client.get('fullName'); // 'Betty Jones'
4113
+
4114
+ client.set('lastName', 'Fuller');
4115
+ client.get('fullName'); // 'Betty Fuller'
4154
4116
  ```
4155
4117
 
4156
- @method readOnly
4157
- @for Ember.computed
4158
- @param {String} dependentKey
4159
- @return {Ember.ComputedProperty} computed property which creates a
4160
- one way computed property to the original value for property.
4161
- @since 1.5.0
4118
+ _Note: This is the preferred way to define computed properties when writing third-party
4119
+ libraries that depend on or use Ember, since there is no guarantee that the user
4120
+ will have prototype extensions enabled._
4121
+
4122
+ You might use this method if you disabled
4123
+ [Prototype Extensions](http://emberjs.com/guides/configuring-ember/disabling-prototype-extensions/).
4124
+ The alternative syntax might look like this
4125
+ (if prototype extensions are enabled, which is the default behavior):
4126
+
4127
+ ```js
4128
+ fullName: function () {
4129
+ return this.get('firstName') + ' ' + this.get('lastName');
4130
+ }.property('firstName', 'lastName')
4131
+ ```
4132
+
4133
+ @class computed
4134
+ @namespace Ember
4135
+ @constructor
4136
+ @static
4137
+ @param {String} [dependentKeys*] Optional dependent keys that trigger this computed property.
4138
+ @param {Function} func The computed property function.
4139
+ @return {Ember.ComputedProperty} property descriptor instance
4162
4140
  @public
4163
4141
  */
4164
4142
 
4165
- function readOnly(dependentKey) {
4166
- return _emberMetalAlias.default(dependentKey).readOnly();
4143
+ function computed(func) {
4144
+ var args;
4145
+
4146
+ if (arguments.length > 1) {
4147
+ args = [].slice.call(arguments);
4148
+ func = args.pop();
4149
+ }
4150
+
4151
+ var cp = new ComputedProperty(func);
4152
+
4153
+ if (args) {
4154
+ cp.property.apply(cp, args);
4155
+ }
4156
+
4157
+ return cp;
4167
4158
  }
4168
4159
 
4169
4160
  /**
4170
- Creates a new property that is an alias for another property
4171
- on an object. Calls to `get` or `set` this property behave as
4172
- though they were called on the original property, but also
4173
- print a deprecation warning.
4161
+ Returns the cached value for a property, if one exists.
4162
+ This can be useful for peeking at the value of a computed
4163
+ property that is generated lazily, without accidentally causing
4164
+ it to be created.
4174
4165
 
4175
- @method deprecatingAlias
4176
- @for Ember.computed
4177
- @param {String} dependentKey
4178
- @return {Ember.ComputedProperty} computed property which creates an
4179
- alias with a deprecation to the original value for property.
4180
- @since 1.7.0
4166
+ @method cacheFor
4167
+ @for Ember
4168
+ @param {Object} obj the object whose property you want to check
4169
+ @param {String} key the name of the property whose cached value you want
4170
+ to return
4171
+ @return {Object} the cached value
4181
4172
  @public
4182
4173
  */
4174
+ function cacheFor(obj, key) {
4175
+ var meta = obj.__ember_meta__;
4176
+ var cache = meta && meta.source === obj && meta.readableCache();
4177
+ var ret = cache && cache[key];
4183
4178
 
4184
- function deprecatingAlias(dependentKey, options) {
4185
- return _emberMetalComputed.computed(dependentKey, {
4186
- get: function (key) {
4187
- _emberMetalCore.default.deprecate('Usage of `' + key + '` is deprecated, use `' + dependentKey + '` instead.', false, options);
4188
- return _emberMetalProperty_get.get(this, dependentKey);
4189
- },
4190
- set: function (key, value) {
4191
- _emberMetalCore.default.deprecate('Usage of `' + key + '` is deprecated, use `' + dependentKey + '` instead.', false, options);
4192
- _emberMetalProperty_set.set(this, dependentKey, value);
4193
- return value;
4194
- }
4195
- });
4179
+ if (ret === UNDEFINED) {
4180
+ return undefined;
4181
+ }
4182
+ return ret;
4196
4183
  }
4184
+
4185
+ cacheFor.set = function (cache, key, value) {
4186
+ if (value === undefined) {
4187
+ cache[key] = UNDEFINED;
4188
+ } else {
4189
+ cache[key] = value;
4190
+ }
4191
+ };
4192
+
4193
+ cacheFor.get = function (cache, key) {
4194
+ var ret = cache[key];
4195
+ if (ret === UNDEFINED) {
4196
+ return undefined;
4197
+ }
4198
+ return ret;
4199
+ };
4200
+
4201
+ cacheFor.remove = function (cache, key) {
4202
+ cache[key] = undefined;
4203
+ };
4204
+
4205
+ exports.ComputedProperty = ComputedProperty;
4206
+ exports.computed = computed;
4207
+ exports.cacheFor = cacheFor;
4197
4208
  });
4198
4209
  enifed('ember-metal/core', ['exports', 'ember-metal/assert'], function (exports, _emberMetalAssert) {
4199
4210
  /*globals Ember:true,ENV,EmberENV */
@@ -4218,7 +4229,7 @@ enifed('ember-metal/core', ['exports', 'ember-metal/assert'], function (exports,
4218
4229
 
4219
4230
  @class Ember
4220
4231
  @static
4221
- @version 2.1.0-beta.1
4232
+ @version 2.1.0-beta.3
4222
4233
  @public
4223
4234
  */
4224
4235
 
@@ -4252,11 +4263,11 @@ enifed('ember-metal/core', ['exports', 'ember-metal/assert'], function (exports,
4252
4263
 
4253
4264
  @property VERSION
4254
4265
  @type String
4255
- @default '2.1.0-beta.1'
4266
+ @default '2.1.0-beta.3'
4256
4267
  @static
4257
4268
  @public
4258
4269
  */
4259
- Ember.VERSION = '2.1.0-beta.1';
4270
+ Ember.VERSION = '2.1.0-beta.3';
4260
4271
 
4261
4272
  /**
4262
4273
  The hash of environment variables used to control various configuration
@@ -6346,21 +6357,194 @@ enifed('ember-metal/merge', ['exports'], function (exports) {
6346
6357
 
6347
6358
  exports.default = merge;
6348
6359
 
6349
- function merge(original, updates) {
6350
- if (!updates || typeof updates !== 'object') {
6351
- return original;
6360
+ function merge(original, updates) {
6361
+ if (!updates || typeof updates !== 'object') {
6362
+ return original;
6363
+ }
6364
+
6365
+ var props = Object.keys(updates);
6366
+ var prop;
6367
+ var length = props.length;
6368
+
6369
+ for (var i = 0; i < length; i++) {
6370
+ prop = props[i];
6371
+ original[prop] = updates[prop];
6372
+ }
6373
+
6374
+ return original;
6375
+ }
6376
+ });
6377
+ enifed('ember-metal/meta_listeners', ['exports'], function (exports) {
6378
+ /*
6379
+ When we render a rich template hierarchy, the set of events that
6380
+ *might* happen tends to be much larger than the set of events that
6381
+ actually happen. This implies that we should make listener creation &
6382
+ destruction cheap, even at the cost of making event dispatch more
6383
+ expensive.
6384
+
6385
+ Thus we store a new listener with a single push and no new
6386
+ allocations, without even bothering to do deduplication -- we can
6387
+ save that for dispatch time, if an event actually happens.
6388
+ */
6389
+
6390
+ /* listener flags */
6391
+ 'use strict';
6392
+
6393
+ var ONCE = 1;
6394
+ exports.ONCE = ONCE;
6395
+ var SUSPENDED = 2;
6396
+
6397
+ exports.SUSPENDED = SUSPENDED;
6398
+ var protoMethods = {
6399
+
6400
+ addToListeners: function (eventName, target, method, flags) {
6401
+ if (!this._listeners) {
6402
+ this._listeners = [];
6403
+ }
6404
+ this._listeners.push(eventName, target, method, flags);
6405
+ },
6406
+
6407
+ _finalizeListeners: function () {
6408
+ if (this._listenersFinalized) {
6409
+ return;
6410
+ }
6411
+ if (!this._listeners) {
6412
+ this._listeners = [];
6413
+ }
6414
+ var pointer = this.parent;
6415
+ while (pointer) {
6416
+ var listeners = pointer._listeners;
6417
+ if (listeners) {
6418
+ this._listeners = this._listeners.concat(listeners);
6419
+ }
6420
+ if (pointer._listenersFinalized) {
6421
+ break;
6422
+ }
6423
+ pointer = pointer.parent;
6424
+ }
6425
+ this._listenersFinalized = true;
6426
+ },
6427
+
6428
+ removeFromListeners: function (eventName, target, method, didRemove) {
6429
+ var pointer = this;
6430
+ while (pointer) {
6431
+ var listeners = pointer._listeners;
6432
+ if (listeners) {
6433
+ for (var index = listeners.length - 4; index >= 0; index -= 4) {
6434
+ if (listeners[index] === eventName && (!method || listeners[index + 1] === target && listeners[index + 2] === method)) {
6435
+ if (pointer === this) {
6436
+ // we are modifying our own list, so we edit directly
6437
+ if (typeof didRemove === 'function') {
6438
+ didRemove(eventName, target, listeners[index + 2]);
6439
+ }
6440
+ listeners.splice(index, 4);
6441
+ } else {
6442
+ // we are trying to remove an inherited listener, so we do
6443
+ // just-in-time copying to detach our own listeners from
6444
+ // our inheritance chain.
6445
+ this._finalizeListeners();
6446
+ return this.removeFromListeners(eventName, target, method);
6447
+ }
6448
+ }
6449
+ }
6450
+ }
6451
+ if (pointer._listenersFinalized) {
6452
+ break;
6453
+ }
6454
+ pointer = pointer.parent;
6455
+ }
6456
+ },
6457
+
6458
+ matchingListeners: function (eventName) {
6459
+ var pointer = this;
6460
+ var result = [];
6461
+ while (pointer) {
6462
+ var listeners = pointer._listeners;
6463
+ if (listeners) {
6464
+ for (var index = 0; index < listeners.length - 3; index += 4) {
6465
+ if (listeners[index] === eventName) {
6466
+ pushUniqueListener(result, listeners, index);
6467
+ }
6468
+ }
6469
+ }
6470
+ if (pointer._listenersFinalized) {
6471
+ break;
6472
+ }
6473
+ pointer = pointer.parent;
6474
+ }
6475
+ var sus = this._suspendedListeners;
6476
+ if (sus) {
6477
+ for (var susIndex = 0; susIndex < sus.length - 2; susIndex += 3) {
6478
+ if (eventName === sus[susIndex]) {
6479
+ for (var resultIndex = 0; resultIndex < result.length - 2; resultIndex += 3) {
6480
+ if (result[resultIndex] === sus[susIndex + 1] && result[resultIndex + 1] === sus[susIndex + 2]) {
6481
+ result[resultIndex + 2] |= SUSPENDED;
6482
+ }
6483
+ }
6484
+ }
6485
+ }
6486
+ }
6487
+ return result;
6488
+ },
6489
+
6490
+ suspendListeners: function (eventNames, target, method, callback) {
6491
+ var sus = this._suspendedListeners;
6492
+ if (!sus) {
6493
+ sus = this._suspendedListeners = [];
6494
+ }
6495
+ for (var i = 0; i < eventNames.length; i++) {
6496
+ sus.push(eventNames[i], target, method);
6497
+ }
6498
+ try {
6499
+ return callback.call(target);
6500
+ } finally {
6501
+ if (sus.length === eventNames.length) {
6502
+ this._suspendedListeners = undefined;
6503
+ } else {
6504
+ for (var i = sus.length - 3; i >= 0; i -= 3) {
6505
+ if (sus[i + 1] === target && sus[i + 2] === method && eventNames.indexOf(sus[i]) !== -1) {
6506
+ sus.splice(i, 3);
6507
+ }
6508
+ }
6509
+ }
6510
+ }
6511
+ },
6512
+
6513
+ watchedEvents: function () {
6514
+ var pointer = this;
6515
+ var names = {};
6516
+ while (pointer) {
6517
+ var listeners = pointer._listeners;
6518
+ if (listeners) {
6519
+ for (var index = 0; index < listeners.length - 3; index += 4) {
6520
+ names[listeners[index]] = true;
6521
+ }
6522
+ }
6523
+ if (pointer._listenersFinalized) {
6524
+ break;
6525
+ }
6526
+ pointer = pointer.parent;
6527
+ }
6528
+ return Object.keys(names);
6529
+ },
6530
+
6531
+ _initializeListeners: function () {
6532
+ this._listeners = undefined;
6533
+ this._listenersFinalized = undefined;
6534
+ this._suspendedListeners = undefined;
6352
6535
  }
6536
+ };
6353
6537
 
6354
- var props = Object.keys(updates);
6355
- var prop;
6356
- var length = props.length;
6357
-
6358
- for (var i = 0; i < length; i++) {
6359
- prop = props[i];
6360
- original[prop] = updates[prop];
6538
+ exports.protoMethods = protoMethods;
6539
+ function pushUniqueListener(destination, source, index) {
6540
+ var target = source[index + 1];
6541
+ var method = source[index + 2];
6542
+ for (var destinationIndex = 0; destinationIndex < destination.length - 2; destinationIndex += 3) {
6543
+ if (destination[destinationIndex] === target && destination[destinationIndex + 1] === method) {
6544
+ return;
6545
+ }
6361
6546
  }
6362
-
6363
- return original;
6547
+ destination.push(target, method, source[index + 3]);
6364
6548
  }
6365
6549
  });
6366
6550
  enifed('ember-metal/meta', ['exports', 'ember-metal/features', 'ember-metal/meta_listeners', 'ember-metal/empty_object'], function (exports, _emberMetalFeatures, _emberMetalMeta_listeners, _emberMetalEmpty_object) {
@@ -6556,278 +6740,105 @@ enifed('ember-metal/meta', ['exports', 'ember-metal/features', 'ember-metal/meta
6556
6740
  };
6557
6741
  }
6558
6742
 
6559
- // Implements a member that provides an inheritable, lazily-created
6560
- // object using the method you provide. We will derived children from
6561
- // their parents by calling your object's `copy()` method.
6562
- function inheritedCustomObject(name, Meta) {
6563
- var key = memberProperty(name);
6564
- var capitalized = capitalize(name);
6565
- Meta.prototype['writable' + capitalized] = function (create) {
6566
- var ret = this[key];
6567
- if (!ret) {
6568
- if (this.parent) {
6569
- ret = this[key] = this.parent['writable' + capitalized](create).copy(this.source);
6570
- } else {
6571
- ret = this[key] = create(this.source);
6572
- }
6573
- }
6574
- return ret;
6575
- };
6576
- Meta.prototype['readable' + capitalized] = function () {
6577
- return this._getInherited(key);
6578
- };
6579
- }
6580
-
6581
- function memberProperty(name) {
6582
- return '_' + name;
6583
- }
6584
-
6585
- // there's a more general-purpose capitalize in ember-runtime, but we
6586
- // don't want to make ember-metal depend on ember-runtime.
6587
- function capitalize(name) {
6588
- return name.replace(/^\w/, function (m) {
6589
- return m.toUpperCase();
6590
- });
6591
- }
6592
-
6593
- var META_DESC = {
6594
- writable: true,
6595
- configurable: true,
6596
- enumerable: false,
6597
- value: null
6598
- };
6599
-
6600
- exports.META_DESC = META_DESC;
6601
- var EMBER_META_PROPERTY = {
6602
- name: '__ember_meta__',
6603
- descriptor: META_DESC
6604
- };
6605
-
6606
- // Placeholder for non-writable metas.
6607
- var EMPTY_META = new Meta(null);
6608
-
6609
- exports.EMPTY_META = EMPTY_META;
6610
-
6611
- EMPTY_META.writableValues();
6612
-
6613
- /**
6614
- Retrieves the meta hash for an object. If `writable` is true ensures the
6615
- hash is writable for this object as well.
6616
-
6617
- The meta object contains information about computed property descriptors as
6618
- well as any watched properties and other information. You generally will
6619
- not access this information directly but instead work with higher level
6620
- methods that manipulate this hash indirectly.
6621
-
6622
- @method meta
6623
- @for Ember
6624
- @private
6625
-
6626
- @param {Object} obj The object to retrieve meta for
6627
- @param {Boolean} [writable=true] Pass `false` if you do not intend to modify
6628
- the meta hash, allowing the method to avoid making an unnecessary copy.
6629
- @return {Object} the meta hash for an object
6630
- */
6631
-
6632
- function meta(obj, writable) {
6633
- var ret = obj.__ember_meta__;
6634
- if (writable === false) {
6635
- return ret || EMPTY_META;
6636
- }
6637
-
6638
- if (ret && ret.source === obj) {
6639
- return ret;
6640
- }
6641
-
6642
- if (!ret) {
6643
- ret = new Meta(obj);
6644
-
6645
- ret.writableValues();
6646
- } else {
6647
- ret = new Meta(obj, ret);
6648
- }
6649
-
6650
- if (obj.__defineNonEnumerable) {
6651
- obj.__defineNonEnumerable(EMBER_META_PROPERTY);
6652
- } else {
6653
- Object.defineProperty(obj, '__ember_meta__', META_DESC);
6654
- }
6655
- obj.__ember_meta__ = ret;
6656
-
6657
- return ret;
6658
- }
6659
- });
6660
- enifed('ember-metal/meta_listeners', ['exports'], function (exports) {
6661
- /*
6662
- When we render a rich template hierarchy, the set of events that
6663
- *might* happen tends to be much larger than the set of events that
6664
- actually happen. This implies that we should make listener creation &
6665
- destruction cheap, even at the cost of making event dispatch more
6666
- expensive.
6667
-
6668
- Thus we store a new listener with a single push and no new
6669
- allocations, without even bothering to do deduplication -- we can
6670
- save that for dispatch time, if an event actually happens.
6671
- */
6672
-
6673
- /* listener flags */
6674
- 'use strict';
6675
-
6676
- var ONCE = 1;
6677
- exports.ONCE = ONCE;
6678
- var SUSPENDED = 2;
6679
-
6680
- exports.SUSPENDED = SUSPENDED;
6681
- var protoMethods = {
6682
-
6683
- addToListeners: function (eventName, target, method, flags) {
6684
- if (!this._listeners) {
6685
- this._listeners = [];
6686
- }
6687
- this._listeners.push(eventName, target, method, flags);
6688
- },
6689
-
6690
- _finalizeListeners: function () {
6691
- if (this._listenersFinalized) {
6692
- return;
6693
- }
6694
- if (!this._listeners) {
6695
- this._listeners = [];
6696
- }
6697
- var pointer = this.parent;
6698
- while (pointer) {
6699
- var listeners = pointer._listeners;
6700
- if (listeners) {
6701
- this._listeners = this._listeners.concat(listeners);
6702
- }
6703
- if (pointer._listenersFinalized) {
6704
- break;
6705
- }
6706
- pointer = pointer.parent;
6707
- }
6708
- this._listenersFinalized = true;
6709
- },
6710
-
6711
- removeFromListeners: function (eventName, target, method, didRemove) {
6712
- var pointer = this;
6713
- while (pointer) {
6714
- var listeners = pointer._listeners;
6715
- if (listeners) {
6716
- for (var index = listeners.length - 4; index >= 0; index -= 4) {
6717
- if (listeners[index] === eventName && (!method || listeners[index + 1] === target && listeners[index + 2] === method)) {
6718
- if (pointer === this) {
6719
- // we are modifying our own list, so we edit directly
6720
- if (typeof didRemove === 'function') {
6721
- didRemove(eventName, target, listeners[index + 2]);
6722
- }
6723
- listeners.splice(index, 4);
6724
- } else {
6725
- // we are trying to remove an inherited listener, so we do
6726
- // just-in-time copying to detach our own listeners from
6727
- // our inheritance chain.
6728
- this._finalizeListeners();
6729
- return this.removeFromListeners(eventName, target, method);
6730
- }
6731
- }
6732
- }
6733
- }
6734
- if (pointer._listenersFinalized) {
6735
- break;
6736
- }
6737
- pointer = pointer.parent;
6738
- }
6739
- },
6740
-
6741
- matchingListeners: function (eventName) {
6742
- var pointer = this;
6743
- var result = [];
6744
- while (pointer) {
6745
- var listeners = pointer._listeners;
6746
- if (listeners) {
6747
- for (var index = 0; index < listeners.length - 3; index += 4) {
6748
- if (listeners[index] === eventName) {
6749
- pushUniqueListener(result, listeners, index);
6750
- }
6751
- }
6752
- }
6753
- if (pointer._listenersFinalized) {
6754
- break;
6755
- }
6756
- pointer = pointer.parent;
6757
- }
6758
- var sus = this._suspendedListeners;
6759
- if (sus) {
6760
- for (var susIndex = 0; susIndex < sus.length - 2; susIndex += 3) {
6761
- if (eventName === sus[susIndex]) {
6762
- for (var resultIndex = 0; resultIndex < result.length - 2; resultIndex += 3) {
6763
- if (result[resultIndex] === sus[susIndex + 1] && result[resultIndex + 1] === sus[susIndex + 2]) {
6764
- result[resultIndex + 2] |= SUSPENDED;
6765
- }
6766
- }
6767
- }
6768
- }
6769
- }
6770
- return result;
6771
- },
6772
-
6773
- suspendListeners: function (eventNames, target, method, callback) {
6774
- var sus = this._suspendedListeners;
6775
- if (!sus) {
6776
- sus = this._suspendedListeners = [];
6777
- }
6778
- for (var i = 0; i < eventNames.length; i++) {
6779
- sus.push(eventNames[i], target, method);
6780
- }
6781
- try {
6782
- return callback.call(target);
6783
- } finally {
6784
- if (sus.length === eventNames.length) {
6785
- this._suspendedListeners = undefined;
6743
+ // Implements a member that provides an inheritable, lazily-created
6744
+ // object using the method you provide. We will derived children from
6745
+ // their parents by calling your object's `copy()` method.
6746
+ function inheritedCustomObject(name, Meta) {
6747
+ var key = memberProperty(name);
6748
+ var capitalized = capitalize(name);
6749
+ Meta.prototype['writable' + capitalized] = function (create) {
6750
+ var ret = this[key];
6751
+ if (!ret) {
6752
+ if (this.parent) {
6753
+ ret = this[key] = this.parent['writable' + capitalized](create).copy(this.source);
6786
6754
  } else {
6787
- for (var i = sus.length - 3; i >= 0; i -= 3) {
6788
- if (sus[i + 1] === target && sus[i + 2] === method && eventNames.indexOf(sus[i]) !== -1) {
6789
- sus.splice(i, 3);
6790
- }
6791
- }
6755
+ ret = this[key] = create(this.source);
6792
6756
  }
6793
6757
  }
6794
- },
6758
+ return ret;
6759
+ };
6760
+ Meta.prototype['readable' + capitalized] = function () {
6761
+ return this._getInherited(key);
6762
+ };
6763
+ }
6795
6764
 
6796
- watchedEvents: function () {
6797
- var pointer = this;
6798
- var names = {};
6799
- while (pointer) {
6800
- var listeners = pointer._listeners;
6801
- if (listeners) {
6802
- for (var index = 0; index < listeners.length - 3; index += 4) {
6803
- names[listeners[index]] = true;
6804
- }
6805
- }
6806
- if (pointer._listenersFinalized) {
6807
- break;
6808
- }
6809
- pointer = pointer.parent;
6810
- }
6811
- return Object.keys(names);
6812
- },
6765
+ function memberProperty(name) {
6766
+ return '_' + name;
6767
+ }
6813
6768
 
6814
- _initializeListeners: function () {
6815
- this._listeners = undefined;
6816
- this._listenersFinalized = undefined;
6817
- this._suspendedListeners = undefined;
6818
- }
6769
+ // there's a more general-purpose capitalize in ember-runtime, but we
6770
+ // don't want to make ember-metal depend on ember-runtime.
6771
+ function capitalize(name) {
6772
+ return name.replace(/^\w/, function (m) {
6773
+ return m.toUpperCase();
6774
+ });
6775
+ }
6776
+
6777
+ var META_DESC = {
6778
+ writable: true,
6779
+ configurable: true,
6780
+ enumerable: false,
6781
+ value: null
6819
6782
  };
6820
6783
 
6821
- exports.protoMethods = protoMethods;
6822
- function pushUniqueListener(destination, source, index) {
6823
- var target = source[index + 1];
6824
- var method = source[index + 2];
6825
- for (var destinationIndex = 0; destinationIndex < destination.length - 2; destinationIndex += 3) {
6826
- if (destination[destinationIndex] === target && destination[destinationIndex + 1] === method) {
6827
- return;
6828
- }
6784
+ exports.META_DESC = META_DESC;
6785
+ var EMBER_META_PROPERTY = {
6786
+ name: '__ember_meta__',
6787
+ descriptor: META_DESC
6788
+ };
6789
+
6790
+ // Placeholder for non-writable metas.
6791
+ var EMPTY_META = new Meta(null);
6792
+
6793
+ exports.EMPTY_META = EMPTY_META;
6794
+
6795
+ EMPTY_META.writableValues();
6796
+
6797
+ /**
6798
+ Retrieves the meta hash for an object. If `writable` is true ensures the
6799
+ hash is writable for this object as well.
6800
+
6801
+ The meta object contains information about computed property descriptors as
6802
+ well as any watched properties and other information. You generally will
6803
+ not access this information directly but instead work with higher level
6804
+ methods that manipulate this hash indirectly.
6805
+
6806
+ @method meta
6807
+ @for Ember
6808
+ @private
6809
+
6810
+ @param {Object} obj The object to retrieve meta for
6811
+ @param {Boolean} [writable=true] Pass `false` if you do not intend to modify
6812
+ the meta hash, allowing the method to avoid making an unnecessary copy.
6813
+ @return {Object} the meta hash for an object
6814
+ */
6815
+
6816
+ function meta(obj, writable) {
6817
+ var ret = obj.__ember_meta__;
6818
+ if (writable === false) {
6819
+ return ret || EMPTY_META;
6829
6820
  }
6830
- destination.push(target, method, source[index + 3]);
6821
+
6822
+ if (ret && ret.source === obj) {
6823
+ return ret;
6824
+ }
6825
+
6826
+ if (!ret) {
6827
+ ret = new Meta(obj);
6828
+
6829
+ ret.writableValues();
6830
+ } else {
6831
+ ret = new Meta(obj, ret);
6832
+ }
6833
+
6834
+ if (obj.__defineNonEnumerable) {
6835
+ obj.__defineNonEnumerable(EMBER_META_PROPERTY);
6836
+ } else {
6837
+ Object.defineProperty(obj, '__ember_meta__', META_DESC);
6838
+ }
6839
+ obj.__ember_meta__ = ret;
6840
+
6841
+ return ret;
6831
6842
  }
6832
6843
  });
6833
6844
  enifed('ember-metal/mixin', ['exports', 'ember-metal/core', 'ember-metal/merge', 'ember-metal/empty_object', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/utils', 'ember-metal/meta', 'ember-metal/expand_properties', 'ember-metal/properties', 'ember-metal/computed', 'ember-metal/binding', 'ember-metal/observer', 'ember-metal/events', 'ember-metal/streams/utils'], function (exports, _emberMetalCore, _emberMetalMerge, _emberMetalEmpty_object, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalUtils, _emberMetalMeta, _emberMetalExpand_properties, _emberMetalProperties, _emberMetalComputed, _emberMetalBinding, _emberMetalObserver, _emberMetalEvents, _emberMetalStreamsUtils) {
@@ -6849,6 +6860,9 @@ enifed('ember-metal/mixin', ['exports', 'ember-metal/core', 'ember-metal/merge',
6849
6860
  @submodule ember-metal
6850
6861
  */
6851
6862
 
6863
+ function ROOT() {}
6864
+ ROOT.__hasSuper = false;
6865
+
6852
6866
  var REQUIRED;
6853
6867
  var a_slice = [].slice;
6854
6868
 
@@ -6994,7 +7008,7 @@ enifed('ember-metal/mixin', ['exports', 'ember-metal/core', 'ember-metal/merge',
6994
7008
  }
6995
7009
 
6996
7010
  if (hasFunction) {
6997
- newBase._super = function () {};
7011
+ newBase._super = ROOT;
6998
7012
  }
6999
7013
 
7000
7014
  return newBase;
@@ -7191,7 +7205,7 @@ enifed('ember-metal/mixin', ['exports', 'ember-metal/core', 'ember-metal/merge',
7191
7205
  var keys = [];
7192
7206
  var key, value, desc;
7193
7207
 
7194
- obj._super = function () {};
7208
+ obj._super = ROOT;
7195
7209
 
7196
7210
  // Go through all mixins and hashes passed in, and:
7197
7211
  //
@@ -7569,7 +7583,7 @@ enifed('ember-metal/mixin', ['exports', 'ember-metal/core', 'ember-metal/merge',
7569
7583
  @method aliasMethod
7570
7584
  @for Ember
7571
7585
  @param {String} methodName name of the method to alias
7572
- @private
7586
+ @public
7573
7587
  */
7574
7588
 
7575
7589
  function aliasMethod(methodName) {
@@ -7758,6 +7772,75 @@ enifed('ember-metal/mixin', ['exports', 'ember-metal/core', 'ember-metal/merge',
7758
7772
  exports.REQUIRED = REQUIRED;
7759
7773
  });
7760
7774
  // warn, assert, wrap, et;
7775
+ enifed('ember-metal/observer_set', ['exports', 'ember-metal/utils', 'ember-metal/events'], function (exports, _emberMetalUtils, _emberMetalEvents) {
7776
+ 'use strict';
7777
+
7778
+ /*
7779
+ this.observerSet = {
7780
+ [senderGuid]: { // variable name: `keySet`
7781
+ [keyName]: listIndex
7782
+ }
7783
+ },
7784
+ this.observers = [
7785
+ {
7786
+ sender: obj,
7787
+ keyName: keyName,
7788
+ eventName: eventName,
7789
+ listeners: [
7790
+ [target, method, flags]
7791
+ ]
7792
+ },
7793
+ ...
7794
+ ]
7795
+ */
7796
+ exports.default = ObserverSet;
7797
+
7798
+ function ObserverSet() {
7799
+ this.clear();
7800
+ }
7801
+
7802
+ ObserverSet.prototype.add = function (sender, keyName, eventName) {
7803
+ var observerSet = this.observerSet;
7804
+ var observers = this.observers;
7805
+ var senderGuid = _emberMetalUtils.guidFor(sender);
7806
+ var keySet = observerSet[senderGuid];
7807
+ var index;
7808
+
7809
+ if (!keySet) {
7810
+ observerSet[senderGuid] = keySet = {};
7811
+ }
7812
+ index = keySet[keyName];
7813
+ if (index === undefined) {
7814
+ index = observers.push({
7815
+ sender: sender,
7816
+ keyName: keyName,
7817
+ eventName: eventName,
7818
+ listeners: []
7819
+ }) - 1;
7820
+ keySet[keyName] = index;
7821
+ }
7822
+ return observers[index].listeners;
7823
+ };
7824
+
7825
+ ObserverSet.prototype.flush = function () {
7826
+ var observers = this.observers;
7827
+ var i, len, observer, sender;
7828
+ this.clear();
7829
+ for (i = 0, len = observers.length; i < len; ++i) {
7830
+ observer = observers[i];
7831
+ sender = observer.sender;
7832
+ if (sender.isDestroying || sender.isDestroyed) {
7833
+ continue;
7834
+ }
7835
+ _emberMetalEvents.sendEvent(sender, observer.eventName, [sender, observer.keyName], observer.listeners);
7836
+ }
7837
+ };
7838
+
7839
+ ObserverSet.prototype.clear = function () {
7840
+ this.observerSet = {};
7841
+ this.observers = [];
7842
+ };
7843
+ });
7761
7844
  enifed('ember-metal/observer', ['exports', 'ember-metal/watching', 'ember-metal/events'], function (exports, _emberMetalWatching, _emberMetalEvents) {
7762
7845
  'use strict';
7763
7846
 
@@ -7838,108 +7921,39 @@ enifed('ember-metal/observer', ['exports', 'ember-metal/watching', 'ember-metal/
7838
7921
  _emberMetalWatching.watch(obj, path);
7839
7922
 
7840
7923
  return this;
7841
- }
7842
-
7843
- // Suspend observer during callback.
7844
- //
7845
- // This should only be used by the target of the observer
7846
- // while it is setting the observed path.
7847
-
7848
- function _suspendObserver(obj, path, target, method, callback) {
7849
- return _emberMetalEvents.suspendListener(obj, changeEvent(path), target, method, callback);
7850
- }
7851
-
7852
- function _suspendObservers(obj, paths, target, method, callback) {
7853
- var events = paths.map(changeEvent);
7854
- return _emberMetalEvents.suspendListeners(obj, events, target, method, callback);
7855
- }
7856
-
7857
- /**
7858
- @method removeBeforeObserver
7859
- @for Ember
7860
- @param obj
7861
- @param {String} path
7862
- @param {Object|Function} target
7863
- @param {Function|String} [method]
7864
- @deprecated
7865
- @private
7866
- */
7867
-
7868
- function _removeBeforeObserver(obj, path, target, method) {
7869
- _emberMetalWatching.unwatch(obj, path);
7870
- _emberMetalEvents.removeListener(obj, beforeEvent(path), target, method);
7871
-
7872
- return this;
7873
- }
7874
- });
7875
- enifed('ember-metal/observer_set', ['exports', 'ember-metal/utils', 'ember-metal/events'], function (exports, _emberMetalUtils, _emberMetalEvents) {
7876
- 'use strict';
7877
-
7878
- /*
7879
- this.observerSet = {
7880
- [senderGuid]: { // variable name: `keySet`
7881
- [keyName]: listIndex
7882
- }
7883
- },
7884
- this.observers = [
7885
- {
7886
- sender: obj,
7887
- keyName: keyName,
7888
- eventName: eventName,
7889
- listeners: [
7890
- [target, method, flags]
7891
- ]
7892
- },
7893
- ...
7894
- ]
7895
- */
7896
- exports.default = ObserverSet;
7924
+ }
7897
7925
 
7898
- function ObserverSet() {
7899
- this.clear();
7926
+ // Suspend observer during callback.
7927
+ //
7928
+ // This should only be used by the target of the observer
7929
+ // while it is setting the observed path.
7930
+
7931
+ function _suspendObserver(obj, path, target, method, callback) {
7932
+ return _emberMetalEvents.suspendListener(obj, changeEvent(path), target, method, callback);
7900
7933
  }
7901
7934
 
7902
- ObserverSet.prototype.add = function (sender, keyName, eventName) {
7903
- var observerSet = this.observerSet;
7904
- var observers = this.observers;
7905
- var senderGuid = _emberMetalUtils.guidFor(sender);
7906
- var keySet = observerSet[senderGuid];
7907
- var index;
7935
+ function _suspendObservers(obj, paths, target, method, callback) {
7936
+ var events = paths.map(changeEvent);
7937
+ return _emberMetalEvents.suspendListeners(obj, events, target, method, callback);
7938
+ }
7908
7939
 
7909
- if (!keySet) {
7910
- observerSet[senderGuid] = keySet = {};
7911
- }
7912
- index = keySet[keyName];
7913
- if (index === undefined) {
7914
- index = observers.push({
7915
- sender: sender,
7916
- keyName: keyName,
7917
- eventName: eventName,
7918
- listeners: []
7919
- }) - 1;
7920
- keySet[keyName] = index;
7921
- }
7922
- return observers[index].listeners;
7923
- };
7940
+ /**
7941
+ @method removeBeforeObserver
7942
+ @for Ember
7943
+ @param obj
7944
+ @param {String} path
7945
+ @param {Object|Function} target
7946
+ @param {Function|String} [method]
7947
+ @deprecated
7948
+ @private
7949
+ */
7924
7950
 
7925
- ObserverSet.prototype.flush = function () {
7926
- var observers = this.observers;
7927
- var i, len, observer, sender;
7928
- this.clear();
7929
- for (i = 0, len = observers.length; i < len; ++i) {
7930
- observer = observers[i];
7931
- sender = observer.sender;
7932
- if (sender.isDestroying || sender.isDestroyed) {
7933
- continue;
7934
- }
7935
- _emberMetalEvents.sendEvent(sender, observer.eventName, [sender, observer.keyName], observer.listeners);
7936
- }
7937
- };
7951
+ function _removeBeforeObserver(obj, path, target, method) {
7952
+ _emberMetalWatching.unwatch(obj, path);
7953
+ _emberMetalEvents.removeListener(obj, beforeEvent(path), target, method);
7938
7954
 
7939
- ObserverSet.prototype.clear = function () {
7940
- this.observerSet = {};
7941
- this.observers = [];
7942
- };
7955
+ return this;
7956
+ }
7943
7957
  });
7944
7958
  enifed('ember-metal/path_cache', ['exports', 'ember-metal/cache'], function (exports, _emberMetalCache) {
7945
7959
  'use strict';
@@ -9566,61 +9580,6 @@ enifed('ember-metal/set_properties', ['exports', 'ember-metal/property_events',
9566
9580
  return properties;
9567
9581
  }
9568
9582
  });
9569
- enifed('ember-metal/streams/conditional', ['exports', 'ember-metal/streams/stream', 'ember-metal/streams/utils'], function (exports, _emberMetalStreamsStream, _emberMetalStreamsUtils) {
9570
- 'use strict';
9571
-
9572
- exports.default = conditional;
9573
-
9574
- function conditional(test, consequent, alternate) {
9575
- if (_emberMetalStreamsUtils.isStream(test)) {
9576
- return new ConditionalStream(test, consequent, alternate);
9577
- } else {
9578
- if (test) {
9579
- return consequent;
9580
- } else {
9581
- return alternate;
9582
- }
9583
- }
9584
- }
9585
-
9586
- function ConditionalStream(test, consequent, alternate) {
9587
- this.init();
9588
-
9589
- this.oldTestResult = undefined;
9590
- this.test = test;
9591
- this.consequent = consequent;
9592
- this.alternate = alternate;
9593
- }
9594
-
9595
- ConditionalStream.prototype = Object.create(_emberMetalStreamsStream.default.prototype);
9596
-
9597
- ConditionalStream.prototype.compute = function () {
9598
- var oldTestResult = this.oldTestResult;
9599
- var newTestResult = !!_emberMetalStreamsUtils.read(this.test);
9600
-
9601
- if (newTestResult !== oldTestResult) {
9602
- switch (oldTestResult) {
9603
- case true:
9604
- _emberMetalStreamsUtils.unsubscribe(this.consequent, this.notify, this);break;
9605
- case false:
9606
- _emberMetalStreamsUtils.unsubscribe(this.alternate, this.notify, this);break;
9607
- case undefined:
9608
- _emberMetalStreamsUtils.subscribe(this.test, this.notify, this);
9609
- }
9610
-
9611
- switch (newTestResult) {
9612
- case true:
9613
- _emberMetalStreamsUtils.subscribe(this.consequent, this.notify, this);break;
9614
- case false:
9615
- _emberMetalStreamsUtils.subscribe(this.alternate, this.notify, this);
9616
- }
9617
-
9618
- this.oldTestResult = newTestResult;
9619
- }
9620
-
9621
- return newTestResult ? _emberMetalStreamsUtils.read(this.consequent) : _emberMetalStreamsUtils.read(this.alternate);
9622
- };
9623
- });
9624
9583
  enifed('ember-metal/streams/dependency', ['exports', 'ember-metal/core', 'ember-metal/merge', 'ember-metal/streams/utils'], function (exports, _emberMetalCore, _emberMetalMerge, _emberMetalStreamsUtils) {
9625
9584
  'use strict';
9626
9585
 
@@ -10379,7 +10338,7 @@ enifed('ember-metal/streams/utils', ['exports', 'ember-metal/core', './stream'],
10379
10338
  });
10380
10339
 
10381
10340
  for (i = 0, l = array.length; i < l; i++) {
10382
- subscribe(array[i], stream.notify, stream);
10341
+ stream.addDependency(array[i]);
10383
10342
  }
10384
10343
 
10385
10344
  // used by angle bracket components to detect an attribute was provided
@@ -10815,9 +10774,31 @@ enifed('ember-metal/utils', ['exports'], function (exports) {
10815
10774
  }
10816
10775
  }
10817
10776
 
10818
- var sourceAvailable = (function () {
10819
- return this;
10820
- }).toString().indexOf('return this;') > -1;
10777
+ var checkHasSuper = (function () {
10778
+ var sourceAvailable = (function () {
10779
+ return this;
10780
+ }).toString().indexOf('return this;') > -1;
10781
+
10782
+ if (sourceAvailable) {
10783
+ return function checkHasSuper(func) {
10784
+ return func.toString().indexOf('_super') > -1;
10785
+ };
10786
+ }
10787
+
10788
+ return function checkHasSuper() {
10789
+ return true;
10790
+ };
10791
+ })();
10792
+
10793
+ function ROOT() {}
10794
+ ROOT.__hasSuper = false;
10795
+
10796
+ function hasSuper(func) {
10797
+ if (func.__hasSuper === undefined) {
10798
+ func.__hasSuper = checkHasSuper(func);
10799
+ }
10800
+ return func.__hasSuper;
10801
+ }
10821
10802
 
10822
10803
  /**
10823
10804
  Wraps the passed function so that `this._super` will point to the superFunc
@@ -10832,36 +10813,24 @@ enifed('ember-metal/utils', ['exports'], function (exports) {
10832
10813
  @return {Function} wrapped function.
10833
10814
  */
10834
10815
 
10835
- function wrap(func, _superFunc) {
10836
- var superFunc = _superFunc;
10837
- var hasSuper;
10838
- if (sourceAvailable) {
10839
- hasSuper = func.__hasSuper;
10840
-
10841
- if (hasSuper === undefined) {
10842
- hasSuper = func.toString().indexOf('_super') > -1;
10843
- func.__hasSuper = hasSuper;
10844
- }
10845
-
10846
- if (!hasSuper) {
10847
- return func;
10848
- }
10816
+ function wrap(func, superFunc) {
10817
+ if (!hasSuper(func)) {
10818
+ return func;
10849
10819
  }
10850
-
10851
- if (superFunc.wrappedFunction === undefined) {
10852
- // terminate _super to prevent infinite recursion
10853
- superFunc = wrap(superFunc, function () {});
10820
+ // ensure an unwrapped super that calls _super is wrapped with a terminal _super
10821
+ if (!superFunc.wrappedFunction && hasSuper(superFunc)) {
10822
+ return _wrap(func, _wrap(superFunc, ROOT));
10854
10823
  }
10855
-
10856
10824
  return _wrap(func, superFunc);
10857
10825
  }
10858
10826
 
10859
10827
  function _wrap(func, superFunc) {
10860
10828
  function superWrapper() {
10861
- var ret;
10862
10829
  var orig = this._super;
10830
+ var length = arguments.length;
10831
+ var ret = undefined;
10863
10832
  this._super = superFunc;
10864
- switch (arguments.length) {
10833
+ switch (length) {
10865
10834
  case 0:
10866
10835
  ret = func.call(this);break;
10867
10836
  case 1:
@@ -10875,7 +10844,14 @@ enifed('ember-metal/utils', ['exports'], function (exports) {
10875
10844
  case 5:
10876
10845
  ret = func.call(this, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);break;
10877
10846
  default:
10878
- ret = func.apply(this, arguments);break;
10847
+ // v8 bug potentially incorrectly deopts this function: https://code.google.com/p/v8/issues/detail?id=3709
10848
+ // we may want to keep this around till this ages out on mobile
10849
+ var args = new Array(length);
10850
+ for (var x = 0; x < length; x++) {
10851
+ args[x] = arguments[x];
10852
+ }
10853
+ ret = func.apply(this, args);
10854
+ break;
10879
10855
  }
10880
10856
  this._super = orig;
10881
10857
  return ret;
@@ -11350,7 +11326,7 @@ enifed('ember-metal/watching', ['exports', 'ember-metal/chains', 'ember-metal/wa
11350
11326
  }
11351
11327
  }
11352
11328
  });
11353
- enifed('ember-template-compiler', ['exports', 'ember-metal', 'ember-template-compiler/system/precompile', 'ember-template-compiler/system/compile', 'ember-template-compiler/system/template', 'ember-template-compiler/plugins', 'ember-template-compiler/plugins/transform-old-binding-syntax', 'ember-template-compiler/plugins/transform-old-class-binding-syntax', 'ember-template-compiler/plugins/transform-item-class', 'ember-template-compiler/plugins/transform-component-attrs-into-mut', 'ember-template-compiler/plugins/transform-component-curly-to-readonly', 'ember-template-compiler/plugins/transform-angle-bracket-components', 'ember-template-compiler/plugins/transform-input-on-to-onEvent', 'ember-template-compiler/plugins/transform-top-level-components', 'ember-template-compiler/plugins/transform-each-into-collection', 'ember-template-compiler/plugins/assert-no-view-and-controller-paths', 'ember-template-compiler/plugins/assert-no-view-helper', 'ember-template-compiler/compat'], function (exports, _emberMetal, _emberTemplateCompilerSystemPrecompile, _emberTemplateCompilerSystemCompile, _emberTemplateCompilerSystemTemplate, _emberTemplateCompilerPlugins, _emberTemplateCompilerPluginsTransformOldBindingSyntax, _emberTemplateCompilerPluginsTransformOldClassBindingSyntax, _emberTemplateCompilerPluginsTransformItemClass, _emberTemplateCompilerPluginsTransformComponentAttrsIntoMut, _emberTemplateCompilerPluginsTransformComponentCurlyToReadonly, _emberTemplateCompilerPluginsTransformAngleBracketComponents, _emberTemplateCompilerPluginsTransformInputOnToOnEvent, _emberTemplateCompilerPluginsTransformTopLevelComponents, _emberTemplateCompilerPluginsTransformEachIntoCollection, _emberTemplateCompilerPluginsAssertNoViewAndControllerPaths, _emberTemplateCompilerPluginsAssertNoViewHelper, _emberTemplateCompilerCompat) {
11329
+ enifed('ember-template-compiler', ['exports', 'ember-metal', 'ember-template-compiler/system/precompile', 'ember-template-compiler/system/compile', 'ember-template-compiler/system/template', 'ember-template-compiler/plugins', 'ember-template-compiler/plugins/transform-old-binding-syntax', 'ember-template-compiler/plugins/transform-old-class-binding-syntax', 'ember-template-compiler/plugins/transform-item-class', 'ember-template-compiler/plugins/transform-component-attrs-into-mut', 'ember-template-compiler/plugins/transform-component-curly-to-readonly', 'ember-template-compiler/plugins/transform-angle-bracket-components', 'ember-template-compiler/plugins/transform-input-on-to-onEvent', 'ember-template-compiler/plugins/transform-top-level-components', 'ember-template-compiler/plugins/transform-each-into-collection', 'ember-template-compiler/plugins/transform-unescaped-inline-link-to', 'ember-template-compiler/plugins/assert-no-view-and-controller-paths', 'ember-template-compiler/plugins/assert-no-view-helper', 'ember-template-compiler/compat'], function (exports, _emberMetal, _emberTemplateCompilerSystemPrecompile, _emberTemplateCompilerSystemCompile, _emberTemplateCompilerSystemTemplate, _emberTemplateCompilerPlugins, _emberTemplateCompilerPluginsTransformOldBindingSyntax, _emberTemplateCompilerPluginsTransformOldClassBindingSyntax, _emberTemplateCompilerPluginsTransformItemClass, _emberTemplateCompilerPluginsTransformComponentAttrsIntoMut, _emberTemplateCompilerPluginsTransformComponentCurlyToReadonly, _emberTemplateCompilerPluginsTransformAngleBracketComponents, _emberTemplateCompilerPluginsTransformInputOnToOnEvent, _emberTemplateCompilerPluginsTransformTopLevelComponents, _emberTemplateCompilerPluginsTransformEachIntoCollection, _emberTemplateCompilerPluginsTransformUnescapedInlineLinkTo, _emberTemplateCompilerPluginsAssertNoViewAndControllerPaths, _emberTemplateCompilerPluginsAssertNoViewHelper, _emberTemplateCompilerCompat) {
11354
11330
  'use strict';
11355
11331
 
11356
11332
  _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsTransformOldBindingSyntax.default);
@@ -11361,6 +11337,7 @@ enifed('ember-template-compiler', ['exports', 'ember-metal', 'ember-template-com
11361
11337
  _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsTransformAngleBracketComponents.default);
11362
11338
  _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsTransformInputOnToOnEvent.default);
11363
11339
  _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsTransformTopLevelComponents.default);
11340
+ _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsTransformUnescapedInlineLinkTo.default);
11364
11341
 
11365
11342
  if (_emberMetal.default.ENV._ENABLE_LEGACY_VIEW_SUPPORT) {
11366
11343
  _emberTemplateCompilerPlugins.registerPlugin('ast', _emberTemplateCompilerPluginsTransformEachIntoCollection.default);
@@ -12267,6 +12244,36 @@ enifed('ember-template-compiler/plugins/transform-top-level-components', ['expor
12267
12244
 
12268
12245
  exports.default = TransformTopLevelComponents;
12269
12246
  });
12247
+ enifed('ember-template-compiler/plugins/transform-unescaped-inline-link-to', ['exports'], function (exports) {
12248
+ 'use strict';
12249
+
12250
+ exports.default = TransformUnescapedInlineLinkTo;
12251
+
12252
+ function TransformUnescapedInlineLinkTo(options) {
12253
+ this.options = options;
12254
+ this.syntax = null;
12255
+ }
12256
+
12257
+ TransformUnescapedInlineLinkTo.prototype.transform = function TransformUnescapedInlineLinkTo_transform(ast) {
12258
+ var b = this.syntax.builders;
12259
+ var walker = new this.syntax.Walker();
12260
+
12261
+ walker.visit(ast, function (node) {
12262
+ if (!validate(node)) {
12263
+ return;
12264
+ }
12265
+
12266
+ node.escaped = true;
12267
+ node.params[0] = b.sexpr(b.string('-html-safe'), [node.params[0]]);
12268
+ });
12269
+
12270
+ return ast;
12271
+ };
12272
+
12273
+ function validate(node) {
12274
+ return node.type === 'MustacheStatement' && node.path.original === 'link-to' && !node.escaped;
12275
+ }
12276
+ });
12270
12277
  enifed('ember-template-compiler/system/calculate-location-display', ['exports'], function (exports) {
12271
12278
  'use strict';
12272
12279
 
@@ -12300,41 +12307,6 @@ enifed('ember-template-compiler/system/calculate-location-display', ['exports'],
12300
12307
  return moduleInfo;
12301
12308
  }
12302
12309
  });
12303
- enifed('ember-template-compiler/system/compile', ['exports', 'ember-metal/core', 'ember-template-compiler/system/compile_options', 'ember-template-compiler/system/template'], function (exports, _emberMetalCore, _emberTemplateCompilerSystemCompile_options, _emberTemplateCompilerSystemTemplate) {
12304
- /**
12305
- @module ember
12306
- @submodule ember-template-compiler
12307
- */
12308
-
12309
- 'use strict';
12310
-
12311
- var compile;
12312
-
12313
- /**
12314
- Uses HTMLBars `compile` function to process a string into a compiled template.
12315
-
12316
- This is not present in production builds.
12317
-
12318
- @private
12319
- @method compile
12320
- @param {String} templateString This is the string to be compiled by HTMLBars.
12321
- @param {Object} options This is an options hash to augment the compiler options.
12322
- */
12323
-
12324
- exports.default = function (templateString, options) {
12325
- if (!compile && _emberMetalCore.default.__loader.registry['htmlbars-compiler/compiler']) {
12326
- compile = requireModule('htmlbars-compiler/compiler').compile;
12327
- }
12328
-
12329
- if (!compile) {
12330
- throw new Error('Cannot call `compile` without the template compiler loaded. Please load `ember-template-compiler.js` prior to calling `compile`.');
12331
- }
12332
-
12333
- var templateSpec = compile(templateString, _emberTemplateCompilerSystemCompile_options.default(options));
12334
-
12335
- return _emberTemplateCompilerSystemTemplate.default(templateSpec);
12336
- };
12337
- });
12338
12310
  enifed('ember-template-compiler/system/compile_options', ['exports', 'ember-metal/features', 'ember-metal/assign', 'ember-template-compiler/plugins'], function (exports, _emberMetalFeatures, _emberMetalAssign, _emberTemplateCompilerPlugins) {
12339
12311
  /**
12340
12312
  @module ember
@@ -12375,7 +12347,7 @@ enifed('ember-template-compiler/system/compile_options', ['exports', 'ember-meta
12375
12347
  options.buildMeta = function buildMeta(program) {
12376
12348
  return {
12377
12349
  topLevel: detectTopLevel(program),
12378
- revision: 'Ember@2.1.0-beta.1',
12350
+ revision: 'Ember@2.1.0-beta.3',
12379
12351
  loc: program.loc,
12380
12352
  moduleName: options.moduleName
12381
12353
  };
@@ -12430,6 +12402,41 @@ enifed('ember-template-compiler/system/compile_options', ['exports', 'ember-meta
12430
12402
  return null;
12431
12403
  }
12432
12404
  });
12405
+ enifed('ember-template-compiler/system/compile', ['exports', 'ember-metal/core', 'ember-template-compiler/system/compile_options', 'ember-template-compiler/system/template'], function (exports, _emberMetalCore, _emberTemplateCompilerSystemCompile_options, _emberTemplateCompilerSystemTemplate) {
12406
+ /**
12407
+ @module ember
12408
+ @submodule ember-template-compiler
12409
+ */
12410
+
12411
+ 'use strict';
12412
+
12413
+ var compile;
12414
+
12415
+ /**
12416
+ Uses HTMLBars `compile` function to process a string into a compiled template.
12417
+
12418
+ This is not present in production builds.
12419
+
12420
+ @private
12421
+ @method compile
12422
+ @param {String} templateString This is the string to be compiled by HTMLBars.
12423
+ @param {Object} options This is an options hash to augment the compiler options.
12424
+ */
12425
+
12426
+ exports.default = function (templateString, options) {
12427
+ if (!compile && _emberMetalCore.default.__loader.registry['htmlbars-compiler/compiler']) {
12428
+ compile = requireModule('htmlbars-compiler/compiler').compile;
12429
+ }
12430
+
12431
+ if (!compile) {
12432
+ throw new Error('Cannot call `compile` without the template compiler loaded. Please load `ember-template-compiler.js` prior to calling `compile`.');
12433
+ }
12434
+
12435
+ var templateSpec = compile(templateString, _emberTemplateCompilerSystemCompile_options.default(options));
12436
+
12437
+ return _emberTemplateCompilerSystemTemplate.default(templateSpec);
12438
+ };
12439
+ });
12433
12440
  enifed('ember-template-compiler/system/precompile', ['exports', 'ember-metal/core', 'ember-template-compiler/system/compile_options'], function (exports, _emberMetalCore, _emberTemplateCompilerSystemCompile_options) {
12434
12441
  /**
12435
12442
  @module ember
@@ -13868,7 +13875,6 @@ enifed("htmlbars-runtime/hooks", ["exports", "./render", "../morph-range/morph-l
13868
13875
 
13869
13876
  exports.wrap = wrap;
13870
13877
  exports.wrapForHelper = wrapForHelper;
13871
- exports.hostYieldWithShadowTemplate = hostYieldWithShadowTemplate;
13872
13878
  exports.createScope = createScope;
13873
13879
  exports.createFreshScope = createFreshScope;
13874
13880
  exports.bindShadowScope = bindShadowScope;
@@ -13895,6 +13901,7 @@ enifed("htmlbars-runtime/hooks", ["exports", "./render", "../morph-range/morph-l
13895
13901
  exports.subexpr = subexpr;
13896
13902
  exports.get = get;
13897
13903
  exports.getRoot = getRoot;
13904
+ exports.getBlock = getBlock;
13898
13905
  exports.getChild = getChild;
13899
13906
  exports.getValue = getValue;
13900
13907
  exports.getCellOrValue = getCellOrValue;
@@ -14000,9 +14007,7 @@ enifed("htmlbars-runtime/hooks", ["exports", "./render", "../morph-range/morph-l
14000
14007
 
14001
14008
  function wrapForHelper(template, env, scope, morph, renderState, visitor) {
14002
14009
  if (!template) {
14003
- return {
14004
- yieldIn: yieldInShadowTemplate(null, env, scope, morph, renderState, visitor)
14005
- };
14010
+ return {};
14006
14011
  }
14007
14012
 
14008
14013
  var yieldArgs = yieldTemplate(template, env, scope, morph, renderState, visitor);
@@ -14012,7 +14017,6 @@ enifed("htmlbars-runtime/hooks", ["exports", "./render", "../morph-range/morph-l
14012
14017
  arity: template.arity,
14013
14018
  yield: yieldArgs,
14014
14019
  yieldItem: yieldItem(template, env, scope, morph, renderState, visitor),
14015
- yieldIn: yieldInShadowTemplate(template, env, scope, morph, renderState, visitor),
14016
14020
  raw: template,
14017
14021
 
14018
14022
  render: function (self, blockArguments) {
@@ -14179,55 +14183,6 @@ enifed("htmlbars-runtime/hooks", ["exports", "./render", "../morph-range/morph-l
14179
14183
  function isStableTemplate(template, lastYielded) {
14180
14184
  return !lastYielded.shadowTemplate && template === lastYielded.template;
14181
14185
  }
14182
-
14183
- function yieldInShadowTemplate(template, env, parentScope, morph, renderState, visitor) {
14184
- var hostYield = hostYieldWithShadowTemplate(template, env, parentScope, morph, renderState, visitor);
14185
-
14186
- return function (shadowTemplate, self) {
14187
- hostYield(shadowTemplate, env, self, []);
14188
- };
14189
- }
14190
-
14191
- function hostYieldWithShadowTemplate(template, env, parentScope, morph, renderState, visitor) {
14192
- return function (shadowTemplate, env, self, blockArguments) {
14193
- renderState.morphToClear = null;
14194
-
14195
- if (morph.lastYielded && isStableShadowRoot(template, shadowTemplate, morph.lastYielded)) {
14196
- return morph.lastResult.revalidateWith(env, undefined, self, blockArguments, visitor);
14197
- }
14198
-
14199
- var shadowScope = env.hooks.createFreshScope();
14200
- env.hooks.bindShadowScope(env, parentScope, shadowScope, renderState.shadowOptions);
14201
- blockToYield.arity = template.arity;
14202
- env.hooks.bindBlock(env, shadowScope, blockToYield);
14203
-
14204
- morph.lastYielded = { self: self, template: template, shadowTemplate: shadowTemplate };
14205
-
14206
- // Render the shadow template with the block available
14207
- _render.default(shadowTemplate.raw, env, shadowScope, { renderNode: morph, self: self, blockArguments: blockArguments });
14208
- };
14209
-
14210
- function blockToYield(env, blockArguments, self, renderNode, shadowParent, visitor) {
14211
- if (renderNode.lastResult) {
14212
- renderNode.lastResult.revalidateWith(env, undefined, undefined, blockArguments, visitor);
14213
- } else {
14214
- var scope = parentScope;
14215
-
14216
- // Since a yielded template shares a `self` with its original context,
14217
- // we only need to create a new scope if the template has block parameters
14218
- if (template.arity) {
14219
- scope = env.hooks.createChildScope(parentScope);
14220
- }
14221
-
14222
- _render.default(template, env, scope, { renderNode: renderNode, self: self, blockArguments: blockArguments });
14223
- }
14224
- }
14225
- }
14226
-
14227
- function isStableShadowRoot(template, shadowTemplate, lastYielded) {
14228
- return template === lastYielded.template && shadowTemplate === lastYielded.shadowTemplate;
14229
- }
14230
-
14231
14186
  function optionsFor(template, inverse, env, scope, morph, visitor) {
14232
14187
  // If there was a template yielded last time, set morphToClear so it will be cleared
14233
14188
  // if no template is yielded on this render.
@@ -14740,20 +14695,23 @@ enifed("htmlbars-runtime/hooks", ["exports", "./render", "../morph-range/morph-l
14740
14695
  // scopes; it should not be provided to user code.
14741
14696
 
14742
14697
  var to = env.hooks.getValue(hash.to) || 'default';
14743
- if (scope.blocks[to]) {
14744
- scope.blocks[to](env, params, hash.self, morph, scope, visitor);
14698
+ var block = env.hooks.getBlock(scope, to);
14699
+
14700
+ if (block) {
14701
+ block.invoke(env, params, hash.self, morph, scope, visitor);
14745
14702
  }
14746
14703
  return true;
14747
14704
  },
14748
14705
 
14749
14706
  hasBlock: function (morph, env, scope, params) {
14750
14707
  var name = env.hooks.getValue(params[0]) || 'default';
14751
- return !!scope.blocks[name];
14708
+ return !!env.hooks.getBlock(scope, name);
14752
14709
  },
14753
14710
 
14754
14711
  hasBlockParams: function (morph, env, scope, params) {
14755
14712
  var name = env.hooks.getValue(params[0]) || 'default';
14756
- return !!(scope.blocks[name] && scope.blocks[name].arity);
14713
+ var block = env.hooks.getBlock(scope, name);
14714
+ return !!(block && block.arity);
14757
14715
  }
14758
14716
 
14759
14717
  };
@@ -14953,6 +14911,10 @@ enifed("htmlbars-runtime/hooks", ["exports", "./render", "../morph-range/morph-l
14953
14911
  }
14954
14912
  }
14955
14913
 
14914
+ function getBlock(scope, key) {
14915
+ return scope.blocks[key];
14916
+ }
14917
+
14956
14918
  function getChild(value, key) {
14957
14919
  return value[key];
14958
14920
  }
@@ -15019,6 +14981,7 @@ enifed("htmlbars-runtime/hooks", ["exports", "./render", "../morph-range/morph-l
15019
14981
  createFreshScope: createFreshScope,
15020
14982
  getChild: getChild,
15021
14983
  getRoot: getRoot,
14984
+ getBlock: getBlock,
15022
14985
  getValue: getValue,
15023
14986
  getCellOrValue: getCellOrValue,
15024
14987
  keywords: keywords,
@@ -15345,11 +15308,6 @@ enifed("htmlbars-runtime/render", ["exports", "../htmlbars-util/array-utils", ".
15345
15308
 
15346
15309
  this.bindScope();
15347
15310
 
15348
- if (options.attributes !== undefined) {
15349
- nodes.push({ state: {} });
15350
- this.statements.push(['attributes', attachAttributes(options.attributes)]);
15351
- }
15352
-
15353
15311
  if (options.self !== undefined) {
15354
15312
  this.bindSelf(options.self);
15355
15313
  }
@@ -15589,8 +15547,6 @@ enifed("htmlbars-runtime/render", ["exports", "../htmlbars-util/array-utils", ".
15589
15547
  visitor.attribute(statement, morph, env, scope);break;
15590
15548
  case 'component':
15591
15549
  visitor.component(statement, morph, env, scope, template, visitor);break;
15592
- case 'attributes':
15593
- visitor.attributes(statement, morph, env, scope, this.fragment, visitor);break;
15594
15550
  }
15595
15551
 
15596
15552
  if (env.hooks.didRenderNode) {
@@ -18843,7 +18799,12 @@ enifed("htmlbars-util/morph-utils", ["exports"], function (exports) {
18843
18799
  current = current.nextMorph;
18844
18800
  }
18845
18801
  } else if (node.morphList) {
18846
- nodes.push(node.morphList);
18802
+ var current = node.morphList.firstChildMorph;
18803
+
18804
+ while (current) {
18805
+ nodes.push(current);
18806
+ current = current.nextMorph;
18807
+ }
18847
18808
  }
18848
18809
  }
18849
18810
  }
@@ -19051,44 +19012,54 @@ enifed("htmlbars-util/template-utils", ["exports", "../htmlbars-util/morph-utils
19051
19012
  this.shadowOptions = null;
19052
19013
  }
19053
19014
 
19054
- function blockFor(render, template, blockOptions) {
19055
- var block = function (env, blockArguments, self, renderNode, parentScope, visitor) {
19056
- if (renderNode.lastResult) {
19057
- renderNode.lastResult.revalidateWith(env, undefined, self, blockArguments, visitor);
19058
- } else {
19015
+ function Block(render, template, blockOptions) {
19016
+ this.render = render;
19017
+ this.template = template;
19018
+ this.blockOptions = blockOptions;
19019
+ this.arity = template.arity;
19020
+ }
19021
+
19022
+ Block.prototype.invoke = function (env, blockArguments, self, renderNode, parentScope, visitor) {
19023
+ var _this = this;
19024
+
19025
+ if (renderNode.lastResult) {
19026
+ renderNode.lastResult.revalidateWith(env, undefined, self, blockArguments, visitor);
19027
+ } else {
19028
+ (function () {
19059
19029
  var options = { renderState: new RenderState(renderNode) };
19030
+ var render = _this.render;
19031
+ var template = _this.template;
19032
+ var scope = _this.blockOptions.scope;
19060
19033
 
19061
- var scope = blockOptions.scope;
19062
19034
  var shadowScope = scope ? env.hooks.createChildScope(scope) : env.hooks.createFreshScope();
19063
- var attributes = blockOptions.attributes;
19064
19035
 
19065
- env.hooks.bindShadowScope(env, parentScope, shadowScope, blockOptions.options);
19036
+ env.hooks.bindShadowScope(env, parentScope, shadowScope, _this.blockOptions.options);
19066
19037
 
19067
19038
  if (self !== undefined) {
19068
19039
  env.hooks.bindSelf(env, shadowScope, self);
19069
- } else if (blockOptions.self !== undefined) {
19070
- env.hooks.bindSelf(env, shadowScope, blockOptions.self);
19040
+ } else if (_this.blockOptions.self !== undefined) {
19041
+ env.hooks.bindSelf(env, shadowScope, _this.blockOptions.self);
19071
19042
  }
19072
19043
 
19073
- bindBlocks(env, shadowScope, blockOptions.yieldTo);
19044
+ bindBlocks(env, shadowScope, _this.blockOptions.yieldTo);
19074
19045
 
19075
19046
  renderAndCleanup(renderNode, env, options, null, function () {
19076
19047
  options.renderState.morphToClear = null;
19077
- render(template, env, shadowScope, { renderNode: renderNode, blockArguments: blockArguments, attributes: attributes });
19048
+ render(template, env, shadowScope, { renderNode: renderNode, blockArguments: blockArguments });
19078
19049
  });
19079
- }
19080
- };
19081
-
19082
- block.arity = template.arity;
19050
+ })();
19051
+ }
19052
+ };
19083
19053
 
19084
- return block;
19054
+ function blockFor(render, template, blockOptions) {
19055
+ return new Block(render, template, blockOptions);
19085
19056
  }
19086
19057
 
19087
19058
  function bindBlocks(env, shadowScope, blocks) {
19088
19059
  if (!blocks) {
19089
19060
  return;
19090
19061
  }
19091
- if (typeof blocks === 'function') {
19062
+ if (blocks instanceof Block) {
19092
19063
  env.hooks.bindBlock(env, shadowScope, blocks);
19093
19064
  } else {
19094
19065
  for (var name in blocks) {