ember-source 1.0.1 → 1.1.0
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 +4 -4
- data/VERSION +1 -1
- data/dist/ember-data-deps.js +528 -206
- data/dist/ember-data-deps.min.js +8 -10
- data/dist/ember-data-deps.prod.js +516 -196
- data/dist/ember-debug.js +12 -8
- data/dist/ember-runtime.js +528 -206
- data/dist/ember-runtime.min.js +8 -10
- data/dist/ember-runtime.prod.js +516 -196
- data/dist/ember-spade.js +13 -1
- data/dist/ember-template-compiler.js +3 -21
- data/dist/ember-template-compiler.min.js +5 -7
- data/dist/ember-template-compiler.prod.js +1 -17
- data/dist/ember-tests.js +13 -1
- data/dist/ember.js +1030 -525
- data/dist/ember.min.js +12 -14
- data/dist/ember.prod.js +977 -501
- data/lib/ember/version.rb +1 -7
- metadata +5 -5
data/dist/ember-debug.js
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
(function() {
|
2
|
-
var Ember = { assert: function() {} };
|
3
|
-
// Version:
|
4
|
-
// Last commit: 697d46e (2014-01-13 21:44:17 -0500)
|
5
|
-
|
2
|
+
var Ember = { assert: function() {}, FEATURES: { isEnabled: function() {} } };
|
3
|
+
// Version: 1.1.0
|
6
4
|
|
7
5
|
(function() {
|
8
6
|
/*global __fail__*/
|
@@ -57,7 +55,7 @@ Ember.assert = function(desc, test) {
|
|
57
55
|
|
58
56
|
if (Ember.testing && !test) {
|
59
57
|
// when testing, ensure test failures when assertions fail
|
60
|
-
throw new Error("Assertion Failed: " + desc);
|
58
|
+
throw new Ember.Error("Assertion Failed: " + desc);
|
61
59
|
}
|
62
60
|
};
|
63
61
|
|
@@ -109,7 +107,7 @@ Ember.deprecate = function(message, test) {
|
|
109
107
|
if (arguments.length === 1) { test = false; }
|
110
108
|
if (test) { return; }
|
111
109
|
|
112
|
-
if (Ember.ENV.RAISE_ON_DEPRECATION) { throw new Error(message); }
|
110
|
+
if (Ember.ENV.RAISE_ON_DEPRECATION) { throw new Ember.Error(message); }
|
113
111
|
|
114
112
|
var error;
|
115
113
|
|
@@ -140,15 +138,21 @@ Ember.deprecate = function(message, test) {
|
|
140
138
|
|
141
139
|
|
142
140
|
/**
|
141
|
+
Alias an old, deprecated method with its new counterpart.
|
142
|
+
|
143
143
|
Display a deprecation warning with the provided message and a stack trace
|
144
|
-
(Chrome and Firefox only) when the
|
144
|
+
(Chrome and Firefox only) when the assigned method is called.
|
145
145
|
|
146
146
|
Ember build tools will not remove calls to `Ember.deprecateFunc()`, though
|
147
147
|
no warnings will be shown in production.
|
148
148
|
|
149
|
+
```javascript
|
150
|
+
Ember.oldMethod = Ember.deprecateFunc("Please use the new, updated method", Ember.newMethod);
|
151
|
+
```
|
152
|
+
|
149
153
|
@method deprecateFunc
|
150
154
|
@param {String} message A description of the deprecation.
|
151
|
-
@param {Function} func The function to
|
155
|
+
@param {Function} func The new function called to replace its deprecated counterpart.
|
152
156
|
@return {Function} a new function that wrapped the original function with a deprecation warning
|
153
157
|
*/
|
154
158
|
Ember.deprecateFunc = function(message, func) {
|
data/dist/ember-runtime.js
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
// Version:
|
2
|
-
// Last commit: 697d46e (2014-01-13 21:44:17 -0500)
|
3
|
-
|
1
|
+
// Version: 1.1.0
|
4
2
|
|
5
3
|
(function() {
|
6
4
|
/*global __fail__*/
|
@@ -55,7 +53,7 @@ Ember.assert = function(desc, test) {
|
|
55
53
|
|
56
54
|
if (Ember.testing && !test) {
|
57
55
|
// when testing, ensure test failures when assertions fail
|
58
|
-
throw new Error("Assertion Failed: " + desc);
|
56
|
+
throw new Ember.Error("Assertion Failed: " + desc);
|
59
57
|
}
|
60
58
|
};
|
61
59
|
|
@@ -107,7 +105,7 @@ Ember.deprecate = function(message, test) {
|
|
107
105
|
if (arguments.length === 1) { test = false; }
|
108
106
|
if (test) { return; }
|
109
107
|
|
110
|
-
if (Ember.ENV.RAISE_ON_DEPRECATION) { throw new Error(message); }
|
108
|
+
if (Ember.ENV.RAISE_ON_DEPRECATION) { throw new Ember.Error(message); }
|
111
109
|
|
112
110
|
var error;
|
113
111
|
|
@@ -138,15 +136,21 @@ Ember.deprecate = function(message, test) {
|
|
138
136
|
|
139
137
|
|
140
138
|
/**
|
139
|
+
Alias an old, deprecated method with its new counterpart.
|
140
|
+
|
141
141
|
Display a deprecation warning with the provided message and a stack trace
|
142
|
-
(Chrome and Firefox only) when the
|
142
|
+
(Chrome and Firefox only) when the assigned method is called.
|
143
143
|
|
144
144
|
Ember build tools will not remove calls to `Ember.deprecateFunc()`, though
|
145
145
|
no warnings will be shown in production.
|
146
146
|
|
147
|
+
```javascript
|
148
|
+
Ember.oldMethod = Ember.deprecateFunc("Please use the new, updated method", Ember.newMethod);
|
149
|
+
```
|
150
|
+
|
147
151
|
@method deprecateFunc
|
148
152
|
@param {String} message A description of the deprecation.
|
149
|
-
@param {Function} func The function to
|
153
|
+
@param {Function} func The new function called to replace its deprecated counterpart.
|
150
154
|
@return {Function} a new function that wrapped the original function with a deprecation warning
|
151
155
|
*/
|
152
156
|
Ember.deprecateFunc = function(message, func) {
|
@@ -170,9 +174,7 @@ if (!Ember.testing) {
|
|
170
174
|
|
171
175
|
})();
|
172
176
|
|
173
|
-
// Version:
|
174
|
-
// Last commit: 697d46e (2014-01-13 21:44:17 -0500)
|
175
|
-
|
177
|
+
// Version: 1.1.0
|
176
178
|
|
177
179
|
(function() {
|
178
180
|
var define, requireModule;
|
@@ -237,7 +239,7 @@ var define, requireModule;
|
|
237
239
|
|
238
240
|
@class Ember
|
239
241
|
@static
|
240
|
-
@version 1.0
|
242
|
+
@version 1.1.0
|
241
243
|
*/
|
242
244
|
|
243
245
|
if ('undefined' === typeof Ember) {
|
@@ -264,10 +266,10 @@ Ember.toString = function() { return "Ember"; };
|
|
264
266
|
/**
|
265
267
|
@property VERSION
|
266
268
|
@type String
|
267
|
-
@default '1.0
|
269
|
+
@default '1.1.0'
|
268
270
|
@final
|
269
271
|
*/
|
270
|
-
Ember.VERSION = '1.0
|
272
|
+
Ember.VERSION = '1.1.0';
|
271
273
|
|
272
274
|
/**
|
273
275
|
Standard environmental variables. You can define these in a global `ENV`
|
@@ -292,6 +294,27 @@ Ember.ENV = Ember.ENV || ENV;
|
|
292
294
|
|
293
295
|
Ember.config = Ember.config || {};
|
294
296
|
|
297
|
+
/**
|
298
|
+
Hash of enabled Canary features. Add to before creating your application.
|
299
|
+
|
300
|
+
@property FEATURES
|
301
|
+
@type Hash
|
302
|
+
*/
|
303
|
+
|
304
|
+
Ember.FEATURES = {};
|
305
|
+
|
306
|
+
/**
|
307
|
+
Test that a feature is enabled. Parsed by Ember's build tools to leave
|
308
|
+
experimental features out of beta/stable builds.
|
309
|
+
|
310
|
+
@method isEnabled
|
311
|
+
@param {string} feature
|
312
|
+
*/
|
313
|
+
|
314
|
+
Ember.FEATURES.isEnabled = function(feature) {
|
315
|
+
return Ember.FEATURES[feature];
|
316
|
+
};
|
317
|
+
|
295
318
|
// ..........................................................
|
296
319
|
// BOOTSTRAP
|
297
320
|
//
|
@@ -502,7 +525,7 @@ Ember.Logger = {
|
|
502
525
|
|
503
526
|
@method assert
|
504
527
|
@for Ember.Logger
|
505
|
-
@param
|
528
|
+
@param {Boolean} bool Value to test
|
506
529
|
*/
|
507
530
|
assert: consoleMethod('assert') || assertPolyfill
|
508
531
|
};
|
@@ -2251,6 +2274,7 @@ function suspendListeners(obj, eventNames, target, method, callback) {
|
|
2251
2274
|
}
|
2252
2275
|
|
2253
2276
|
var suspendedActions = [],
|
2277
|
+
actionsList = [],
|
2254
2278
|
eventName, actions, i, l;
|
2255
2279
|
|
2256
2280
|
for (i=0, l=eventNames.length; i<l; i++) {
|
@@ -2261,6 +2285,7 @@ function suspendListeners(obj, eventNames, target, method, callback) {
|
|
2261
2285
|
if (actionIndex !== -1) {
|
2262
2286
|
actions[actionIndex+2] |= SUSPENDED;
|
2263
2287
|
suspendedActions.push(actionIndex);
|
2288
|
+
actionsList.push(actions);
|
2264
2289
|
}
|
2265
2290
|
}
|
2266
2291
|
|
@@ -2269,7 +2294,7 @@ function suspendListeners(obj, eventNames, target, method, callback) {
|
|
2269
2294
|
function finalizer() {
|
2270
2295
|
for (var i = 0, l = suspendedActions.length; i < l; i++) {
|
2271
2296
|
var actionIndex = suspendedActions[i];
|
2272
|
-
|
2297
|
+
actionsList[i][actionIndex+2] &= ~SUSPENDED;
|
2273
2298
|
}
|
2274
2299
|
}
|
2275
2300
|
|
@@ -4609,18 +4634,18 @@ function registerComputedWithProperties(name, macro) {
|
|
4609
4634
|
}
|
4610
4635
|
|
4611
4636
|
/**
|
4612
|
-
A computed property that returns true
|
4637
|
+
A computed property that returns true if the value of the dependent
|
4613
4638
|
property is null, an empty string, empty array, or empty function.
|
4614
4639
|
|
4615
4640
|
Note: When using `Ember.computed.empty` to watch an array make sure to
|
4616
|
-
use the `array.
|
4641
|
+
use the `array.[]` syntax so the computed can subscribe to transitions
|
4617
4642
|
from empty to non-empty states.
|
4618
4643
|
|
4619
4644
|
Example
|
4620
4645
|
|
4621
4646
|
```javascript
|
4622
4647
|
var ToDoList = Ember.Object.extend({
|
4623
|
-
done: Ember.computed.empty('todos.
|
4648
|
+
done: Ember.computed.empty('todos.[]') // detect array changes
|
4624
4649
|
});
|
4625
4650
|
var todoList = ToDoList.create({todos: ['Unit Test', 'Documentation', 'Release']});
|
4626
4651
|
todoList.get('done'); // false
|
@@ -4639,7 +4664,7 @@ registerComputed('empty', function(dependentKey) {
|
|
4639
4664
|
});
|
4640
4665
|
|
4641
4666
|
/**
|
4642
|
-
A computed property that returns true
|
4667
|
+
A computed property that returns true if the value of the dependent
|
4643
4668
|
property is NOT null, an empty string, empty array, or empty function.
|
4644
4669
|
|
4645
4670
|
Example
|
@@ -4665,7 +4690,7 @@ registerComputed('notEmpty', function(dependentKey) {
|
|
4665
4690
|
});
|
4666
4691
|
|
4667
4692
|
/**
|
4668
|
-
A computed property that returns true
|
4693
|
+
A computed property that returns true if the value of the dependent
|
4669
4694
|
property is null or undefined. This avoids errors from JSLint complaining
|
4670
4695
|
about use of ==, which can be technically confusing.
|
4671
4696
|
|
@@ -4704,9 +4729,9 @@ registerComputed('none', function(dependentKey) {
|
|
4704
4729
|
isAnonymous: Ember.computed.not('loggedIn')
|
4705
4730
|
});
|
4706
4731
|
var user = User.create({loggedIn: false});
|
4707
|
-
user.get('isAnonymous'); // false
|
4708
|
-
user.set('loggedIn', true);
|
4709
4732
|
user.get('isAnonymous'); // true
|
4733
|
+
user.set('loggedIn', true);
|
4734
|
+
user.get('isAnonymous'); // false
|
4710
4735
|
```
|
4711
4736
|
|
4712
4737
|
@method computed.not
|
@@ -4740,7 +4765,7 @@ registerComputed('not', function(dependentKey) {
|
|
4740
4765
|
@method computed.bool
|
4741
4766
|
@for Ember
|
4742
4767
|
@param {String} dependentKey
|
4743
|
-
@return {Ember.ComputedProperty} computed property which
|
4768
|
+
@return {Ember.ComputedProperty} computed property which converts
|
4744
4769
|
to boolean the original value for property
|
4745
4770
|
*/
|
4746
4771
|
registerComputed('bool', function(dependentKey) {
|
@@ -4791,7 +4816,7 @@ registerComputed('match', function(dependentKey, regexp) {
|
|
4791
4816
|
var hampster = Hampster.create();
|
4792
4817
|
hampster.get('napTime'); // false
|
4793
4818
|
hampster.set('state', 'sleepy');
|
4794
|
-
hampster.get('napTime'); //
|
4819
|
+
hampster.get('napTime'); // true
|
4795
4820
|
hampster.set('state', 'hungry');
|
4796
4821
|
hampster.get('napTime'); // false
|
4797
4822
|
```
|
@@ -4958,7 +4983,7 @@ registerComputedWithProperties('and', function(properties) {
|
|
4958
4983
|
});
|
4959
4984
|
|
4960
4985
|
/**
|
4961
|
-
A computed property
|
4986
|
+
A computed property which performs a logical `or` on the
|
4962
4987
|
original values for the provided dependent properties.
|
4963
4988
|
|
4964
4989
|
Example
|
@@ -5125,7 +5150,7 @@ Ember.computed.alias = function(dependentKey) {
|
|
5125
5150
|
@method computed.oneWay
|
5126
5151
|
@for Ember
|
5127
5152
|
@param {String} dependentKey
|
5128
|
-
@return {Ember.ComputedProperty} computed property which creates
|
5153
|
+
@return {Ember.ComputedProperty} computed property which creates a
|
5129
5154
|
one way computed property to the original value for property.
|
5130
5155
|
*/
|
5131
5156
|
Ember.computed.oneWay = function(dependentKey) {
|
@@ -5137,7 +5162,7 @@ Ember.computed.oneWay = function(dependentKey) {
|
|
5137
5162
|
|
5138
5163
|
/**
|
5139
5164
|
A computed property that acts like a standard getter and setter,
|
5140
|
-
but
|
5165
|
+
but returns the value at the provided `defaultPath` if the
|
5141
5166
|
property itself has not been set to a value
|
5142
5167
|
|
5143
5168
|
Example
|
@@ -5505,7 +5530,12 @@ define("backburner",
|
|
5505
5530
|
debouncees = [],
|
5506
5531
|
timers = [],
|
5507
5532
|
autorun, laterTimer, laterTimerExpiresAt,
|
5508
|
-
global = this
|
5533
|
+
global = this,
|
5534
|
+
NUMBER = /\d+/;
|
5535
|
+
|
5536
|
+
function isCoercableNumber(number) {
|
5537
|
+
return typeof number === 'number' || NUMBER.test(number);
|
5538
|
+
}
|
5509
5539
|
|
5510
5540
|
function Backburner(queueNames, options) {
|
5511
5541
|
this.queueNames = queueNames;
|
@@ -5620,32 +5650,60 @@ define("backburner",
|
|
5620
5650
|
},
|
5621
5651
|
|
5622
5652
|
setTimeout: function() {
|
5623
|
-
var
|
5624
|
-
|
5625
|
-
|
5626
|
-
|
5627
|
-
|
5653
|
+
var args = slice.call(arguments);
|
5654
|
+
var length = args.length;
|
5655
|
+
var method, wait, target;
|
5656
|
+
var self = this;
|
5657
|
+
var methodOrTarget, methodOrWait, methodOrArgs;
|
5628
5658
|
|
5629
|
-
if (
|
5630
|
-
|
5631
|
-
|
5659
|
+
if (length === 0) {
|
5660
|
+
return;
|
5661
|
+
} else if (length === 1) {
|
5662
|
+
method = args.shift();
|
5663
|
+
wait = 0;
|
5664
|
+
} else if (length === 2) {
|
5665
|
+
methodOrTarget = args[0];
|
5666
|
+
methodOrWait = args[1];
|
5667
|
+
|
5668
|
+
if (typeof methodOrWait === 'function' || typeof methodOrTarget[methodOrWait] === 'function') {
|
5669
|
+
target = args.shift();
|
5670
|
+
method = args.shift();
|
5671
|
+
wait = 0;
|
5672
|
+
} else if (isCoercableNumber(methodOrWait)) {
|
5673
|
+
method = args.shift();
|
5674
|
+
wait = args.shift();
|
5675
|
+
} else {
|
5676
|
+
method = args.shift();
|
5677
|
+
wait = 0;
|
5678
|
+
}
|
5679
|
+
} else {
|
5680
|
+
var last = args[args.length - 1];
|
5681
|
+
|
5682
|
+
if (isCoercableNumber(last)) {
|
5683
|
+
wait = args.pop();
|
5684
|
+
}
|
5685
|
+
|
5686
|
+
methodOrTarget = args[0];
|
5687
|
+
methodOrArgs = args[1];
|
5688
|
+
|
5689
|
+
if (typeof methodOrArgs === 'function' || (typeof methodOrArgs === 'string' &&
|
5690
|
+
methodOrTarget !== null &&
|
5691
|
+
methodOrArgs in methodOrTarget)) {
|
5692
|
+
target = args.shift();
|
5693
|
+
method = args.shift();
|
5694
|
+
} else {
|
5695
|
+
method = args.shift();
|
5696
|
+
}
|
5632
5697
|
}
|
5633
5698
|
|
5699
|
+
var executeAt = (+new Date()) + parseInt(wait, 10);
|
5700
|
+
|
5634
5701
|
if (typeof method === 'string') {
|
5635
5702
|
method = target[method];
|
5636
5703
|
}
|
5637
5704
|
|
5638
|
-
|
5639
|
-
|
5640
|
-
args = slice.call(arguments, 2);
|
5641
|
-
|
5642
|
-
fn = function() {
|
5643
|
-
method.apply(target, args);
|
5644
|
-
};
|
5645
|
-
} else {
|
5646
|
-
fn = function() {
|
5647
|
-
method.call(target);
|
5648
|
-
};
|
5705
|
+
function fn() {
|
5706
|
+
method.apply(target, args);
|
5649
5707
|
}
|
5650
5708
|
|
5651
5709
|
// find position to insert - TODO: binary search
|
@@ -5846,6 +5904,7 @@ define("backburner",
|
|
5846
5904
|
|
5847
5905
|
__exports__.Backburner = Backburner;
|
5848
5906
|
});
|
5907
|
+
|
5849
5908
|
})();
|
5850
5909
|
|
5851
5910
|
|
@@ -6981,7 +7040,9 @@ function applyConcatenatedProperties(obj, key, value, values) {
|
|
6981
7040
|
return Ember.makeArray(baseValue).concat(value);
|
6982
7041
|
}
|
6983
7042
|
} else {
|
6984
|
-
|
7043
|
+
// Make sure this mixin has its own array so it is not
|
7044
|
+
// accidentally mutated by another child's interactions
|
7045
|
+
return Ember.makeArray(value).slice();
|
6985
7046
|
}
|
6986
7047
|
}
|
6987
7048
|
|
@@ -7019,15 +7080,14 @@ function addNormalizedProperty(base, key, value, meta, descs, values, concats, m
|
|
7019
7080
|
descs[key] = value;
|
7020
7081
|
values[key] = undefined;
|
7021
7082
|
} else {
|
7022
|
-
|
7023
|
-
if (isMethod(value)) {
|
7024
|
-
value = giveMethodSuper(base, key, value, values, descs);
|
7025
|
-
} else if ((concats && a_indexOf.call(concats, key) >= 0) ||
|
7083
|
+
if ((concats && a_indexOf.call(concats, key) >= 0) ||
|
7026
7084
|
key === 'concatenatedProperties' ||
|
7027
7085
|
key === 'mergedProperties') {
|
7028
7086
|
value = applyConcatenatedProperties(base, key, value, values);
|
7029
7087
|
} else if ((mergings && a_indexOf.call(mergings, key) >= 0)) {
|
7030
7088
|
value = applyMergedProperties(base, key, value, values);
|
7089
|
+
} else if (isMethod(value)) {
|
7090
|
+
value = giveMethodSuper(base, key, value, values, descs);
|
7031
7091
|
}
|
7032
7092
|
|
7033
7093
|
descs[key] = undefined;
|
@@ -7463,11 +7523,10 @@ Alias.prototype = new Ember.Descriptor();
|
|
7463
7523
|
@deprecated Use `Ember.aliasMethod` or `Ember.computed.alias` instead
|
7464
7524
|
*/
|
7465
7525
|
Ember.alias = function(methodName) {
|
7526
|
+
Ember.deprecate("Ember.alias is deprecated. Please use Ember.aliasMethod or Ember.computed.alias instead.");
|
7466
7527
|
return new Alias(methodName);
|
7467
7528
|
};
|
7468
7529
|
|
7469
|
-
Ember.alias = Ember.deprecateFunc("Ember.alias is deprecated. Please use Ember.aliasMethod or Ember.computed.alias instead.", Ember.alias);
|
7470
|
-
|
7471
7530
|
/**
|
7472
7531
|
Makes a method available via an additional name.
|
7473
7532
|
|
@@ -7609,6 +7668,55 @@ Ember.beforeObserver = function(func) {
|
|
7609
7668
|
|
7610
7669
|
|
7611
7670
|
|
7671
|
+
(function() {
|
7672
|
+
// Provides a way to register library versions with ember.
|
7673
|
+
var forEach = Ember.EnumerableUtils.forEach,
|
7674
|
+
indexOf = Ember.EnumerableUtils.indexOf;
|
7675
|
+
|
7676
|
+
Ember.libraries = function() {
|
7677
|
+
var libraries = [];
|
7678
|
+
var coreLibIndex = 0;
|
7679
|
+
|
7680
|
+
var getLibrary = function(name) {
|
7681
|
+
for (var i = 0; i < libraries.length; i++) {
|
7682
|
+
if (libraries[i].name === name) {
|
7683
|
+
return libraries[i];
|
7684
|
+
}
|
7685
|
+
}
|
7686
|
+
};
|
7687
|
+
|
7688
|
+
libraries.register = function(name, version) {
|
7689
|
+
if (!getLibrary(name)) {
|
7690
|
+
libraries.push({name: name, version: version});
|
7691
|
+
}
|
7692
|
+
};
|
7693
|
+
|
7694
|
+
libraries.registerCoreLibrary = function(name, version) {
|
7695
|
+
if (!getLibrary(name)) {
|
7696
|
+
libraries.splice(coreLibIndex++, 0, {name: name, version: version});
|
7697
|
+
}
|
7698
|
+
};
|
7699
|
+
|
7700
|
+
libraries.deRegister = function(name) {
|
7701
|
+
var lib = getLibrary(name);
|
7702
|
+
if (lib) libraries.splice(indexOf(libraries, lib), 1);
|
7703
|
+
};
|
7704
|
+
|
7705
|
+
libraries.each = function (callback) {
|
7706
|
+
forEach(libraries, function(lib) {
|
7707
|
+
callback(lib.name, lib.version);
|
7708
|
+
});
|
7709
|
+
};
|
7710
|
+
|
7711
|
+
return libraries;
|
7712
|
+
}();
|
7713
|
+
|
7714
|
+
Ember.libraries.registerCoreLibrary('Ember', Ember.VERSION);
|
7715
|
+
|
7716
|
+
})();
|
7717
|
+
|
7718
|
+
|
7719
|
+
|
7612
7720
|
(function() {
|
7613
7721
|
/**
|
7614
7722
|
Ember Metal
|
@@ -8267,6 +8375,13 @@ define("rsvp",
|
|
8267
8375
|
|
8268
8376
|
(function() {
|
8269
8377
|
/**
|
8378
|
+
@private
|
8379
|
+
Public api for the container is still in flux.
|
8380
|
+
The public api, specified on the application namespace should be considered the stable api.
|
8381
|
+
// @module container
|
8382
|
+
*/
|
8383
|
+
|
8384
|
+
/*
|
8270
8385
|
Flag to enable/disable model factory injections (disabled by default)
|
8271
8386
|
If model factory injections are enabled, models should not be
|
8272
8387
|
accessed globally (only through `container.lookupFactory('model:modelName'))`);
|
@@ -8277,11 +8392,7 @@ define("container",
|
|
8277
8392
|
[],
|
8278
8393
|
function() {
|
8279
8394
|
|
8280
|
-
|
8281
|
-
A safe and simple inheriting object.
|
8282
|
-
|
8283
|
-
@class InheritingDict
|
8284
|
-
*/
|
8395
|
+
// A safe and simple inheriting object.
|
8285
8396
|
function InheritingDict(parent) {
|
8286
8397
|
this.parent = parent;
|
8287
8398
|
this.dict = {};
|
@@ -8354,7 +8465,7 @@ define("container",
|
|
8354
8465
|
|
8355
8466
|
@method has
|
8356
8467
|
@param {String} key
|
8357
|
-
@
|
8468
|
+
@return {Boolean}
|
8358
8469
|
*/
|
8359
8470
|
has: function(key) {
|
8360
8471
|
var dict = this.dict;
|
@@ -8388,11 +8499,10 @@ define("container",
|
|
8388
8499
|
}
|
8389
8500
|
};
|
8390
8501
|
|
8391
|
-
/**
|
8392
|
-
A lightweight container that helps to assemble and decouple components.
|
8393
8502
|
|
8394
|
-
|
8395
|
-
|
8503
|
+
// A lightweight container that helps to assemble and decouple components.
|
8504
|
+
// Public api for the container is still in flux.
|
8505
|
+
// The public api, specified on the application namespace should be considered the stable api.
|
8396
8506
|
function Container(parent) {
|
8397
8507
|
this.parent = parent;
|
8398
8508
|
this.children = [];
|
@@ -8481,7 +8591,7 @@ define("container",
|
|
8481
8591
|
to correctly inherit from the current container.
|
8482
8592
|
|
8483
8593
|
@method child
|
8484
|
-
@
|
8594
|
+
@return {Container}
|
8485
8595
|
*/
|
8486
8596
|
child: function() {
|
8487
8597
|
var container = new Container(this);
|
@@ -8517,25 +8627,25 @@ define("container",
|
|
8517
8627
|
```
|
8518
8628
|
|
8519
8629
|
@method register
|
8520
|
-
@param {String}
|
8521
|
-
@param {String} name
|
8630
|
+
@param {String} fullName
|
8522
8631
|
@param {Function} factory
|
8523
8632
|
@param {Object} options
|
8524
8633
|
*/
|
8525
|
-
register: function(
|
8526
|
-
|
8634
|
+
register: function(fullName, factory, options) {
|
8635
|
+
if (fullName.indexOf(':') === -1) {
|
8636
|
+
throw new TypeError("malformed fullName, expected: `type:name` got: " + fullName + "");
|
8637
|
+
}
|
8527
8638
|
|
8528
|
-
if (
|
8529
|
-
|
8530
|
-
factory = name;
|
8531
|
-
fullName = type;
|
8532
|
-
} else {
|
8533
|
-
Ember.deprecate('register("'+type +'", "'+ name+'") is now deprecated in-favour of register("'+type+':'+name+'");', false);
|
8534
|
-
fullName = type + ":" + name;
|
8639
|
+
if (factory === undefined) {
|
8640
|
+
throw new TypeError('Attempting to register an unknown factory: `' + fullName + '`');
|
8535
8641
|
}
|
8536
8642
|
|
8537
8643
|
var normalizedName = this.normalize(fullName);
|
8538
8644
|
|
8645
|
+
if (this.cache.has(normalizedName)) {
|
8646
|
+
throw new Error('Cannot re-register: `' + fullName +'`, as it has already been looked up.');
|
8647
|
+
}
|
8648
|
+
|
8539
8649
|
this.registry.set(normalizedName, factory);
|
8540
8650
|
this._options.set(normalizedName, options || {});
|
8541
8651
|
},
|
@@ -8595,7 +8705,7 @@ define("container",
|
|
8595
8705
|
|
8596
8706
|
@method resolve
|
8597
8707
|
@param {String} fullName
|
8598
|
-
@
|
8708
|
+
@return {Function} fullName's factory
|
8599
8709
|
*/
|
8600
8710
|
resolve: function(fullName) {
|
8601
8711
|
return this.resolver(fullName) || this.registry.get(fullName);
|
@@ -8630,7 +8740,7 @@ define("container",
|
|
8630
8740
|
@method makeToString
|
8631
8741
|
|
8632
8742
|
@param {any} factory
|
8633
|
-
@param {string}
|
8743
|
+
@param {string} fullName
|
8634
8744
|
@return {function} toString function
|
8635
8745
|
*/
|
8636
8746
|
makeToString: function(factory, fullName) {
|
@@ -8687,7 +8797,7 @@ define("container",
|
|
8687
8797
|
|
8688
8798
|
var value = instantiate(this, fullName);
|
8689
8799
|
|
8690
|
-
if (
|
8800
|
+
if (value === undefined) { return; }
|
8691
8801
|
|
8692
8802
|
if (isSingleton(this, fullName) && options.singleton !== false) {
|
8693
8803
|
this.cache.set(fullName, value);
|
@@ -8765,7 +8875,7 @@ define("container",
|
|
8765
8875
|
this.optionsForType(type, options);
|
8766
8876
|
},
|
8767
8877
|
|
8768
|
-
|
8878
|
+
/**
|
8769
8879
|
@private
|
8770
8880
|
|
8771
8881
|
Used only via `injection`.
|
@@ -8807,7 +8917,7 @@ define("container",
|
|
8807
8917
|
addTypeInjection(this.typeInjections, type, property, fullName);
|
8808
8918
|
},
|
8809
8919
|
|
8810
|
-
|
8920
|
+
/**
|
8811
8921
|
Defines injection rules.
|
8812
8922
|
|
8813
8923
|
These rules are used to inject dependencies onto objects when they
|
@@ -8815,8 +8925,8 @@ define("container",
|
|
8815
8925
|
|
8816
8926
|
Two forms of injections are possible:
|
8817
8927
|
|
8818
|
-
|
8819
|
-
|
8928
|
+
* Injecting one fullName on another fullName
|
8929
|
+
* Injecting one fullName on a type
|
8820
8930
|
|
8821
8931
|
Example:
|
8822
8932
|
|
@@ -8862,7 +8972,7 @@ define("container",
|
|
8862
8972
|
},
|
8863
8973
|
|
8864
8974
|
|
8865
|
-
|
8975
|
+
/**
|
8866
8976
|
@private
|
8867
8977
|
|
8868
8978
|
Used only via `factoryInjection`.
|
@@ -8899,7 +9009,7 @@ define("container",
|
|
8899
9009
|
addTypeInjection(this.factoryTypeInjections, type, property, fullName);
|
8900
9010
|
},
|
8901
9011
|
|
8902
|
-
|
9012
|
+
/**
|
8903
9013
|
Defines factory injection rules.
|
8904
9014
|
|
8905
9015
|
Similar to regular injection rules, but are run against factories, via
|
@@ -8910,8 +9020,8 @@ define("container",
|
|
8910
9020
|
|
8911
9021
|
Two forms of injections are possible:
|
8912
9022
|
|
8913
|
-
|
8914
|
-
|
9023
|
+
* Injecting one fullName on another fullName
|
9024
|
+
* Injecting one fullName on a type
|
8915
9025
|
|
8916
9026
|
Example:
|
8917
9027
|
|
@@ -9013,7 +9123,7 @@ define("container",
|
|
9013
9123
|
injection = injections[i];
|
9014
9124
|
lookup = container.lookup(injection.fullName);
|
9015
9125
|
|
9016
|
-
if (lookup) {
|
9126
|
+
if (lookup !== undefined) {
|
9017
9127
|
hash[injection.property] = lookup;
|
9018
9128
|
} else {
|
9019
9129
|
throw new Error('Attempting to inject an unknown injection: `' + injection.fullName + '`');
|
@@ -9045,13 +9155,13 @@ define("container",
|
|
9045
9155
|
var cache = container.factoryCache;
|
9046
9156
|
var type = fullName.split(":")[0];
|
9047
9157
|
|
9048
|
-
if (
|
9158
|
+
if (factory === undefined) { return; }
|
9049
9159
|
|
9050
9160
|
if (cache.has(fullName)) {
|
9051
9161
|
return cache.get(fullName);
|
9052
9162
|
}
|
9053
9163
|
|
9054
|
-
if (typeof factory.extend !== 'function' || (!Ember.MODEL_FACTORY_INJECTIONS && type === 'model')) {
|
9164
|
+
if (!factory || typeof factory.extend !== 'function' || (!Ember.MODEL_FACTORY_INJECTIONS && type === 'model')) {
|
9055
9165
|
// TODO: think about a 'safe' merge style extension
|
9056
9166
|
// for now just fallback to create time injection
|
9057
9167
|
return factory;
|
@@ -9427,16 +9537,39 @@ Ember.ORDER_DEFINITION = Ember.ENV.ORDER_DEFINITION || [
|
|
9427
9537
|
Ember.keys = Object.keys;
|
9428
9538
|
|
9429
9539
|
if (!Ember.keys || Ember.create.isSimulated) {
|
9540
|
+
var prototypeProperties = [
|
9541
|
+
'constructor',
|
9542
|
+
'hasOwnProperty',
|
9543
|
+
'isPrototypeOf',
|
9544
|
+
'propertyIsEnumerable',
|
9545
|
+
'valueOf',
|
9546
|
+
'toLocaleString',
|
9547
|
+
'toString'
|
9548
|
+
],
|
9549
|
+
pushPropertyName = function(obj, array, key) {
|
9550
|
+
// Prevents browsers that don't respect non-enumerability from
|
9551
|
+
// copying internal Ember properties
|
9552
|
+
if (key.substring(0,2) === '__') return;
|
9553
|
+
if (key === '_super') return;
|
9554
|
+
if (indexOf(array, key) >= 0) return;
|
9555
|
+
if (!obj.hasOwnProperty(key)) return;
|
9556
|
+
|
9557
|
+
array.push(key);
|
9558
|
+
};
|
9559
|
+
|
9430
9560
|
Ember.keys = function(obj) {
|
9431
|
-
var ret = [];
|
9432
|
-
for(
|
9433
|
-
|
9434
|
-
|
9435
|
-
if (key.substring(0,2) === '__') continue;
|
9436
|
-
if (key === '_super') continue;
|
9561
|
+
var ret = [], key;
|
9562
|
+
for (key in obj) {
|
9563
|
+
pushPropertyName(obj, ret, key);
|
9564
|
+
}
|
9437
9565
|
|
9438
|
-
|
9566
|
+
// IE8 doesn't enumerate property that named the same as prototype properties.
|
9567
|
+
for (var i = 0, l = prototypeProperties.length; i < l; i++) {
|
9568
|
+
key = prototypeProperties[i];
|
9569
|
+
|
9570
|
+
pushPropertyName(obj, ret, key);
|
9439
9571
|
}
|
9572
|
+
|
9440
9573
|
return ret;
|
9441
9574
|
};
|
9442
9575
|
}
|
@@ -10876,6 +11009,8 @@ var get = Ember.get,
|
|
10876
11009
|
set = Ember.set,
|
10877
11010
|
guidFor = Ember.guidFor,
|
10878
11011
|
metaFor = Ember.meta,
|
11012
|
+
propertyWillChange = Ember.propertyWillChange,
|
11013
|
+
propertyDidChange = Ember.propertyDidChange,
|
10879
11014
|
addBeforeObserver = Ember.addBeforeObserver,
|
10880
11015
|
removeBeforeObserver = Ember.removeBeforeObserver,
|
10881
11016
|
addObserver = Ember.addObserver,
|
@@ -10930,11 +11065,13 @@ function ItemPropertyObserverContext (dependentArray, index, trackedArray) {
|
|
10930
11065
|
this.trackedArray = trackedArray;
|
10931
11066
|
this.beforeObserver = null;
|
10932
11067
|
this.observer = null;
|
11068
|
+
|
11069
|
+
this.destroyed = false;
|
10933
11070
|
}
|
10934
11071
|
|
10935
11072
|
DependentArraysObserver.prototype = {
|
10936
11073
|
setValue: function (newValue) {
|
10937
|
-
this.instanceMeta.setValue(newValue);
|
11074
|
+
this.instanceMeta.setValue(newValue, true);
|
10938
11075
|
},
|
10939
11076
|
getValue: function () {
|
10940
11077
|
return this.instanceMeta.getValue();
|
@@ -10999,6 +11136,7 @@ DependentArraysObserver.prototype = {
|
|
10999
11136
|
if (operation === Ember.TrackedArray.DELETE) { return; }
|
11000
11137
|
|
11001
11138
|
forEach(observerContexts, function (observerContext) {
|
11139
|
+
observerContext.destroyed = true;
|
11002
11140
|
beforeObserver = observerContext.beforeObserver;
|
11003
11141
|
observer = observerContext.observer;
|
11004
11142
|
item = observerContext.item;
|
@@ -11023,11 +11161,10 @@ DependentArraysObserver.prototype = {
|
|
11023
11161
|
var dependentArrayObserver = this;
|
11024
11162
|
|
11025
11163
|
observerContext.beforeObserver = function (obj, keyName) {
|
11026
|
-
dependentArrayObserver.
|
11027
|
-
return dependentArrayObserver.itemPropertyWillChange(obj, keyName, observerContext.dependentArray, observerContext.index);
|
11164
|
+
return dependentArrayObserver.itemPropertyWillChange(obj, keyName, observerContext.dependentArray, observerContext);
|
11028
11165
|
};
|
11029
11166
|
observerContext.observer = function (obj, keyName) {
|
11030
|
-
return dependentArrayObserver.itemPropertyDidChange(obj, keyName, observerContext.dependentArray, observerContext
|
11167
|
+
return dependentArrayObserver.itemPropertyDidChange(obj, keyName, observerContext.dependentArray, observerContext);
|
11031
11168
|
};
|
11032
11169
|
},
|
11033
11170
|
|
@@ -11035,14 +11172,14 @@ DependentArraysObserver.prototype = {
|
|
11035
11172
|
this.trackedArraysByGuid[dependentKey] = new Ember.TrackedArray(observerContexts);
|
11036
11173
|
},
|
11037
11174
|
|
11038
|
-
|
11175
|
+
trackAdd: function (dependentKey, index, newItems) {
|
11039
11176
|
var trackedArray = this.trackedArraysByGuid[dependentKey];
|
11040
11177
|
if (trackedArray) {
|
11041
11178
|
trackedArray.addItems(index, newItems);
|
11042
11179
|
}
|
11043
11180
|
},
|
11044
11181
|
|
11045
|
-
|
11182
|
+
trackRemove: function (dependentKey, index, removedCount) {
|
11046
11183
|
var trackedArray = this.trackedArraysByGuid[dependentKey];
|
11047
11184
|
|
11048
11185
|
if (trackedArray) {
|
@@ -11083,10 +11220,10 @@ DependentArraysObserver.prototype = {
|
|
11083
11220
|
sliceIndex,
|
11084
11221
|
observerContexts;
|
11085
11222
|
|
11086
|
-
observerContexts = this.
|
11087
|
-
|
11223
|
+
observerContexts = this.trackRemove(dependentKey, index, removedCount);
|
11088
11224
|
|
11089
11225
|
function removeObservers(propertyKey) {
|
11226
|
+
observerContexts[sliceIndex].destroyed = true;
|
11090
11227
|
removeBeforeObserver(item, propertyKey, this, observerContexts[sliceIndex].beforeObserver);
|
11091
11228
|
removeObserver(item, propertyKey, this, observerContexts[sliceIndex].observer);
|
11092
11229
|
}
|
@@ -11128,33 +11265,38 @@ DependentArraysObserver.prototype = {
|
|
11128
11265
|
this.instanceMeta.context, this.getValue(), item, changeMeta, this.instanceMeta.sugarMeta));
|
11129
11266
|
}, this);
|
11130
11267
|
|
11131
|
-
this.
|
11268
|
+
this.trackAdd(dependentKey, index, observerContexts);
|
11132
11269
|
},
|
11133
11270
|
|
11134
|
-
itemPropertyWillChange: function (obj, keyName, array,
|
11271
|
+
itemPropertyWillChange: function (obj, keyName, array, observerContext) {
|
11135
11272
|
var guid = guidFor(obj);
|
11136
11273
|
|
11137
11274
|
if (!this.changedItems[guid]) {
|
11138
11275
|
this.changedItems[guid] = {
|
11139
|
-
array:
|
11140
|
-
|
11141
|
-
obj:
|
11142
|
-
previousValues:
|
11276
|
+
array: array,
|
11277
|
+
observerContext: observerContext,
|
11278
|
+
obj: obj,
|
11279
|
+
previousValues: {}
|
11143
11280
|
};
|
11144
11281
|
}
|
11145
11282
|
|
11146
11283
|
this.changedItems[guid].previousValues[keyName] = get(obj, keyName);
|
11147
11284
|
},
|
11148
11285
|
|
11149
|
-
itemPropertyDidChange: function(obj, keyName, array,
|
11150
|
-
|
11286
|
+
itemPropertyDidChange: function(obj, keyName, array, observerContext) {
|
11287
|
+
this.flushChanges();
|
11151
11288
|
},
|
11152
11289
|
|
11153
11290
|
flushChanges: function() {
|
11154
11291
|
var changedItems = this.changedItems, key, c, changeMeta;
|
11292
|
+
|
11155
11293
|
for (key in changedItems) {
|
11156
11294
|
c = changedItems[key];
|
11157
|
-
|
11295
|
+
if (c.observerContext.destroyed) { continue; }
|
11296
|
+
|
11297
|
+
this.updateIndexes(c.observerContext.trackedArray, c.observerContext.dependentArray);
|
11298
|
+
|
11299
|
+
changeMeta = createChangeMeta(c.array, c.obj, c.observerContext.index, this.instanceMeta.propertyName, this.cp, c.previousValues);
|
11158
11300
|
this.setValue(
|
11159
11301
|
this.callbacks.removedItem.call(this.instanceMeta.context, this.getValue(), c.obj, changeMeta, this.instanceMeta.sugarMeta));
|
11160
11302
|
this.setValue(
|
@@ -11224,11 +11366,21 @@ ReduceComputedPropertyInstanceMeta.prototype = {
|
|
11224
11366
|
}
|
11225
11367
|
},
|
11226
11368
|
|
11227
|
-
setValue: function(newValue) {
|
11369
|
+
setValue: function(newValue, triggerObservers) {
|
11228
11370
|
// This lets sugars force a recomputation, handy for very simple
|
11229
11371
|
// implementations of eg max.
|
11230
11372
|
if (newValue !== undefined) {
|
11373
|
+
var fireObservers = triggerObservers && (newValue !== this.cache[this.propertyName]);
|
11374
|
+
|
11375
|
+
if (fireObservers) {
|
11376
|
+
propertyWillChange(this.context, this.propertyName);
|
11377
|
+
}
|
11378
|
+
|
11231
11379
|
this.cache[this.propertyName] = newValue;
|
11380
|
+
|
11381
|
+
if (fireObservers) {
|
11382
|
+
propertyDidChange(this.context, this.propertyName);
|
11383
|
+
}
|
11232
11384
|
} else {
|
11233
11385
|
delete this.cache[this.propertyName];
|
11234
11386
|
}
|
@@ -11354,13 +11506,11 @@ ReduceComputedProperty.prototype._instanceMeta = function (context, propertyName
|
|
11354
11506
|
};
|
11355
11507
|
|
11356
11508
|
ReduceComputedProperty.prototype.initialValue = function () {
|
11357
|
-
|
11358
|
-
|
11359
|
-
|
11360
|
-
|
11361
|
-
|
11362
|
-
default:
|
11363
|
-
return this.options.initialValue;
|
11509
|
+
if (typeof this.options.initialValue === 'function') {
|
11510
|
+
return this.options.initialValue();
|
11511
|
+
}
|
11512
|
+
else {
|
11513
|
+
return this.options.initialValue;
|
11364
11514
|
}
|
11365
11515
|
};
|
11366
11516
|
|
@@ -11383,25 +11533,25 @@ ReduceComputedProperty.prototype.clearItemPropertyKeys = function (dependentArra
|
|
11383
11533
|
ReduceComputedProperty.prototype.property = function () {
|
11384
11534
|
var cp = this,
|
11385
11535
|
args = a_slice.call(arguments),
|
11386
|
-
propertyArgs =
|
11536
|
+
propertyArgs = new Ember.Set(),
|
11387
11537
|
match,
|
11388
11538
|
dependentArrayKey,
|
11389
11539
|
itemPropertyKey;
|
11390
11540
|
|
11391
11541
|
forEach(a_slice.call(arguments), function (dependentKey) {
|
11392
11542
|
if (doubleEachPropertyPattern.test(dependentKey)) {
|
11393
|
-
throw new Error("Nested @each properties not supported: " + dependentKey);
|
11543
|
+
throw new Ember.Error("Nested @each properties not supported: " + dependentKey);
|
11394
11544
|
} else if (match = eachPropertyPattern.exec(dependentKey)) {
|
11395
11545
|
dependentArrayKey = match[1];
|
11396
11546
|
itemPropertyKey = match[2];
|
11397
11547
|
cp.itemPropertyKey(dependentArrayKey, itemPropertyKey);
|
11398
|
-
propertyArgs.
|
11548
|
+
propertyArgs.add(dependentArrayKey);
|
11399
11549
|
} else {
|
11400
|
-
propertyArgs.
|
11550
|
+
propertyArgs.add(dependentKey);
|
11401
11551
|
}
|
11402
11552
|
});
|
11403
11553
|
|
11404
|
-
return ComputedProperty.prototype.property.apply(this, propertyArgs);
|
11554
|
+
return ComputedProperty.prototype.property.apply(this, propertyArgs.toArray());
|
11405
11555
|
};
|
11406
11556
|
|
11407
11557
|
/**
|
@@ -11413,7 +11563,7 @@ ReduceComputedProperty.prototype.property = function () {
|
|
11413
11563
|
If there are more than one arguments the first arguments are
|
11414
11564
|
considered to be dependent property keys. The last argument is
|
11415
11565
|
required to be an options object. The options object can have the
|
11416
|
-
following four properties
|
11566
|
+
following four properties:
|
11417
11567
|
|
11418
11568
|
`initialValue` - A value or function that will be used as the initial
|
11419
11569
|
value for the computed. If this property is a function the result of calling
|
@@ -11494,6 +11644,12 @@ ReduceComputedProperty.prototype.property = function () {
|
|
11494
11644
|
to invalidate the computation. This is generally not a good idea for
|
11495
11645
|
arrayComputed but it's used in eg max and min.
|
11496
11646
|
|
11647
|
+
Note that observers will be fired if either of these functions return a value
|
11648
|
+
that differs from the accumulated value. When returning an object that
|
11649
|
+
mutates in response to array changes, for example an array that maps
|
11650
|
+
everything from some other array (see `Ember.computed.map`), it is usually
|
11651
|
+
important that the *same* array be returned to avoid accidentally triggering observers.
|
11652
|
+
|
11497
11653
|
Example
|
11498
11654
|
|
11499
11655
|
```javascript
|
@@ -11518,7 +11674,7 @@ ReduceComputedProperty.prototype.property = function () {
|
|
11518
11674
|
@for Ember
|
11519
11675
|
@param {String} [dependentKeys*]
|
11520
11676
|
@param {Object} options
|
11521
|
-
@
|
11677
|
+
@return {Ember.ComputedProperty}
|
11522
11678
|
*/
|
11523
11679
|
Ember.reduceComputed = function (options) {
|
11524
11680
|
var args;
|
@@ -11529,11 +11685,11 @@ Ember.reduceComputed = function (options) {
|
|
11529
11685
|
}
|
11530
11686
|
|
11531
11687
|
if (typeof options !== "object") {
|
11532
|
-
throw new Error("Reduce Computed Property declared without an options hash");
|
11688
|
+
throw new Ember.Error("Reduce Computed Property declared without an options hash");
|
11533
11689
|
}
|
11534
11690
|
|
11535
|
-
if (!options
|
11536
|
-
throw new Error("Reduce Computed Property declared without an initial value");
|
11691
|
+
if (!('initialValue' in options)) {
|
11692
|
+
throw new Ember.Error("Reduce Computed Property declared without an initial value");
|
11537
11693
|
}
|
11538
11694
|
|
11539
11695
|
var cp = new ReduceComputedProperty(options);
|
@@ -11701,7 +11857,7 @@ ArrayComputedProperty.prototype.resetValue = function (array) {
|
|
11701
11857
|
@for Ember
|
11702
11858
|
@param {String} [dependentKeys*]
|
11703
11859
|
@param {Object} options
|
11704
|
-
@
|
11860
|
+
@return {Ember.ComputedProperty}
|
11705
11861
|
*/
|
11706
11862
|
Ember.arrayComputed = function (options) {
|
11707
11863
|
var args;
|
@@ -11712,7 +11868,7 @@ Ember.arrayComputed = function (options) {
|
|
11712
11868
|
}
|
11713
11869
|
|
11714
11870
|
if (typeof options !== "object") {
|
11715
|
-
throw new Error("Array Computed Property declared without an options hash");
|
11871
|
+
throw new Ember.Error("Array Computed Property declared without an options hash");
|
11716
11872
|
}
|
11717
11873
|
|
11718
11874
|
var cp = new ArrayComputedProperty(options);
|
@@ -11859,7 +12015,7 @@ Ember.computed.min = function (dependentKey) {
|
|
11859
12015
|
Ember.computed.map = function(dependentKey, callback) {
|
11860
12016
|
var options = {
|
11861
12017
|
addedItem: function(array, item, changeMeta, instanceMeta) {
|
11862
|
-
var mapped = callback(item);
|
12018
|
+
var mapped = callback.call(this, item);
|
11863
12019
|
array.insertAt(changeMeta.index, mapped);
|
11864
12020
|
return array;
|
11865
12021
|
},
|
@@ -11879,16 +12035,15 @@ Ember.computed.map = function(dependentKey, callback) {
|
|
11879
12035
|
|
11880
12036
|
```javascript
|
11881
12037
|
App.Person = Ember.Object.extend({
|
11882
|
-
childAges: Ember.computed.mapBy('children', 'age')
|
11883
|
-
minChildAge: Ember.computed.min('childAges')
|
12038
|
+
childAges: Ember.computed.mapBy('children', 'age')
|
11884
12039
|
});
|
11885
12040
|
|
11886
12041
|
var lordByron = App.Person.create({children: []});
|
11887
|
-
lordByron.get('
|
12042
|
+
lordByron.get('childAges'); // []
|
11888
12043
|
lordByron.get('children').pushObject({name: 'Augusta Ada Byron', age: 7});
|
11889
|
-
lordByron.get('
|
12044
|
+
lordByron.get('childAges'); // [7]
|
11890
12045
|
lordByron.get('children').pushObjects([{name: 'Allegra Byron', age: 5}, {name: 'Elizabeth Medora Leigh', age: 8}]);
|
11891
|
-
lordByron.get('
|
12046
|
+
lordByron.get('childAges'); // [7, 5, 8]
|
11892
12047
|
```
|
11893
12048
|
|
11894
12049
|
@method computed.mapBy
|
@@ -11952,7 +12107,7 @@ Ember.computed.filter = function(dependentKey, callback) {
|
|
11952
12107
|
},
|
11953
12108
|
|
11954
12109
|
addedItem: function(array, item, changeMeta, instanceMeta) {
|
11955
|
-
var match = !!callback(item),
|
12110
|
+
var match = !!callback.call(this, item),
|
11956
12111
|
filterIndex = instanceMeta.filteredArrayIndexes.addItem(changeMeta.index, match);
|
11957
12112
|
|
11958
12113
|
if (match) {
|
@@ -12201,7 +12356,7 @@ Ember.computed.intersect = function () {
|
|
12201
12356
|
*/
|
12202
12357
|
Ember.computed.setDiff = function (setAProperty, setBProperty) {
|
12203
12358
|
if (arguments.length !== 2) {
|
12204
|
-
throw new Error("setDiff requires exactly two dependent arrays.");
|
12359
|
+
throw new Ember.Error("setDiff requires exactly two dependent arrays.");
|
12205
12360
|
}
|
12206
12361
|
return Ember.arrayComputed.call(null, setAProperty, setBProperty, {
|
12207
12362
|
addedItem: function (array, item, changeMeta, instanceMeta) {
|
@@ -12316,7 +12471,7 @@ function binarySearch(array, item, low, high) {
|
|
12316
12471
|
]});
|
12317
12472
|
|
12318
12473
|
todoList.get('sortedTodos'); // [{name:'Documentation', priority:3}, {name:'Release', priority:1}, {name:'Unit Test', priority:2}]
|
12319
|
-
todoList.get('
|
12474
|
+
todoList.get('priorityTodos'); // [{name:'Release', priority:1}, {name:'Unit Test', priority:2}, {name:'Documentation', priority:3}]
|
12320
12475
|
```
|
12321
12476
|
|
12322
12477
|
@method computed.sort
|
@@ -12457,7 +12612,7 @@ Ember.RSVP = requireModule('rsvp');
|
|
12457
12612
|
|
12458
12613
|
var STRING_DASHERIZE_REGEXP = (/[ _]/g);
|
12459
12614
|
var STRING_DASHERIZE_CACHE = {};
|
12460
|
-
var STRING_DECAMELIZE_REGEXP = (/([a-z])([A-Z])/g);
|
12615
|
+
var STRING_DECAMELIZE_REGEXP = (/([a-z\d])([A-Z])/g);
|
12461
12616
|
var STRING_CAMELIZE_REGEXP = (/(\-|_|\.|\s)+(.)?/g);
|
12462
12617
|
var STRING_UNDERSCORE_REGEXP_1 = (/([a-z\d])([A-Z]+)/g);
|
12463
12618
|
var STRING_UNDERSCORE_REGEXP_2 = (/\-|\s+/g);
|
@@ -13124,7 +13279,7 @@ Ember.Copyable = Ember.Mixin.create(/** @scope Ember.Copyable.prototype */ {
|
|
13124
13279
|
if (Ember.Freezable && Ember.Freezable.detect(this)) {
|
13125
13280
|
return get(this, 'isFrozen') ? this : this.copy().freeze();
|
13126
13281
|
} else {
|
13127
|
-
throw new Error(Ember.String.fmt("%@ does not support freezing", [this]));
|
13282
|
+
throw new Ember.Error(Ember.String.fmt("%@ does not support freezing", [this]));
|
13128
13283
|
}
|
13129
13284
|
}
|
13130
13285
|
});
|
@@ -13433,7 +13588,7 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,/**
|
|
13433
13588
|
@return this
|
13434
13589
|
*/
|
13435
13590
|
insertAt: function(idx, object) {
|
13436
|
-
if (idx > get(this, 'length')) throw new Error(OUT_OF_RANGE_EXCEPTION) ;
|
13591
|
+
if (idx > get(this, 'length')) throw new Ember.Error(OUT_OF_RANGE_EXCEPTION) ;
|
13437
13592
|
this.replace(idx, 0, [object]) ;
|
13438
13593
|
return this ;
|
13439
13594
|
},
|
@@ -13461,7 +13616,7 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,/**
|
|
13461
13616
|
if ('number' === typeof start) {
|
13462
13617
|
|
13463
13618
|
if ((start < 0) || (start >= get(this, 'length'))) {
|
13464
|
-
throw new Error(OUT_OF_RANGE_EXCEPTION);
|
13619
|
+
throw new Ember.Error(OUT_OF_RANGE_EXCEPTION);
|
13465
13620
|
}
|
13466
13621
|
|
13467
13622
|
// fast case
|
@@ -14274,18 +14429,29 @@ Ember.TargetActionSupport = Ember.Mixin.create({
|
|
14274
14429
|
*/
|
14275
14430
|
triggerAction: function(opts) {
|
14276
14431
|
opts = opts || {};
|
14277
|
-
var action = opts
|
14278
|
-
target = opts
|
14279
|
-
actionContext = opts
|
14432
|
+
var action = opts.action || get(this, 'action'),
|
14433
|
+
target = opts.target || get(this, 'targetObject'),
|
14434
|
+
actionContext = opts.actionContext;
|
14435
|
+
|
14436
|
+
function args(options, actionName) {
|
14437
|
+
var ret = [];
|
14438
|
+
if (actionName) { ret.push(actionName); }
|
14439
|
+
|
14440
|
+
return ret.concat(options);
|
14441
|
+
}
|
14442
|
+
|
14443
|
+
if (typeof actionContext === 'undefined') {
|
14444
|
+
actionContext = get(this, 'actionContextObject') || this;
|
14445
|
+
}
|
14280
14446
|
|
14281
14447
|
if (target && action) {
|
14282
14448
|
var ret;
|
14283
14449
|
|
14284
14450
|
if (target.send) {
|
14285
|
-
ret = target.send.apply(target,
|
14451
|
+
ret = target.send.apply(target, args(actionContext, action));
|
14286
14452
|
} else {
|
14287
14453
|
Ember.assert("The action '" + action + "' did not exist on " + target, typeof target[action] === 'function');
|
14288
|
-
ret = target[action].apply(target,
|
14454
|
+
ret = target[action].apply(target, args(actionContext));
|
14289
14455
|
}
|
14290
14456
|
|
14291
14457
|
if (ret !== false) ret = true;
|
@@ -14676,6 +14842,7 @@ function installPromise(proxy, promise) {
|
|
14676
14842
|
|
14677
14843
|
If the controller is backing a template, the attributes are
|
14678
14844
|
bindable from within that template
|
14845
|
+
|
14679
14846
|
```handlebars
|
14680
14847
|
{{#if isPending}}
|
14681
14848
|
loading...
|
@@ -14699,7 +14866,7 @@ Ember.PromiseProxyMixin = Ember.Mixin.create({
|
|
14699
14866
|
installPromise(this, promise);
|
14700
14867
|
return promise;
|
14701
14868
|
} else {
|
14702
|
-
throw new Error("PromiseProxy's promise must be set");
|
14869
|
+
throw new Ember.Error("PromiseProxy's promise must be set");
|
14703
14870
|
}
|
14704
14871
|
}),
|
14705
14872
|
|
@@ -14742,9 +14909,9 @@ Ember.TrackedArray = function (items) {
|
|
14742
14909
|
var length = get(items, 'length');
|
14743
14910
|
|
14744
14911
|
if (length) {
|
14745
|
-
this.
|
14912
|
+
this._operations = [new ArrayOperation(RETAIN, length, items)];
|
14746
14913
|
} else {
|
14747
|
-
this.
|
14914
|
+
this._operations = [];
|
14748
14915
|
}
|
14749
14916
|
};
|
14750
14917
|
|
@@ -14762,8 +14929,10 @@ Ember.TrackedArray.prototype = {
|
|
14762
14929
|
@param newItems
|
14763
14930
|
*/
|
14764
14931
|
addItems: function (index, newItems) {
|
14765
|
-
var count = get(newItems, 'length')
|
14766
|
-
|
14932
|
+
var count = get(newItems, 'length');
|
14933
|
+
if (count < 1) { return; }
|
14934
|
+
|
14935
|
+
var match = this._findArrayOperation(index),
|
14767
14936
|
arrayOperation = match.operation,
|
14768
14937
|
arrayOperationIndex = match.index,
|
14769
14938
|
arrayOperationRangeStart = match.rangeStart,
|
@@ -14778,7 +14947,7 @@ Ember.TrackedArray.prototype = {
|
|
14778
14947
|
if (arrayOperation) {
|
14779
14948
|
if (!match.split) {
|
14780
14949
|
// insert left of arrayOperation
|
14781
|
-
this.
|
14950
|
+
this._operations.splice(arrayOperationIndex, 0, newArrayOperation);
|
14782
14951
|
composeIndex = arrayOperationIndex;
|
14783
14952
|
} else {
|
14784
14953
|
this._split(arrayOperationIndex, index - arrayOperationRangeStart, newArrayOperation);
|
@@ -14786,7 +14955,7 @@ Ember.TrackedArray.prototype = {
|
|
14786
14955
|
}
|
14787
14956
|
} else {
|
14788
14957
|
// insert at end
|
14789
|
-
this.
|
14958
|
+
this._operations.push(newArrayOperation);
|
14790
14959
|
composeIndex = arrayOperationIndex;
|
14791
14960
|
}
|
14792
14961
|
|
@@ -14801,6 +14970,8 @@ Ember.TrackedArray.prototype = {
|
|
14801
14970
|
@param count
|
14802
14971
|
*/
|
14803
14972
|
removeItems: function (index, count) {
|
14973
|
+
if (count < 1) { return; }
|
14974
|
+
|
14804
14975
|
var match = this._findArrayOperation(index),
|
14805
14976
|
arrayOperation = match.operation,
|
14806
14977
|
arrayOperationIndex = match.index,
|
@@ -14811,7 +14982,7 @@ Ember.TrackedArray.prototype = {
|
|
14811
14982
|
newArrayOperation = new ArrayOperation(DELETE, count);
|
14812
14983
|
if (!match.split) {
|
14813
14984
|
// insert left of arrayOperation
|
14814
|
-
this.
|
14985
|
+
this._operations.splice(arrayOperationIndex, 0, newArrayOperation);
|
14815
14986
|
composeIndex = arrayOperationIndex;
|
14816
14987
|
} else {
|
14817
14988
|
this._split(arrayOperationIndex, index - arrayOperationRangeStart, newArrayOperation);
|
@@ -14826,30 +14997,29 @@ Ember.TrackedArray.prototype = {
|
|
14826
14997
|
items in the array.
|
14827
14998
|
|
14828
14999
|
`callback` will be called for each operation and will be passed the following arguments:
|
14829
|
-
|
14830
|
-
|
14831
|
-
|
14832
|
-
|
14833
|
-
|
15000
|
+
* {array} items The items for the given operation
|
15001
|
+
* {number} offset The computed offset of the items, ie the index in the
|
15002
|
+
array of the first item for this operation.
|
15003
|
+
* {string} operation The type of the operation. One of
|
15004
|
+
`Ember.TrackedArray.{RETAIN, DELETE, INSERT}`
|
14834
15005
|
|
14835
15006
|
@method apply
|
14836
|
-
|
14837
15007
|
@param {function} callback
|
14838
15008
|
*/
|
14839
15009
|
apply: function (callback) {
|
14840
15010
|
var items = [],
|
14841
15011
|
offset = 0;
|
14842
15012
|
|
14843
|
-
forEach(this.
|
14844
|
-
callback(arrayOperation.items, offset, arrayOperation.
|
15013
|
+
forEach(this._operations, function (arrayOperation) {
|
15014
|
+
callback(arrayOperation.items, offset, arrayOperation.type);
|
14845
15015
|
|
14846
|
-
if (arrayOperation.
|
15016
|
+
if (arrayOperation.type !== DELETE) {
|
14847
15017
|
offset += arrayOperation.count;
|
14848
15018
|
items = items.concat(arrayOperation.items);
|
14849
15019
|
}
|
14850
15020
|
});
|
14851
15021
|
|
14852
|
-
this.
|
15022
|
+
this._operations = [new ArrayOperation(RETAIN, items.length, items)];
|
14853
15023
|
},
|
14854
15024
|
|
14855
15025
|
/**
|
@@ -14871,10 +15041,10 @@ Ember.TrackedArray.prototype = {
|
|
14871
15041
|
|
14872
15042
|
// OPTIMIZE: we could search these faster if we kept a balanced tree.
|
14873
15043
|
// find leftmost arrayOperation to the right of `index`
|
14874
|
-
for (arrayOperationIndex = arrayOperationRangeStart = 0, len = this.
|
14875
|
-
arrayOperation = this.
|
15044
|
+
for (arrayOperationIndex = arrayOperationRangeStart = 0, len = this._operations.length; arrayOperationIndex < len; ++arrayOperationIndex) {
|
15045
|
+
arrayOperation = this._operations[arrayOperationIndex];
|
14876
15046
|
|
14877
|
-
if (arrayOperation.
|
15047
|
+
if (arrayOperation.type === DELETE) { continue; }
|
14878
15048
|
|
14879
15049
|
arrayOperationRangeEnd = arrayOperationRangeStart + arrayOperation.count - 1;
|
14880
15050
|
|
@@ -14892,25 +15062,24 @@ Ember.TrackedArray.prototype = {
|
|
14892
15062
|
},
|
14893
15063
|
|
14894
15064
|
_split: function (arrayOperationIndex, splitIndex, newArrayOperation) {
|
14895
|
-
var arrayOperation = this.
|
15065
|
+
var arrayOperation = this._operations[arrayOperationIndex],
|
14896
15066
|
splitItems = arrayOperation.items.slice(splitIndex),
|
14897
|
-
splitArrayOperation = new ArrayOperation(arrayOperation.
|
15067
|
+
splitArrayOperation = new ArrayOperation(arrayOperation.type, splitItems.length, splitItems);
|
14898
15068
|
|
14899
15069
|
// truncate LHS
|
14900
15070
|
arrayOperation.count = splitIndex;
|
14901
15071
|
arrayOperation.items = arrayOperation.items.slice(0, splitIndex);
|
14902
15072
|
|
14903
|
-
this.
|
15073
|
+
this._operations.splice(arrayOperationIndex + 1, 0, newArrayOperation, splitArrayOperation);
|
14904
15074
|
},
|
14905
15075
|
|
14906
|
-
// TODO: unify _composeInsert, _composeDelete
|
14907
15076
|
// see SubArray for a better implementation.
|
14908
15077
|
_composeInsert: function (index) {
|
14909
|
-
var newArrayOperation = this.
|
14910
|
-
leftArrayOperation = this.
|
14911
|
-
rightArrayOperation = this.
|
14912
|
-
leftOp = leftArrayOperation && leftArrayOperation.
|
14913
|
-
rightOp = rightArrayOperation && rightArrayOperation.
|
15078
|
+
var newArrayOperation = this._operations[index],
|
15079
|
+
leftArrayOperation = this._operations[index-1], // may be undefined
|
15080
|
+
rightArrayOperation = this._operations[index+1], // may be undefined
|
15081
|
+
leftOp = leftArrayOperation && leftArrayOperation.type,
|
15082
|
+
rightOp = rightArrayOperation && rightArrayOperation.type;
|
14914
15083
|
|
14915
15084
|
if (leftOp === INSERT) {
|
14916
15085
|
// merge left
|
@@ -14918,30 +15087,31 @@ Ember.TrackedArray.prototype = {
|
|
14918
15087
|
leftArrayOperation.items = leftArrayOperation.items.concat(newArrayOperation.items);
|
14919
15088
|
|
14920
15089
|
if (rightOp === INSERT) {
|
14921
|
-
// also merge right
|
15090
|
+
// also merge right (we have split an insert with an insert)
|
14922
15091
|
leftArrayOperation.count += rightArrayOperation.count;
|
14923
15092
|
leftArrayOperation.items = leftArrayOperation.items.concat(rightArrayOperation.items);
|
14924
|
-
this.
|
15093
|
+
this._operations.splice(index, 2);
|
14925
15094
|
} else {
|
14926
15095
|
// only merge left
|
14927
|
-
this.
|
15096
|
+
this._operations.splice(index, 1);
|
14928
15097
|
}
|
14929
15098
|
} else if (rightOp === INSERT) {
|
14930
15099
|
// merge right
|
14931
15100
|
newArrayOperation.count += rightArrayOperation.count;
|
14932
15101
|
newArrayOperation.items = newArrayOperation.items.concat(rightArrayOperation.items);
|
14933
|
-
this.
|
15102
|
+
this._operations.splice(index + 1, 1);
|
14934
15103
|
}
|
14935
15104
|
},
|
14936
15105
|
|
14937
15106
|
_composeDelete: function (index) {
|
14938
|
-
var arrayOperation = this.
|
15107
|
+
var arrayOperation = this._operations[index],
|
14939
15108
|
deletesToGo = arrayOperation.count,
|
14940
|
-
leftArrayOperation = this.
|
14941
|
-
leftOp = leftArrayOperation && leftArrayOperation.
|
15109
|
+
leftArrayOperation = this._operations[index-1], // may be undefined
|
15110
|
+
leftOp = leftArrayOperation && leftArrayOperation.type,
|
14942
15111
|
nextArrayOperation,
|
14943
15112
|
nextOp,
|
14944
15113
|
nextCount,
|
15114
|
+
removeNewAndNextOp = false,
|
14945
15115
|
removedItems = [];
|
14946
15116
|
|
14947
15117
|
if (leftOp === DELETE) {
|
@@ -14950,8 +15120,8 @@ Ember.TrackedArray.prototype = {
|
|
14950
15120
|
}
|
14951
15121
|
|
14952
15122
|
for (var i = index + 1; deletesToGo > 0; ++i) {
|
14953
|
-
nextArrayOperation = this.
|
14954
|
-
nextOp = nextArrayOperation.
|
15123
|
+
nextArrayOperation = this._operations[i];
|
15124
|
+
nextOp = nextArrayOperation.type;
|
14955
15125
|
nextCount = nextArrayOperation.count;
|
14956
15126
|
|
14957
15127
|
if (nextOp === DELETE) {
|
@@ -14960,6 +15130,7 @@ Ember.TrackedArray.prototype = {
|
|
14960
15130
|
}
|
14961
15131
|
|
14962
15132
|
if (nextCount > deletesToGo) {
|
15133
|
+
// d:2 {r,i}:5 we reduce the retain or insert, but it stays
|
14963
15134
|
removedItems = removedItems.concat(nextArrayOperation.items.splice(0, deletesToGo));
|
14964
15135
|
nextArrayOperation.count -= deletesToGo;
|
14965
15136
|
|
@@ -14971,29 +15142,57 @@ Ember.TrackedArray.prototype = {
|
|
14971
15142
|
|
14972
15143
|
deletesToGo = 0;
|
14973
15144
|
} else {
|
15145
|
+
if (nextCount === deletesToGo) {
|
15146
|
+
// Handle edge case of d:2 i:2 in which case both operations go away
|
15147
|
+
// during composition.
|
15148
|
+
removeNewAndNextOp = true;
|
15149
|
+
}
|
14974
15150
|
removedItems = removedItems.concat(nextArrayOperation.items);
|
14975
15151
|
deletesToGo -= nextCount;
|
14976
15152
|
}
|
14977
15153
|
|
14978
15154
|
if (nextOp === INSERT) {
|
15155
|
+
// d:2 i:3 will result in delete going away
|
14979
15156
|
arrayOperation.count -= nextCount;
|
14980
15157
|
}
|
14981
15158
|
}
|
14982
15159
|
|
14983
15160
|
if (arrayOperation.count > 0) {
|
14984
|
-
|
15161
|
+
// compose our new delete with possibly several operations to the right of
|
15162
|
+
// disparate types
|
15163
|
+
this._operations.splice(index+1, i-1-index);
|
14985
15164
|
} else {
|
14986
15165
|
// The delete operation can go away; it has merely reduced some other
|
14987
|
-
// operation, as in
|
14988
|
-
|
15166
|
+
// operation, as in d:3 i:4; it may also have eliminated that operation,
|
15167
|
+
// as in d:3 i:3.
|
15168
|
+
this._operations.splice(index, removeNewAndNextOp ? 2 : 1);
|
14989
15169
|
}
|
14990
15170
|
|
14991
15171
|
return removedItems;
|
15172
|
+
},
|
15173
|
+
|
15174
|
+
toString: function () {
|
15175
|
+
var str = "";
|
15176
|
+
forEach(this._operations, function (operation) {
|
15177
|
+
str += " " + operation.type + ":" + operation.count;
|
15178
|
+
});
|
15179
|
+
return str.substring(1);
|
14992
15180
|
}
|
14993
15181
|
};
|
14994
15182
|
|
15183
|
+
/**
|
15184
|
+
Internal data structure to represent an array operation.
|
15185
|
+
|
15186
|
+
@method ArrayOperation
|
15187
|
+
@private
|
15188
|
+
@property {string} type The type of the operation. One of
|
15189
|
+
`Ember.TrackedArray.{RETAIN, INSERT, DELETE}`
|
15190
|
+
@property {number} count The number of items in this operation.
|
15191
|
+
@property {array} items The items of the operation, if included. RETAIN and
|
15192
|
+
INSERT include their items, DELETE does not.
|
15193
|
+
*/
|
14995
15194
|
function ArrayOperation (operation, count, items) {
|
14996
|
-
this.
|
15195
|
+
this.type = operation; // RETAIN | INSERT | DELETE
|
14997
15196
|
this.count = count;
|
14998
15197
|
this.items = items;
|
14999
15198
|
}
|
@@ -15061,7 +15260,7 @@ Ember.SubArray.prototype = {
|
|
15061
15260
|
@param {number} index The index of the item in the tracked array.
|
15062
15261
|
@param {boolean} match `true` iff the item is included in the subarray.
|
15063
15262
|
|
15064
|
-
@
|
15263
|
+
@return {number} The index of the item in the subarray.
|
15065
15264
|
*/
|
15066
15265
|
addItem: function(index, match) {
|
15067
15266
|
var returnValue = -1,
|
@@ -15113,7 +15312,7 @@ Ember.SubArray.prototype = {
|
|
15113
15312
|
|
15114
15313
|
@param {number} index The index of the item in the tracked array.
|
15115
15314
|
|
15116
|
-
@
|
15315
|
+
@return {number} The index of the item in the subarray, or `-1` if the item
|
15117
15316
|
was not in the subarray.
|
15118
15317
|
*/
|
15119
15318
|
removeItem: function(index) {
|
@@ -15131,6 +15330,8 @@ Ember.SubArray.prototype = {
|
|
15131
15330
|
self._operations.splice(operationIndex, 1);
|
15132
15331
|
self._composeAt(operationIndex);
|
15133
15332
|
}
|
15333
|
+
}, function() {
|
15334
|
+
throw new Ember.Error("Can't remove an item that has never been added.");
|
15134
15335
|
});
|
15135
15336
|
|
15136
15337
|
return returnValue;
|
@@ -15177,6 +15378,7 @@ Ember.SubArray.prototype = {
|
|
15177
15378
|
if (otherOp.type === op.type) {
|
15178
15379
|
op.count += otherOp.count;
|
15179
15380
|
this._operations.splice(index-1, 1);
|
15381
|
+
--index;
|
15180
15382
|
}
|
15181
15383
|
}
|
15182
15384
|
|
@@ -15273,7 +15475,11 @@ function makeCtor() {
|
|
15273
15475
|
|
15274
15476
|
Ember.assert("Ember.Object.create no longer supports mixing in other definitions, use createWithMixins instead.", !(properties instanceof Ember.Mixin));
|
15275
15477
|
|
15276
|
-
|
15478
|
+
if (Ember.typeOf(properties) !== 'object') { continue; }
|
15479
|
+
|
15480
|
+
var keyNames = Ember.keys(properties);
|
15481
|
+
for (var j = 0, ll = keyNames.length; j < ll; j++) {
|
15482
|
+
var keyName = keyNames[j];
|
15277
15483
|
if (!properties.hasOwnProperty(keyName)) { continue; }
|
15278
15484
|
|
15279
15485
|
var value = properties[keyName],
|
@@ -15459,7 +15665,10 @@ CoreObject.PrototypeMixin = Mixin.create({
|
|
15459
15665
|
are also concatenated, in addition to `classNames`.
|
15460
15666
|
|
15461
15667
|
This feature is available for you to use throughout the Ember object model,
|
15462
|
-
although typical app developers are likely to use it infrequently.
|
15668
|
+
although typical app developers are likely to use it infrequently. Since
|
15669
|
+
it changes expectations about behavior of properties, you should properly
|
15670
|
+
document its usage in each individual concatenated property (to not
|
15671
|
+
mislead your users to think they can override the property in a subclass).
|
15463
15672
|
|
15464
15673
|
@property concatenatedProperties
|
15465
15674
|
@type Array
|
@@ -15599,6 +15808,86 @@ var ClassMixin = Mixin.create({
|
|
15599
15808
|
|
15600
15809
|
isMethod: false,
|
15601
15810
|
|
15811
|
+
/**
|
15812
|
+
Creates a new subclass.
|
15813
|
+
|
15814
|
+
```javascript
|
15815
|
+
App.Person = Ember.Object.extend({
|
15816
|
+
say: function(thing) {
|
15817
|
+
alert(thing);
|
15818
|
+
}
|
15819
|
+
});
|
15820
|
+
```
|
15821
|
+
|
15822
|
+
This defines a new subclass of Ember.Object: `App.Person`. It contains one method: `say()`.
|
15823
|
+
|
15824
|
+
You can also create a subclass from any existing class by calling its `extend()` method. For example, you might want to create a subclass of Ember's built-in `Ember.View` class:
|
15825
|
+
|
15826
|
+
```javascript
|
15827
|
+
App.PersonView = Ember.View.extend({
|
15828
|
+
tagName: 'li',
|
15829
|
+
classNameBindings: ['isAdministrator']
|
15830
|
+
});
|
15831
|
+
```
|
15832
|
+
|
15833
|
+
When defining a subclass, you can override methods but still access the implementation of your parent class by calling the special `_super()` method:
|
15834
|
+
|
15835
|
+
```javascript
|
15836
|
+
App.Person = Ember.Object.extend({
|
15837
|
+
say: function(thing) {
|
15838
|
+
var name = this.get('name');
|
15839
|
+
alert(name + ' says: ' + thing);
|
15840
|
+
}
|
15841
|
+
});
|
15842
|
+
|
15843
|
+
App.Soldier = App.Person.extend({
|
15844
|
+
say: function(thing) {
|
15845
|
+
this._super(thing + ", sir!");
|
15846
|
+
},
|
15847
|
+
march: function(numberOfHours) {
|
15848
|
+
alert(this.get('name') + ' marches for ' + numberOfHours + ' hours.')
|
15849
|
+
}
|
15850
|
+
});
|
15851
|
+
|
15852
|
+
var yehuda = App.Soldier.create({
|
15853
|
+
name: "Yehuda Katz"
|
15854
|
+
});
|
15855
|
+
|
15856
|
+
yehuda.say("Yes"); // alerts "Yehuda Katz says: Yes, sir!"
|
15857
|
+
```
|
15858
|
+
|
15859
|
+
The `create()` on line #17 creates an *instance* of the `App.Soldier` class. The `extend()` on line #8 creates a *subclass* of `App.Person`. Any instance of the `App.Person` class will *not* have the `march()` method.
|
15860
|
+
|
15861
|
+
You can also pass `Ember.Mixin` classes to add additional properties to the subclass.
|
15862
|
+
|
15863
|
+
```javascript
|
15864
|
+
App.Person = Ember.Object.extend({
|
15865
|
+
say: function(thing) {
|
15866
|
+
alert(this.get('name') + ' says: ' + thing);
|
15867
|
+
}
|
15868
|
+
});
|
15869
|
+
|
15870
|
+
App.SingingMixin = Ember.Mixin.create({
|
15871
|
+
sing: function(thing){
|
15872
|
+
alert(this.get('name') + ' sings: la la la ' + thing);
|
15873
|
+
}
|
15874
|
+
});
|
15875
|
+
|
15876
|
+
App.BroadwayStar = App.Person.extend(App.SingingMixin, {
|
15877
|
+
dance: function() {
|
15878
|
+
alert(this.get('name') + ' dances: tap tap tap tap ');
|
15879
|
+
}
|
15880
|
+
});
|
15881
|
+
```
|
15882
|
+
|
15883
|
+
The `App.BroadwayStar` class contains three methods: `say()`, `sing()`, and `dance()`.
|
15884
|
+
|
15885
|
+
@method extend
|
15886
|
+
@static
|
15887
|
+
|
15888
|
+
@param {Ember.Mixin} [mixins]* One or more Ember.Mixin classes
|
15889
|
+
@param {Object} [arguments]* Object containing values to use within the new class
|
15890
|
+
*/
|
15602
15891
|
extend: function() {
|
15603
15892
|
var Class = makeCtor(), proto;
|
15604
15893
|
Class.ClassMixin = Mixin.create(this.ClassMixin);
|
@@ -15730,6 +16019,39 @@ var ClassMixin = Mixin.create({
|
|
15730
16019
|
MyObject.canBuild; // false
|
15731
16020
|
o = MyObject.create();
|
15732
16021
|
```
|
16022
|
+
|
16023
|
+
In other words, this creates static properties and functions for the class. These are only available on the class
|
16024
|
+
and not on any instance of that class.
|
16025
|
+
|
16026
|
+
```javascript
|
16027
|
+
App.Person = Ember.Object.extend({
|
16028
|
+
name : "",
|
16029
|
+
sayHello : function(){
|
16030
|
+
alert("Hello. My name is " + this.get('name'));
|
16031
|
+
}
|
16032
|
+
});
|
16033
|
+
|
16034
|
+
App.Person.reopenClass({
|
16035
|
+
species : "Homo sapiens",
|
16036
|
+
createPerson: function(newPersonsName){
|
16037
|
+
return App.Person.create({
|
16038
|
+
name:newPersonsName
|
16039
|
+
});
|
16040
|
+
}
|
16041
|
+
});
|
16042
|
+
|
16043
|
+
var tom = App.Person.create({
|
16044
|
+
name : "Tom Dale"
|
16045
|
+
});
|
16046
|
+
var yehuda = App.Person.createPerson("Yehuda Katz");
|
16047
|
+
|
16048
|
+
tom.sayHello(); // "Hello. My name is Tom Dale"
|
16049
|
+
yehuda.sayHello(); // "Hello. My name is Yehuda Katz"
|
16050
|
+
alert(App.Person.species); // "Homo sapiens"
|
16051
|
+
```
|
16052
|
+
|
16053
|
+
Note that `species` and `createPerson` are *not* valid on the `tom` and `yehuda`
|
16054
|
+
variables. They are only valid on `App.Person`.
|
15733
16055
|
|
15734
16056
|
To add functions and properties to instances of
|
15735
16057
|
a constructor by extending the constructor's prototype
|
@@ -16295,7 +16617,7 @@ Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,/** @scope Ember.Array
|
|
16295
16617
|
},
|
16296
16618
|
|
16297
16619
|
_insertAt: function(idx, object) {
|
16298
|
-
if (idx > get(this, 'content.length')) throw new Error(OUT_OF_RANGE_EXCEPTION);
|
16620
|
+
if (idx > get(this, 'content.length')) throw new Ember.Error(OUT_OF_RANGE_EXCEPTION);
|
16299
16621
|
this._replace(idx, 0, [object]);
|
16300
16622
|
return this;
|
16301
16623
|
},
|
@@ -16315,7 +16637,7 @@ Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,/** @scope Ember.Array
|
|
16315
16637
|
indices = [], i;
|
16316
16638
|
|
16317
16639
|
if ((start < 0) || (start >= get(this, 'length'))) {
|
16318
|
-
throw new Error(OUT_OF_RANGE_EXCEPTION);
|
16640
|
+
throw new Ember.Error(OUT_OF_RANGE_EXCEPTION);
|
16319
16641
|
}
|
16320
16642
|
|
16321
16643
|
if (len === undefined) len = 1;
|
@@ -17082,7 +17404,7 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
|
|
17082
17404
|
@return {Ember.Set} An empty Set
|
17083
17405
|
*/
|
17084
17406
|
clear: function() {
|
17085
|
-
if (this.isFrozen) { throw new Error(Ember.FROZEN_ERROR); }
|
17407
|
+
if (this.isFrozen) { throw new Ember.Error(Ember.FROZEN_ERROR); }
|
17086
17408
|
|
17087
17409
|
var len = get(this, 'length');
|
17088
17410
|
if (len === 0) { return this; }
|
@@ -17192,7 +17514,7 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
|
|
17192
17514
|
@return {Object} The removed object from the set or null.
|
17193
17515
|
*/
|
17194
17516
|
pop: function() {
|
17195
|
-
if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
|
17517
|
+
if (get(this, 'isFrozen')) throw new Ember.Error(Ember.FROZEN_ERROR);
|
17196
17518
|
var obj = this.length > 0 ? this[this.length-1] : null;
|
17197
17519
|
this.remove(obj);
|
17198
17520
|
return obj;
|
@@ -17309,7 +17631,7 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
|
|
17309
17631
|
|
17310
17632
|
// implements Ember.MutableEnumerable
|
17311
17633
|
addObject: function(obj) {
|
17312
|
-
if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
|
17634
|
+
if (get(this, 'isFrozen')) throw new Ember.Error(Ember.FROZEN_ERROR);
|
17313
17635
|
if (isNone(obj)) return this; // nothing to do
|
17314
17636
|
|
17315
17637
|
var guid = guidFor(obj),
|
@@ -17337,7 +17659,7 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
|
|
17337
17659
|
|
17338
17660
|
// implements Ember.MutableEnumerable
|
17339
17661
|
removeObject: function(obj) {
|
17340
|
-
if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
|
17662
|
+
if (get(this, 'isFrozen')) throw new Ember.Error(Ember.FROZEN_ERROR);
|
17341
17663
|
if (isNone(obj)) return this; // nothing to do
|
17342
17664
|
|
17343
17665
|
var guid = guidFor(obj),
|
@@ -18044,7 +18366,7 @@ Ember.ArrayController = Ember.ArrayProxy.extend(Ember.ControllerMixin,
|
|
18044
18366
|
fullName = "controller:" + controllerClass;
|
18045
18367
|
|
18046
18368
|
if (!container.has(fullName)) {
|
18047
|
-
throw new Error('Could not resolve itemController: "' + controllerClass + '"');
|
18369
|
+
throw new Ember.Error('Could not resolve itemController: "' + controllerClass + '"');
|
18048
18370
|
}
|
18049
18371
|
|
18050
18372
|
subController = container.lookupFactory(fullName).create({
|