ember-source 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ember-source might be problematic. Click here for more details.
- checksums.yaml +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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0bc2c7cb4059e5e50c11dd2420c1a9d43690cdb3
|
4
|
+
data.tar.gz: 9bed191399ac71386e4ededfeb8f3282ecdc539f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a6292985ff546607a84a2c83a8cec1baf39d7542c987ce7e2b852e161a2ed8484c2177fc48b0eb01baa3ebfebddc2349359b286e5ef6d7aa87933de2180032a
|
7
|
+
data.tar.gz: 672a9bc242fcbd5f9cd0088156c90d40d8d20418bc832eb97ffd9ec4edd301f93c2170b7e0d3bc05fa1456eb6fe4a0bdc725822fd9011bba2d0b7ec87a7268ca
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0
|
1
|
+
1.1.0
|
data/dist/ember-data-deps.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({
|