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

Sign up to get free protection for your applications and to get access to all the features.

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) {