ember-source 1.0.0.rc1.2 → 1.0.0.rc1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ember-source might be problematic. Click here for more details.
- data/dist/ember-data-deps.js +1533 -1294
- data/dist/ember-data-deps.min.js +5 -5
- data/dist/ember-data-deps.prod.js +1520 -1281
- data/dist/ember-debug.js +2 -2
- data/dist/ember-old-router.js +1822 -3695
- data/dist/ember-old-router.min.js +8 -9
- data/dist/ember-old-router.prod.js +1817 -3690
- data/dist/ember-runtime.js +1532 -1293
- data/dist/ember-runtime.min.js +5 -5
- data/dist/ember-runtime.prod.js +1517 -1278
- data/dist/ember-spade.js +1 -1
- data/dist/ember-template-compiler.js +3 -3
- data/dist/ember-template-compiler.min.js +2 -2
- data/dist/ember-template-compiler.prod.js +1 -1
- data/dist/ember-tests.js +1 -1
- data/dist/ember.js +2855 -4662
- data/dist/ember.min.js +8 -9
- data/dist/ember.prod.js +2843 -4649
- metadata +2 -2
data/dist/ember-data-deps.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
// Version: v1.0.0-
|
2
|
-
// Last commit:
|
1
|
+
// Version: v1.0.0-rc.1-188-gb6bb967
|
2
|
+
// Last commit: b6bb967 (2013-03-16 18:09:42 -0700)
|
3
3
|
|
4
4
|
|
5
5
|
(function() {
|
@@ -150,8 +150,8 @@ Ember.deprecateFunc = function(message, func) {
|
|
150
150
|
|
151
151
|
})();
|
152
152
|
|
153
|
-
// Version: v1.0.0-
|
154
|
-
// Last commit:
|
153
|
+
// Version: v1.0.0-rc.1-188-gb6bb967
|
154
|
+
// Last commit: b6bb967 (2013-03-16 18:09:42 -0700)
|
155
155
|
|
156
156
|
|
157
157
|
(function() {
|
@@ -297,6 +297,15 @@ Ember.LOG_STACKTRACE_ON_DEPRECATION = (Ember.ENV.LOG_STACKTRACE_ON_DEPRECATION !
|
|
297
297
|
*/
|
298
298
|
Ember.SHIM_ES5 = (Ember.ENV.SHIM_ES5 === false) ? false : Ember.EXTEND_PROTOTYPES;
|
299
299
|
|
300
|
+
/**
|
301
|
+
Determines whether Ember logs info about version of used libraries
|
302
|
+
|
303
|
+
@property LOG_VERSION
|
304
|
+
@type Boolean
|
305
|
+
@default true
|
306
|
+
*/
|
307
|
+
Ember.LOG_VERSION = (Ember.ENV.LOG_VERSION === false) ? false : true;
|
308
|
+
|
300
309
|
/**
|
301
310
|
Empty function. Useful for some operations.
|
302
311
|
|
@@ -409,6 +418,58 @@ Ember.merge = function(original, updates) {
|
|
409
418
|
}
|
410
419
|
};
|
411
420
|
|
421
|
+
/**
|
422
|
+
Returns true if the passed value is null or undefined. This avoids errors
|
423
|
+
from JSLint complaining about use of ==, which can be technically
|
424
|
+
confusing.
|
425
|
+
|
426
|
+
```javascript
|
427
|
+
Ember.isNone(); // true
|
428
|
+
Ember.isNone(null); // true
|
429
|
+
Ember.isNone(undefined); // true
|
430
|
+
Ember.isNone(''); // false
|
431
|
+
Ember.isNone([]); // false
|
432
|
+
Ember.isNone(function(){}); // false
|
433
|
+
```
|
434
|
+
|
435
|
+
@method isNone
|
436
|
+
@for Ember
|
437
|
+
@param {Object} obj Value to test
|
438
|
+
@return {Boolean}
|
439
|
+
*/
|
440
|
+
Ember.isNone = function(obj) {
|
441
|
+
return obj === null || obj === undefined;
|
442
|
+
};
|
443
|
+
Ember.none = Ember.deprecateFunc("Ember.none is deprecated. Please use Ember.isNone instead.", Ember.isNone);
|
444
|
+
|
445
|
+
/**
|
446
|
+
Verifies that a value is `null` or an empty string, empty array,
|
447
|
+
or empty function.
|
448
|
+
|
449
|
+
Constrains the rules on `Ember.isNone` by returning false for empty
|
450
|
+
string and empty arrays.
|
451
|
+
|
452
|
+
```javascript
|
453
|
+
Ember.isEmpty(); // true
|
454
|
+
Ember.isEmpty(null); // true
|
455
|
+
Ember.isEmpty(undefined); // true
|
456
|
+
Ember.isEmpty(''); // true
|
457
|
+
Ember.isEmpty([]); // true
|
458
|
+
Ember.isEmpty('Adam Hawkins'); // false
|
459
|
+
Ember.isEmpty([0,1,2]); // false
|
460
|
+
```
|
461
|
+
|
462
|
+
@method isEmpty
|
463
|
+
@for Ember
|
464
|
+
@param {Object} obj Value to test
|
465
|
+
@return {Boolean}
|
466
|
+
*/
|
467
|
+
Ember.isEmpty = function(obj) {
|
468
|
+
return obj === null || obj === undefined || (obj.length === 0 && typeof obj !== 'function') || (typeof obj === 'object' && Ember.get(obj, 'length') === 0);
|
469
|
+
};
|
470
|
+
Ember.empty = Ember.deprecateFunc("Ember.empty is deprecated. Please use Ember.isEmpty instead.", Ember.isEmpty) ;
|
471
|
+
|
472
|
+
|
412
473
|
})();
|
413
474
|
|
414
475
|
|
@@ -1752,7 +1813,7 @@ var MapWithDefault = Ember.MapWithDefault = function(options) {
|
|
1752
1813
|
@static
|
1753
1814
|
@param [options]
|
1754
1815
|
@param {anything} [options.defaultValue]
|
1755
|
-
@return {Ember.MapWithDefault|Ember.Map} If options are passed, returns
|
1816
|
+
@return {Ember.MapWithDefault|Ember.Map} If options are passed, returns
|
1756
1817
|
`Ember.MapWithDefault` otherwise returns `Ember.Map`
|
1757
1818
|
*/
|
1758
1819
|
MapWithDefault.create = function(options) {
|
@@ -1815,7 +1876,7 @@ var FIRST_KEY = /^([^\.\*]+)/;
|
|
1815
1876
|
// ..........................................................
|
1816
1877
|
// GET AND SET
|
1817
1878
|
//
|
1818
|
-
// If we are on a platform that supports accessors we can
|
1879
|
+
// If we are on a platform that supports accessors we can use those.
|
1819
1880
|
// Otherwise simulate accessors by looking up the property directly on the
|
1820
1881
|
// object.
|
1821
1882
|
|
@@ -1826,7 +1887,7 @@ var FIRST_KEY = /^([^\.\*]+)/;
|
|
1826
1887
|
|
1827
1888
|
If you plan to run on IE8 and older browsers then you should use this
|
1828
1889
|
method anytime you want to retrieve a property on an object that you don't
|
1829
|
-
know for sure is private. (Properties beginning with an underscore '_'
|
1890
|
+
know for sure is private. (Properties beginning with an underscore '_'
|
1830
1891
|
are considered private.)
|
1831
1892
|
|
1832
1893
|
On all newer browsers, you only need to use this method to retrieve
|
@@ -1888,7 +1949,7 @@ get = function get(obj, keyName) {
|
|
1888
1949
|
|
1889
1950
|
If you plan to run on IE8 and older browsers then you should use this
|
1890
1951
|
method anytime you want to set a property on an object that you don't
|
1891
|
-
know for sure is private. (Properties beginning with an underscore '_'
|
1952
|
+
know for sure is private. (Properties beginning with an underscore '_'
|
1892
1953
|
are considered private.)
|
1893
1954
|
|
1894
1955
|
On all newer browsers, you only need to use this method to set
|
@@ -2119,11 +2180,8 @@ Ember.isGlobalPath = function(path) {
|
|
2119
2180
|
@module ember-metal
|
2120
2181
|
*/
|
2121
2182
|
|
2122
|
-
var
|
2123
|
-
META_KEY = Ember.META_KEY,
|
2124
|
-
EMPTY_META = Ember.EMPTY_META,
|
2183
|
+
var META_KEY = Ember.META_KEY,
|
2125
2184
|
metaFor = Ember.meta,
|
2126
|
-
o_create = Ember.create,
|
2127
2185
|
objectDefineProperty = Ember.platform.defineProperty;
|
2128
2186
|
|
2129
2187
|
var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER;
|
@@ -2543,7 +2601,6 @@ var guidFor = Ember.guidFor, // utils.js
|
|
2543
2601
|
META_KEY = Ember.META_KEY, // utils.js
|
2544
2602
|
// circular reference observer depends on Ember.watch
|
2545
2603
|
// we should move change events to this file or its own property_events.js
|
2546
|
-
notifyObservers = Ember.notifyObservers, // observer.js
|
2547
2604
|
forEach = Ember.ArrayPolyfills.forEach, // array.js
|
2548
2605
|
FIRST_KEY = /^([^\.\*]+)/,
|
2549
2606
|
IS_PATH = /[\.\*]/;
|
@@ -3083,7 +3140,7 @@ Ember.finishChains = function(obj) {
|
|
3083
3140
|
@param {String} keyName The property key (or path) that will change.
|
3084
3141
|
@return {void}
|
3085
3142
|
*/
|
3086
|
-
function propertyWillChange(obj, keyName
|
3143
|
+
function propertyWillChange(obj, keyName) {
|
3087
3144
|
var m = metaFor(obj, false),
|
3088
3145
|
watching = m.watching[keyName] > 0 || keyName === 'length',
|
3089
3146
|
proto = m.proto,
|
@@ -3191,7 +3248,6 @@ Ember.warn("The CP_DEFAULT_CACHEABLE flag has been removed and computed properti
|
|
3191
3248
|
var get = Ember.get,
|
3192
3249
|
set = Ember.set,
|
3193
3250
|
metaFor = Ember.meta,
|
3194
|
-
guidFor = Ember.guidFor,
|
3195
3251
|
a_slice = [].slice,
|
3196
3252
|
o_create = Ember.create,
|
3197
3253
|
META_KEY = Ember.META_KEY,
|
@@ -3227,20 +3283,8 @@ function keysForDep(obj, depsMeta, depKey) {
|
|
3227
3283
|
return keys;
|
3228
3284
|
}
|
3229
3285
|
|
3230
|
-
/* return obj[META_KEY].deps */
|
3231
3286
|
function metaForDeps(obj, meta) {
|
3232
|
-
|
3233
|
-
// If the current object has no dependencies...
|
3234
|
-
if (!deps) {
|
3235
|
-
// initialize the dependencies with a pointer back to
|
3236
|
-
// the current object
|
3237
|
-
deps = meta.deps = {};
|
3238
|
-
} else if (!meta.hasOwnProperty('deps')) {
|
3239
|
-
// otherwise if the dependencies are inherited from the
|
3240
|
-
// object's superclass, clone the deps
|
3241
|
-
deps = meta.deps = o_create(deps);
|
3242
|
-
}
|
3243
|
-
return deps;
|
3287
|
+
return keysForDep(obj, meta, 'deps');
|
3244
3288
|
}
|
3245
3289
|
|
3246
3290
|
function addDependentKeys(desc, obj, keyName, meta) {
|
@@ -3293,8 +3337,10 @@ function removeDependentKeys(desc, obj, keyName, meta) {
|
|
3293
3337
|
*/
|
3294
3338
|
function ComputedProperty(func, opts) {
|
3295
3339
|
this.func = func;
|
3340
|
+
|
3296
3341
|
this._cacheable = (opts && opts.cacheable !== undefined) ? opts.cacheable : true;
|
3297
3342
|
this._dependentKeys = opts && opts.dependentKeys;
|
3343
|
+
this._readOnly = opts && (opts.readOnly !== undefined || !!opts.readOnly);
|
3298
3344
|
}
|
3299
3345
|
|
3300
3346
|
Ember.ComputedProperty = ComputedProperty;
|
@@ -3349,6 +3395,28 @@ ComputedPropertyPrototype.volatile = function() {
|
|
3349
3395
|
return this.cacheable(false);
|
3350
3396
|
};
|
3351
3397
|
|
3398
|
+
/**
|
3399
|
+
Call on a computed property to set it into read-only mode. When in this
|
3400
|
+
mode the computed property will throw an error when set.
|
3401
|
+
|
3402
|
+
```javascript
|
3403
|
+
MyApp.person = Ember.Object.create({
|
3404
|
+
guid: function() {
|
3405
|
+
return 'guid-guid-guid';
|
3406
|
+
}.property().readOnly()
|
3407
|
+
});
|
3408
|
+
|
3409
|
+
MyApp.person.set('guid', 'new-guid'); // will throw an exception
|
3410
|
+
```
|
3411
|
+
|
3412
|
+
@method readOnly
|
3413
|
+
@chainable
|
3414
|
+
*/
|
3415
|
+
ComputedPropertyPrototype.readOnly = function(readOnly) {
|
3416
|
+
this._readOnly = readOnly === undefined || !!readOnly;
|
3417
|
+
return this;
|
3418
|
+
};
|
3419
|
+
|
3352
3420
|
/**
|
3353
3421
|
Sets the dependent keys on this computed property. Pass any number of
|
3354
3422
|
arguments containing key paths that this computed property depends on.
|
@@ -3473,9 +3541,14 @@ ComputedPropertyPrototype.set = function(obj, keyName, value) {
|
|
3473
3541
|
cache = meta.cache,
|
3474
3542
|
cachedValue, ret;
|
3475
3543
|
|
3544
|
+
if (this._readOnly) {
|
3545
|
+
throw new Error('Cannot Set: ' + keyName + ' on: ' + obj.toString() );
|
3546
|
+
}
|
3547
|
+
|
3476
3548
|
this._suspended = obj;
|
3477
3549
|
|
3478
3550
|
try {
|
3551
|
+
|
3479
3552
|
if (cacheable && cache.hasOwnProperty(keyName)) {
|
3480
3553
|
cachedValue = cache[keyName];
|
3481
3554
|
hadCachedValue = true;
|
@@ -3566,6 +3639,10 @@ Ember.computed = function(func) {
|
|
3566
3639
|
func = a_slice.call(arguments, -1)[0];
|
3567
3640
|
}
|
3568
3641
|
|
3642
|
+
if ( typeof func !== "function" ) {
|
3643
|
+
throw new Error("Computed Property declared without a property function");
|
3644
|
+
}
|
3645
|
+
|
3569
3646
|
var cp = new ComputedProperty(func);
|
3570
3647
|
|
3571
3648
|
if (args) {
|
@@ -3606,6 +3683,18 @@ Ember.computed.not = function(dependentKey) {
|
|
3606
3683
|
});
|
3607
3684
|
};
|
3608
3685
|
|
3686
|
+
/**
|
3687
|
+
@method computed.none
|
3688
|
+
@for Ember
|
3689
|
+
@param {String} dependentKey
|
3690
|
+
*/
|
3691
|
+
Ember.computed.none = function(dependentKey) {
|
3692
|
+
return Ember.computed(dependentKey, function(key) {
|
3693
|
+
var val = get(this, dependentKey);
|
3694
|
+
return Ember.isNone(val);
|
3695
|
+
});
|
3696
|
+
};
|
3697
|
+
|
3609
3698
|
/**
|
3610
3699
|
@method computed.empty
|
3611
3700
|
@for Ember
|
@@ -3614,7 +3703,7 @@ Ember.computed.not = function(dependentKey) {
|
|
3614
3703
|
Ember.computed.empty = function(dependentKey) {
|
3615
3704
|
return Ember.computed(dependentKey, function(key) {
|
3616
3705
|
var val = get(this, dependentKey);
|
3617
|
-
return
|
3706
|
+
return Ember.isEmpty(val);
|
3618
3707
|
});
|
3619
3708
|
};
|
3620
3709
|
|
@@ -3632,15 +3721,16 @@ Ember.computed.bool = function(dependentKey) {
|
|
3632
3721
|
/**
|
3633
3722
|
@method computed.alias
|
3634
3723
|
@for Ember
|
3724
|
+
|
3635
3725
|
@param {String} dependentKey
|
3636
3726
|
*/
|
3637
3727
|
Ember.computed.alias = function(dependentKey) {
|
3638
3728
|
return Ember.computed(dependentKey, function(key, value){
|
3639
|
-
if (arguments.length
|
3640
|
-
return get(this, dependentKey);
|
3641
|
-
} else {
|
3729
|
+
if (arguments.length > 1) {
|
3642
3730
|
set(this, dependentKey, value);
|
3643
3731
|
return value;
|
3732
|
+
} else {
|
3733
|
+
return get(this, dependentKey);
|
3644
3734
|
}
|
3645
3735
|
});
|
3646
3736
|
};
|
@@ -3656,7 +3746,6 @@ Ember.computed.alias = function(dependentKey) {
|
|
3656
3746
|
|
3657
3747
|
var o_create = Ember.create,
|
3658
3748
|
metaFor = Ember.meta,
|
3659
|
-
metaPath = Ember.metaPath,
|
3660
3749
|
META_KEY = Ember.META_KEY;
|
3661
3750
|
|
3662
3751
|
/*
|
@@ -4229,7 +4318,7 @@ Ember.RunLoop = RunLoop;
|
|
4229
4318
|
|
4230
4319
|
```javascript
|
4231
4320
|
Ember.run(function(){
|
4232
|
-
// code to be execute within a RunLoop
|
4321
|
+
// code to be execute within a RunLoop
|
4233
4322
|
});
|
4234
4323
|
```
|
4235
4324
|
|
@@ -4245,8 +4334,7 @@ Ember.RunLoop = RunLoop;
|
|
4245
4334
|
@return {Object} return value from invoking the passed function.
|
4246
4335
|
*/
|
4247
4336
|
Ember.run = function(target, method) {
|
4248
|
-
var
|
4249
|
-
args = arguments;
|
4337
|
+
var args = arguments;
|
4250
4338
|
run.begin();
|
4251
4339
|
|
4252
4340
|
function tryable() {
|
@@ -4264,11 +4352,11 @@ var run = Ember.run;
|
|
4264
4352
|
/**
|
4265
4353
|
Begins a new RunLoop. Any deferred actions invoked after the begin will
|
4266
4354
|
be buffered until you invoke a matching call to `Ember.run.end()`. This is
|
4267
|
-
|
4355
|
+
a lower-level way to use a RunLoop instead of using `Ember.run()`.
|
4268
4356
|
|
4269
4357
|
```javascript
|
4270
4358
|
Ember.run.begin();
|
4271
|
-
// code to be execute within a RunLoop
|
4359
|
+
// code to be execute within a RunLoop
|
4272
4360
|
Ember.run.end();
|
4273
4361
|
```
|
4274
4362
|
|
@@ -4286,7 +4374,7 @@ Ember.run.begin = function() {
|
|
4286
4374
|
|
4287
4375
|
```javascript
|
4288
4376
|
Ember.run.begin();
|
4289
|
-
// code to be execute within a RunLoop
|
4377
|
+
// code to be execute within a RunLoop
|
4290
4378
|
Ember.run.end();
|
4291
4379
|
```
|
4292
4380
|
|
@@ -4310,9 +4398,9 @@ Ember.run.end = function() {
|
|
4310
4398
|
|
4311
4399
|
@property queues
|
4312
4400
|
@type Array
|
4313
|
-
@default ['sync', 'actions', 'destroy'
|
4401
|
+
@default ['sync', 'actions', 'destroy']
|
4314
4402
|
*/
|
4315
|
-
Ember.run.queues = ['sync', 'actions', 'destroy'
|
4403
|
+
Ember.run.queues = ['sync', 'actions', 'destroy'];
|
4316
4404
|
|
4317
4405
|
/**
|
4318
4406
|
Adds the passed target/method and any optional arguments to the named
|
@@ -4325,19 +4413,19 @@ Ember.run.queues = ['sync', 'actions', 'destroy', 'timers'];
|
|
4325
4413
|
the `run.queues` property.
|
4326
4414
|
|
4327
4415
|
```javascript
|
4328
|
-
Ember.run.schedule('timers', this, function(){
|
4329
|
-
// this will be executed at the end of the RunLoop, when timers are run
|
4330
|
-
console.log("scheduled on timers queue");
|
4331
|
-
});
|
4332
|
-
|
4333
4416
|
Ember.run.schedule('sync', this, function(){
|
4334
|
-
// this will be executed
|
4417
|
+
// this will be executed in the first RunLoop queue, when bindings are synced
|
4335
4418
|
console.log("scheduled on sync queue");
|
4336
4419
|
});
|
4337
4420
|
|
4421
|
+
Ember.run.schedule('actions', this, function(){
|
4422
|
+
// this will be executed in the 'actions' queue, after bindings have synced.
|
4423
|
+
console.log("scheduled on actions queue");
|
4424
|
+
});
|
4425
|
+
|
4338
4426
|
// Note the functions will be run in order based on the run queues order. Output would be:
|
4339
4427
|
// scheduled on sync queue
|
4340
|
-
// scheduled on
|
4428
|
+
// scheduled on actions queue
|
4341
4429
|
```
|
4342
4430
|
|
4343
4431
|
@method schedule
|
@@ -4363,7 +4451,7 @@ function autorun() {
|
|
4363
4451
|
|
4364
4452
|
// Used by global test teardown
|
4365
4453
|
Ember.run.hasScheduledTimers = function() {
|
4366
|
-
return !!(scheduledAutorun || scheduledLater
|
4454
|
+
return !!(scheduledAutorun || scheduledLater);
|
4367
4455
|
};
|
4368
4456
|
|
4369
4457
|
// Used by global test teardown
|
@@ -4376,10 +4464,6 @@ Ember.run.cancelTimers = function () {
|
|
4376
4464
|
clearTimeout(scheduledLater);
|
4377
4465
|
scheduledLater = null;
|
4378
4466
|
}
|
4379
|
-
if (scheduledNext) {
|
4380
|
-
clearTimeout(scheduledNext);
|
4381
|
-
scheduledNext = null;
|
4382
|
-
}
|
4383
4467
|
timers = {};
|
4384
4468
|
};
|
4385
4469
|
|
@@ -4414,7 +4498,8 @@ Ember.run.autorun = function() {
|
|
4414
4498
|
bindings in the application to sync.
|
4415
4499
|
|
4416
4500
|
You should call this method anytime you need any changed state to propagate
|
4417
|
-
throughout the app immediately without repainting the UI
|
4501
|
+
throughout the app immediately without repainting the UI (which happens
|
4502
|
+
in the later 'render' queue added by the `ember-views` package).
|
4418
4503
|
|
4419
4504
|
```javascript
|
4420
4505
|
Ember.run.sync();
|
@@ -4434,25 +4519,30 @@ Ember.run.sync = function() {
|
|
4434
4519
|
|
4435
4520
|
var timers = {}; // active timers...
|
4436
4521
|
|
4437
|
-
var scheduledLater;
|
4522
|
+
var scheduledLater, scheduledLaterExpires;
|
4438
4523
|
function invokeLaterTimers() {
|
4439
4524
|
scheduledLater = null;
|
4440
|
-
|
4441
|
-
|
4442
|
-
|
4443
|
-
|
4444
|
-
|
4445
|
-
if (
|
4446
|
-
|
4447
|
-
|
4448
|
-
|
4449
|
-
|
4525
|
+
run(function() {
|
4526
|
+
var now = (+ new Date()), earliest = -1;
|
4527
|
+
for (var key in timers) {
|
4528
|
+
if (!timers.hasOwnProperty(key)) { continue; }
|
4529
|
+
var timer = timers[key];
|
4530
|
+
if (timer && timer.expires) {
|
4531
|
+
if (now >= timer.expires) {
|
4532
|
+
delete timers[key];
|
4533
|
+
invoke(timer.target, timer.method, timer.args, 2);
|
4534
|
+
} else {
|
4535
|
+
if (earliest < 0 || (timer.expires < earliest)) { earliest = timer.expires; }
|
4536
|
+
}
|
4450
4537
|
}
|
4451
4538
|
}
|
4452
|
-
}
|
4453
4539
|
|
4454
|
-
|
4455
|
-
|
4540
|
+
// schedule next timeout to fire when the earliest timer expires
|
4541
|
+
if (earliest > 0) {
|
4542
|
+
scheduledLater = setTimeout(invokeLaterTimers, earliest - now);
|
4543
|
+
scheduledLaterExpires = earliest;
|
4544
|
+
}
|
4545
|
+
});
|
4456
4546
|
}
|
4457
4547
|
|
4458
4548
|
/**
|
@@ -4500,7 +4590,19 @@ Ember.run.later = function(target, method) {
|
|
4500
4590
|
timer = { target: target, method: method, expires: expires, args: args };
|
4501
4591
|
guid = Ember.guidFor(timer);
|
4502
4592
|
timers[guid] = timer;
|
4503
|
-
|
4593
|
+
|
4594
|
+
if(scheduledLater && expires < scheduledLaterExpires) {
|
4595
|
+
// Cancel later timer (then reschedule earlier timer below)
|
4596
|
+
clearTimeout(scheduledLater);
|
4597
|
+
scheduledLater = null;
|
4598
|
+
}
|
4599
|
+
|
4600
|
+
if (!scheduledLater) {
|
4601
|
+
// Schedule later timers to be run.
|
4602
|
+
scheduledLater = setTimeout(invokeLaterTimers, wait);
|
4603
|
+
scheduledLaterExpires = expires;
|
4604
|
+
}
|
4605
|
+
|
4504
4606
|
return guid;
|
4505
4607
|
};
|
4506
4608
|
|
@@ -4556,6 +4658,21 @@ function scheduleOnce(queue, target, method, args) {
|
|
4556
4658
|
});
|
4557
4659
|
```
|
4558
4660
|
|
4661
|
+
Also note that passing an anonymous function to `Ember.run.once` will
|
4662
|
+
not prevent additional calls with an identical anonymous function from
|
4663
|
+
scheduling the items multiple times, e.g.:
|
4664
|
+
|
4665
|
+
```javascript
|
4666
|
+
function scheduleIt() {
|
4667
|
+
Ember.run.once(myContext, function() { console.log("Closure"); });
|
4668
|
+
}
|
4669
|
+
scheduleIt();
|
4670
|
+
scheduleIt();
|
4671
|
+
// "Closure" will print twice, even though we're using `Ember.run.once`,
|
4672
|
+
// because the function we pass to it is anonymous and won't match the
|
4673
|
+
// previously scheduled operation.
|
4674
|
+
```
|
4675
|
+
|
4559
4676
|
@method once
|
4560
4677
|
@param {Object} [target] target of method to invoke
|
4561
4678
|
@param {Function|String} method The method to invoke.
|
@@ -4572,22 +4689,9 @@ Ember.run.scheduleOnce = function(queue, target, method, args) {
|
|
4572
4689
|
return scheduleOnce(queue, target, method, slice.call(arguments, 3));
|
4573
4690
|
};
|
4574
4691
|
|
4575
|
-
var scheduledNext;
|
4576
|
-
function invokeNextTimers() {
|
4577
|
-
scheduledNext = null;
|
4578
|
-
for(var key in timers) {
|
4579
|
-
if (!timers.hasOwnProperty(key)) { continue; }
|
4580
|
-
var timer = timers[key];
|
4581
|
-
if (timer.next) {
|
4582
|
-
delete timers[key];
|
4583
|
-
invoke(timer.target, timer.method, timer.args, 2);
|
4584
|
-
}
|
4585
|
-
}
|
4586
|
-
}
|
4587
|
-
|
4588
4692
|
/**
|
4589
4693
|
Schedules an item to run after control has been returned to the system.
|
4590
|
-
This is
|
4694
|
+
This is equivalent to calling `Ember.run.later` with a wait time of 1ms.
|
4591
4695
|
|
4592
4696
|
```javascript
|
4593
4697
|
Ember.run.next(myContext, function(){
|
@@ -4603,20 +4707,10 @@ function invokeNextTimers() {
|
|
4603
4707
|
@param {Object} [args*] Optional arguments to pass to the timeout.
|
4604
4708
|
@return {Object} timer
|
4605
4709
|
*/
|
4606
|
-
Ember.run.next = function(
|
4607
|
-
var
|
4608
|
-
|
4609
|
-
|
4610
|
-
method: method,
|
4611
|
-
args: slice.call(arguments),
|
4612
|
-
next: true
|
4613
|
-
};
|
4614
|
-
|
4615
|
-
guid = Ember.guidFor(timer);
|
4616
|
-
timers[guid] = timer;
|
4617
|
-
|
4618
|
-
if (!scheduledNext) { scheduledNext = setTimeout(invokeNextTimers, 1); }
|
4619
|
-
return guid;
|
4710
|
+
Ember.run.next = function() {
|
4711
|
+
var args = slice.call(arguments);
|
4712
|
+
args.push(1); // 1 millisecond wait
|
4713
|
+
return run.later.apply(this, args);
|
4620
4714
|
};
|
4621
4715
|
|
4622
4716
|
/**
|
@@ -5121,7 +5215,6 @@ var Mixin, REQUIRED, Alias,
|
|
5121
5215
|
a_indexOf = Ember.ArrayPolyfills.indexOf,
|
5122
5216
|
a_forEach = Ember.ArrayPolyfills.forEach,
|
5123
5217
|
a_slice = [].slice,
|
5124
|
-
EMPTY_META = {}, // dummy for non-writable meta
|
5125
5218
|
o_create = Ember.create,
|
5126
5219
|
defineProperty = Ember.defineProperty,
|
5127
5220
|
guidFor = Ember.guidFor;
|
@@ -5490,6 +5583,38 @@ Mixin.finishPartial = finishPartial;
|
|
5490
5583
|
Ember.anyUnprocessedMixins = false;
|
5491
5584
|
|
5492
5585
|
/**
|
5586
|
+
Creates an instance of a class. Accepts either no arguments, or an object
|
5587
|
+
containing values to initialize the newly instantiated object with.
|
5588
|
+
|
5589
|
+
```javascript
|
5590
|
+
App.Person = Ember.Object.extend({
|
5591
|
+
helloWorld: function() {
|
5592
|
+
alert("Hi, my name is " + this.get('name'));
|
5593
|
+
}
|
5594
|
+
});
|
5595
|
+
|
5596
|
+
var tom = App.Person.create({
|
5597
|
+
name: 'Tom Dale'
|
5598
|
+
});
|
5599
|
+
|
5600
|
+
tom.helloWorld(); // alerts "Hi, my name is Tom Dale".
|
5601
|
+
```
|
5602
|
+
|
5603
|
+
`create` will call the `init` function if defined during
|
5604
|
+
`Ember.AnyObject.extend`
|
5605
|
+
|
5606
|
+
If no arguments are passed to `create`, it will not set values to the new
|
5607
|
+
instance during initialization:
|
5608
|
+
|
5609
|
+
```javascript
|
5610
|
+
var noName = App.Person.create();
|
5611
|
+
noName.helloWorld(); // alerts undefined
|
5612
|
+
```
|
5613
|
+
|
5614
|
+
NOTE: For performance reasons, you cannot declare methods or computed
|
5615
|
+
properties during `create`. You should instead declare methods and computed
|
5616
|
+
properties when using `extend`.
|
5617
|
+
|
5493
5618
|
@method create
|
5494
5619
|
@static
|
5495
5620
|
@param arguments*
|
@@ -6005,35 +6130,35 @@ define("rsvp",
|
|
6005
6130
|
}
|
6006
6131
|
|
6007
6132
|
function all(promises) {
|
6008
|
-
|
6009
|
-
|
6010
|
-
|
6133
|
+
var i, results = [];
|
6134
|
+
var allPromise = new Promise();
|
6135
|
+
var remaining = promises.length;
|
6011
6136
|
|
6012
6137
|
if (remaining === 0) {
|
6013
6138
|
allPromise.resolve([]);
|
6014
6139
|
}
|
6015
6140
|
|
6016
|
-
|
6017
|
-
|
6018
|
-
|
6019
|
-
|
6020
|
-
|
6141
|
+
var resolver = function(index) {
|
6142
|
+
return function(value) {
|
6143
|
+
resolve(index, value);
|
6144
|
+
};
|
6145
|
+
};
|
6021
6146
|
|
6022
|
-
|
6023
|
-
|
6024
|
-
|
6025
|
-
|
6026
|
-
|
6027
|
-
|
6147
|
+
var resolve = function(index, value) {
|
6148
|
+
results[index] = value;
|
6149
|
+
if (--remaining === 0) {
|
6150
|
+
allPromise.resolve(results);
|
6151
|
+
}
|
6152
|
+
};
|
6028
6153
|
|
6029
|
-
|
6030
|
-
|
6031
|
-
|
6154
|
+
var reject = function(error) {
|
6155
|
+
allPromise.reject(error);
|
6156
|
+
};
|
6032
6157
|
|
6033
|
-
|
6034
|
-
|
6035
|
-
|
6036
|
-
|
6158
|
+
for (i = 0; i < remaining; i++) {
|
6159
|
+
promises[i].then(resolver(i), reject);
|
6160
|
+
}
|
6161
|
+
return allPromise;
|
6037
6162
|
}
|
6038
6163
|
|
6039
6164
|
EventTarget.mixin(Promise.prototype);
|
@@ -6409,57 +6534,6 @@ Ember.typeOf = function(item) {
|
|
6409
6534
|
return ret;
|
6410
6535
|
};
|
6411
6536
|
|
6412
|
-
/**
|
6413
|
-
Returns true if the passed value is null or undefined. This avoids errors
|
6414
|
-
from JSLint complaining about use of ==, which can be technically
|
6415
|
-
confusing.
|
6416
|
-
|
6417
|
-
```javascript
|
6418
|
-
Ember.isNone(); // true
|
6419
|
-
Ember.isNone(null); // true
|
6420
|
-
Ember.isNone(undefined); // true
|
6421
|
-
Ember.isNone(''); // false
|
6422
|
-
Ember.isNone([]); // false
|
6423
|
-
Ember.isNone(function(){}); // false
|
6424
|
-
```
|
6425
|
-
|
6426
|
-
@method isNone
|
6427
|
-
@for Ember
|
6428
|
-
@param {Object} obj Value to test
|
6429
|
-
@return {Boolean}
|
6430
|
-
*/
|
6431
|
-
Ember.isNone = function(obj) {
|
6432
|
-
return obj === null || obj === undefined;
|
6433
|
-
};
|
6434
|
-
Ember.none = Ember.deprecateFunc("Ember.none is deprecated. Please use Ember.isNone instead.", Ember.isNone);
|
6435
|
-
|
6436
|
-
/**
|
6437
|
-
Verifies that a value is `null` or an empty string, empty array,
|
6438
|
-
or empty function.
|
6439
|
-
|
6440
|
-
Constrains the rules on `Ember.isNone` by returning false for empty
|
6441
|
-
string and empty arrays.
|
6442
|
-
|
6443
|
-
```javascript
|
6444
|
-
Ember.isEmpty(); // true
|
6445
|
-
Ember.isEmpty(null); // true
|
6446
|
-
Ember.isEmpty(undefined); // true
|
6447
|
-
Ember.isEmpty(''); // true
|
6448
|
-
Ember.isEmpty([]); // true
|
6449
|
-
Ember.isEmpty('Adam Hawkins'); // false
|
6450
|
-
Ember.isEmpty([0,1,2]); // false
|
6451
|
-
```
|
6452
|
-
|
6453
|
-
@method isEmpty
|
6454
|
-
@for Ember
|
6455
|
-
@param {Object} obj Value to test
|
6456
|
-
@return {Boolean}
|
6457
|
-
*/
|
6458
|
-
Ember.isEmpty = function(obj) {
|
6459
|
-
return obj === null || obj === undefined || (obj.length === 0 && typeof obj !== 'function') || (typeof obj === 'object' && Ember.get(obj, 'length') === 0);
|
6460
|
-
};
|
6461
|
-
Ember.empty = Ember.deprecateFunc("Ember.empty is deprecated. Please use Ember.isEmpty instead.", Ember.isEmpty) ;
|
6462
|
-
|
6463
6537
|
/**
|
6464
6538
|
This will compare two javascript values of possibly different types.
|
6465
6539
|
It will tell you which one is greater than the other by returning:
|
@@ -6753,6 +6827,20 @@ Ember.Error.prototype = Ember.create(Error.prototype);
|
|
6753
6827
|
|
6754
6828
|
|
6755
6829
|
|
6830
|
+
(function() {
|
6831
|
+
/**
|
6832
|
+
Expose RSVP implementation
|
6833
|
+
|
6834
|
+
@class RSVP
|
6835
|
+
@namespace Ember
|
6836
|
+
@constructor
|
6837
|
+
*/
|
6838
|
+
Ember.RSVP = requireModule('rsvp');
|
6839
|
+
|
6840
|
+
})();
|
6841
|
+
|
6842
|
+
|
6843
|
+
|
6756
6844
|
(function() {
|
6757
6845
|
/**
|
6758
6846
|
@module ember
|
@@ -6901,10 +6989,11 @@ Ember.String = {
|
|
6901
6989
|
*/
|
6902
6990
|
dasherize: function(str) {
|
6903
6991
|
var cache = STRING_DASHERIZE_CACHE,
|
6904
|
-
|
6992
|
+
hit = cache.hasOwnProperty(str),
|
6993
|
+
ret;
|
6905
6994
|
|
6906
|
-
if (
|
6907
|
-
return
|
6995
|
+
if (hit) {
|
6996
|
+
return cache[str];
|
6908
6997
|
} else {
|
6909
6998
|
ret = Ember.String.decamelize(str).replace(STRING_DASHERIZE_REGEXP,'-');
|
6910
6999
|
cache[str] = ret;
|
@@ -6914,7 +7003,7 @@ Ember.String = {
|
|
6914
7003
|
},
|
6915
7004
|
|
6916
7005
|
/**
|
6917
|
-
Returns the
|
7006
|
+
Returns the lowerCamelCase form of a string.
|
6918
7007
|
|
6919
7008
|
```javascript
|
6920
7009
|
'innerHTML'.camelize(); // 'innerHTML'
|
@@ -6985,10 +7074,10 @@ Ember.String = {
|
|
6985
7074
|
/**
|
6986
7075
|
Returns the Capitalized form of a string
|
6987
7076
|
|
6988
|
-
'innerHTML'.capitalize()
|
6989
|
-
'action_name'.capitalize()
|
6990
|
-
'css-class-name'.capitalize()
|
6991
|
-
'my favorite items'.capitalize()
|
7077
|
+
'innerHTML'.capitalize() // 'InnerHTML'
|
7078
|
+
'action_name'.capitalize() // 'Action_name'
|
7079
|
+
'css-class-name'.capitalize() // 'Css-class-name'
|
7080
|
+
'my favorite items'.capitalize() // 'My favorite items'
|
6992
7081
|
|
6993
7082
|
@method capitalize
|
6994
7083
|
@param {String} str
|
@@ -7332,8 +7421,7 @@ function iter(key, value) {
|
|
7332
7421
|
@extends Ember.Mixin
|
7333
7422
|
@since Ember 0.9
|
7334
7423
|
*/
|
7335
|
-
Ember.Enumerable = Ember.Mixin.create(
|
7336
|
-
/** @scope Ember.Enumerable.prototype */ {
|
7424
|
+
Ember.Enumerable = Ember.Mixin.create({
|
7337
7425
|
|
7338
7426
|
// compatibility
|
7339
7427
|
isEnumerable: true,
|
@@ -7366,7 +7454,7 @@ Ember.Enumerable = Ember.Mixin.create(
|
|
7366
7454
|
|
7367
7455
|
@method nextObject
|
7368
7456
|
@param {Number} index the current index of the iteration
|
7369
|
-
@param {Object} previousObject the value returned by the last call to
|
7457
|
+
@param {Object} previousObject the value returned by the last call to
|
7370
7458
|
`nextObject`.
|
7371
7459
|
@param {Object} context a context object you can use to maintain state.
|
7372
7460
|
@return {Object} the next object in the iteration or undefined
|
@@ -7385,10 +7473,10 @@ Ember.Enumerable = Ember.Mixin.create(
|
|
7385
7473
|
|
7386
7474
|
```javascript
|
7387
7475
|
var arr = ["a", "b", "c"];
|
7388
|
-
arr.firstObject
|
7476
|
+
arr.get('firstObject'); // "a"
|
7389
7477
|
|
7390
7478
|
var arr = [];
|
7391
|
-
arr.firstObject
|
7479
|
+
arr.get('firstObject'); // undefined
|
7392
7480
|
```
|
7393
7481
|
|
7394
7482
|
@property firstObject
|
@@ -7411,10 +7499,10 @@ Ember.Enumerable = Ember.Mixin.create(
|
|
7411
7499
|
|
7412
7500
|
```javascript
|
7413
7501
|
var arr = ["a", "b", "c"];
|
7414
|
-
arr.lastObject
|
7502
|
+
arr.get('lastObject'); // "c"
|
7415
7503
|
|
7416
7504
|
var arr = [];
|
7417
|
-
arr.lastObject
|
7505
|
+
arr.get('lastObject'); // undefined
|
7418
7506
|
```
|
7419
7507
|
|
7420
7508
|
@property lastObject
|
@@ -7547,7 +7635,7 @@ Ember.Enumerable = Ember.Mixin.create(
|
|
7547
7635
|
@return {Array} The mapped array.
|
7548
7636
|
*/
|
7549
7637
|
map: function(callback, target) {
|
7550
|
-
var ret = [];
|
7638
|
+
var ret = Ember.A([]);
|
7551
7639
|
this.forEach(function(x, idx, i) {
|
7552
7640
|
ret[idx] = callback.call(target, x, idx,i);
|
7553
7641
|
});
|
@@ -7597,7 +7685,7 @@ Ember.Enumerable = Ember.Mixin.create(
|
|
7597
7685
|
@return {Array} A filtered array.
|
7598
7686
|
*/
|
7599
7687
|
filter: function(callback, target) {
|
7600
|
-
var ret = [];
|
7688
|
+
var ret = Ember.A([]);
|
7601
7689
|
this.forEach(function(x, idx, i) {
|
7602
7690
|
if (callback.call(target, x, idx, i)) ret.push(x);
|
7603
7691
|
});
|
@@ -7886,7 +7974,7 @@ Ember.Enumerable = Ember.Mixin.create(
|
|
7886
7974
|
@return {Array} return values from calling invoke.
|
7887
7975
|
*/
|
7888
7976
|
invoke: function(methodName) {
|
7889
|
-
var args, ret = [];
|
7977
|
+
var args, ret = Ember.A([]);
|
7890
7978
|
if (arguments.length>1) args = a_slice.call(arguments, 1);
|
7891
7979
|
|
7892
7980
|
this.forEach(function(x, idx) {
|
@@ -7907,7 +7995,7 @@ Ember.Enumerable = Ember.Mixin.create(
|
|
7907
7995
|
@return {Array} the enumerable as an array.
|
7908
7996
|
*/
|
7909
7997
|
toArray: function() {
|
7910
|
-
var ret = [];
|
7998
|
+
var ret = Ember.A([]);
|
7911
7999
|
this.forEach(function(o, idx) { ret[idx] = o; });
|
7912
8000
|
return ret ;
|
7913
8001
|
},
|
@@ -7941,7 +8029,7 @@ Ember.Enumerable = Ember.Mixin.create(
|
|
7941
8029
|
*/
|
7942
8030
|
without: function(value) {
|
7943
8031
|
if (!this.contains(value)) return this; // nothing to do
|
7944
|
-
var ret = []
|
8032
|
+
var ret = Ember.A([]);
|
7945
8033
|
this.forEach(function(k) {
|
7946
8034
|
if (k !== value) ret[ret.length] = k;
|
7947
8035
|
}) ;
|
@@ -7961,7 +8049,7 @@ Ember.Enumerable = Ember.Mixin.create(
|
|
7961
8049
|
@return {Ember.Enumerable}
|
7962
8050
|
*/
|
7963
8051
|
uniq: function() {
|
7964
|
-
var ret = [];
|
8052
|
+
var ret = Ember.A([]);
|
7965
8053
|
this.forEach(function(k){
|
7966
8054
|
if (a_indexOf(ret, k)<0) ret.push(k);
|
7967
8055
|
});
|
@@ -7993,7 +8081,7 @@ Ember.Enumerable = Ember.Mixin.create(
|
|
7993
8081
|
|
7994
8082
|
@method addEnumerableObserver
|
7995
8083
|
@param {Object} target
|
7996
|
-
@param {Hash} opts
|
8084
|
+
@param {Hash} [opts]
|
7997
8085
|
*/
|
7998
8086
|
addEnumerableObserver: function(target, opts) {
|
7999
8087
|
var willChange = (opts && opts.willChange) || 'enumerableWillChange',
|
@@ -8091,7 +8179,7 @@ Ember.Enumerable = Ember.Mixin.create(
|
|
8091
8179
|
@chainable
|
8092
8180
|
*/
|
8093
8181
|
enumerableContentDidChange: function(removing, adding) {
|
8094
|
-
var
|
8182
|
+
var removeCnt, addCnt, hasDelta;
|
8095
8183
|
|
8096
8184
|
if ('number' === typeof removing) removeCnt = removing;
|
8097
8185
|
else if (removing) removeCnt = get(removing, 'length');
|
@@ -8129,7 +8217,7 @@ Ember.Enumerable = Ember.Mixin.create(
|
|
8129
8217
|
// HELPERS
|
8130
8218
|
//
|
8131
8219
|
|
8132
|
-
var get = Ember.get, set = Ember.set,
|
8220
|
+
var get = Ember.get, set = Ember.set, map = Ember.EnumerableUtils.map, cacheFor = Ember.cacheFor;
|
8133
8221
|
|
8134
8222
|
function none(obj) { return obj===null || obj===undefined; }
|
8135
8223
|
|
@@ -8271,15 +8359,19 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
|
8271
8359
|
```
|
8272
8360
|
|
8273
8361
|
@method slice
|
8274
|
-
@param
|
8275
|
-
@param
|
8362
|
+
@param {Integer} beginIndex (Optional) index to begin slicing from.
|
8363
|
+
@param {Integer} endIndex (Optional) index to end the slice at.
|
8276
8364
|
@return {Array} New array with specified slice
|
8277
8365
|
*/
|
8278
8366
|
slice: function(beginIndex, endIndex) {
|
8279
|
-
var ret = [];
|
8367
|
+
var ret = Ember.A([]);
|
8280
8368
|
var length = get(this, 'length') ;
|
8281
8369
|
if (none(beginIndex)) beginIndex = 0 ;
|
8282
8370
|
if (none(endIndex) || (endIndex > length)) endIndex = length ;
|
8371
|
+
|
8372
|
+
if (beginIndex < 0) beginIndex = length + beginIndex;
|
8373
|
+
if (endIndex < 0) endIndex = length + endIndex;
|
8374
|
+
|
8283
8375
|
while(beginIndex < endIndex) {
|
8284
8376
|
ret[ret.length] = this.objectAt(beginIndex++) ;
|
8285
8377
|
}
|
@@ -8433,9 +8525,9 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
|
8433
8525
|
|
8434
8526
|
@method arrayContentWillChange
|
8435
8527
|
@param {Number} startIdx The starting index in the array that will change.
|
8436
|
-
@param {Number} removeAmt The number of items that will be removed. If you
|
8528
|
+
@param {Number} removeAmt The number of items that will be removed. If you
|
8437
8529
|
pass `null` assumes 0
|
8438
|
-
@param {Number} addAmt The number of items that will be added If you
|
8530
|
+
@param {Number} addAmt The number of items that will be added If you
|
8439
8531
|
pass `null` assumes 0.
|
8440
8532
|
@return {Ember.Array} receiver
|
8441
8533
|
*/
|
@@ -8796,8 +8888,7 @@ var forEach = Ember.EnumerableUtils.forEach;
|
|
8796
8888
|
@extends Ember.Mixin
|
8797
8889
|
@uses Ember.Enumerable
|
8798
8890
|
*/
|
8799
|
-
Ember.MutableEnumerable = Ember.Mixin.create(Ember.Enumerable,
|
8800
|
-
/** @scope Ember.MutableEnumerable.prototype */ {
|
8891
|
+
Ember.MutableEnumerable = Ember.Mixin.create(Ember.Enumerable, {
|
8801
8892
|
|
8802
8893
|
/**
|
8803
8894
|
__Required.__ You must implement this method to apply this mixin.
|
@@ -8882,7 +8973,7 @@ var EMPTY = [];
|
|
8882
8973
|
// HELPERS
|
8883
8974
|
//
|
8884
8975
|
|
8885
|
-
var get = Ember.get, set = Ember.set
|
8976
|
+
var get = Ember.get, set = Ember.set;
|
8886
8977
|
|
8887
8978
|
/**
|
8888
8979
|
This mixin defines the API for modifying array-like objects. These methods
|
@@ -8909,11 +9000,11 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,
|
|
8909
9000
|
passed array. You should also call `this.enumerableContentDidChange()`
|
8910
9001
|
|
8911
9002
|
@method replace
|
8912
|
-
@param {Number} idx Starting index in the array to replace. If
|
9003
|
+
@param {Number} idx Starting index in the array to replace. If
|
8913
9004
|
idx >= length, then append to the end of the array.
|
8914
|
-
@param {Number} amt Number of elements that should be removed from
|
9005
|
+
@param {Number} amt Number of elements that should be removed from
|
8915
9006
|
the array, starting at *idx*.
|
8916
|
-
@param {Array} objects An array of zero or more objects that should be
|
9007
|
+
@param {Array} objects An array of zero or more objects that should be
|
8917
9008
|
inserted into the array at *idx*
|
8918
9009
|
*/
|
8919
9010
|
replace: Ember.required(),
|
@@ -9178,7 +9269,7 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,
|
|
9178
9269
|
@submodule ember-runtime
|
9179
9270
|
*/
|
9180
9271
|
|
9181
|
-
var get = Ember.get, set = Ember.set
|
9272
|
+
var get = Ember.get, set = Ember.set;
|
9182
9273
|
|
9183
9274
|
/**
|
9184
9275
|
## Overview
|
@@ -9776,6 +9867,16 @@ Ember.TargetActionSupport = Ember.Mixin.create({
|
|
9776
9867
|
// outputs: 'Our person has greeted'
|
9777
9868
|
```
|
9778
9869
|
|
9870
|
+
You can also chain multiple event subscriptions:
|
9871
|
+
|
9872
|
+
```javascript
|
9873
|
+
person.on('greet', function() {
|
9874
|
+
console.log('Our person has greeted');
|
9875
|
+
}).one('greet', function() {
|
9876
|
+
console.log('Offer one-time special');
|
9877
|
+
}).off('event', this, forgetThis);
|
9878
|
+
```
|
9879
|
+
|
9779
9880
|
@class Evented
|
9780
9881
|
@namespace Ember
|
9781
9882
|
@extends Ember.Mixin
|
@@ -9803,6 +9904,7 @@ Ember.Evented = Ember.Mixin.create({
|
|
9803
9904
|
*/
|
9804
9905
|
on: function(name, target, method) {
|
9805
9906
|
Ember.addListener(this, name, target, method);
|
9907
|
+
return this;
|
9806
9908
|
},
|
9807
9909
|
|
9808
9910
|
/**
|
@@ -9826,6 +9928,7 @@ Ember.Evented = Ember.Mixin.create({
|
|
9826
9928
|
}
|
9827
9929
|
|
9828
9930
|
Ember.addListener(this, name, target, method, true);
|
9931
|
+
return this;
|
9829
9932
|
},
|
9830
9933
|
|
9831
9934
|
/**
|
@@ -9869,6 +9972,7 @@ Ember.Evented = Ember.Mixin.create({
|
|
9869
9972
|
*/
|
9870
9973
|
off: function(name, target, method) {
|
9871
9974
|
Ember.removeListener(this, name, target, method);
|
9975
|
+
return this;
|
9872
9976
|
},
|
9873
9977
|
|
9874
9978
|
/**
|
@@ -9899,8 +10003,7 @@ RSVP.async = function(callback, binding) {
|
|
9899
10003
|
@submodule ember-runtime
|
9900
10004
|
*/
|
9901
10005
|
|
9902
|
-
var get = Ember.get
|
9903
|
-
slice = Array.prototype.slice;
|
10006
|
+
var get = Ember.get;
|
9904
10007
|
|
9905
10008
|
/**
|
9906
10009
|
@class Deferred
|
@@ -9976,7 +10079,6 @@ Ember.Container.set = Ember.set;
|
|
9976
10079
|
var set = Ember.set, get = Ember.get,
|
9977
10080
|
o_create = Ember.create,
|
9978
10081
|
o_defineProperty = Ember.platform.defineProperty,
|
9979
|
-
a_slice = Array.prototype.slice,
|
9980
10082
|
GUID_KEY = Ember.GUID_KEY,
|
9981
10083
|
guidFor = Ember.guidFor,
|
9982
10084
|
generateGuid = Ember.generateGuid,
|
@@ -10124,6 +10226,37 @@ CoreObject.PrototypeMixin = Mixin.create({
|
|
10124
10226
|
|
10125
10227
|
isInstance: true,
|
10126
10228
|
|
10229
|
+
/**
|
10230
|
+
An overridable method called when objects are instantiated. By default,
|
10231
|
+
does nothing unless it is overridden during class definition.
|
10232
|
+
|
10233
|
+
Example:
|
10234
|
+
|
10235
|
+
```javascript
|
10236
|
+
App.Person = Ember.Object.extend({
|
10237
|
+
init: function() {
|
10238
|
+
this._super();
|
10239
|
+
alert('Name is ' + this.get('name'));
|
10240
|
+
}
|
10241
|
+
});
|
10242
|
+
|
10243
|
+
var steve = App.Person.create({
|
10244
|
+
name: "Steve"
|
10245
|
+
});
|
10246
|
+
|
10247
|
+
// alerts 'Name is Steve'.
|
10248
|
+
```
|
10249
|
+
|
10250
|
+
NOTE: If you do override `init` for a framework class like `Ember.View` or
|
10251
|
+
`Ember.ArrayController`, be sure to call `this._super()` in your
|
10252
|
+
`init` declaration! If you don't, Ember may not have an opportunity to
|
10253
|
+
do important setup work, and you'll see strange behavior in your
|
10254
|
+
application.
|
10255
|
+
|
10256
|
+
```
|
10257
|
+
|
10258
|
+
@method init
|
10259
|
+
*/
|
10127
10260
|
init: function() {},
|
10128
10261
|
|
10129
10262
|
/**
|
@@ -10168,14 +10301,14 @@ CoreObject.PrototypeMixin = Mixin.create({
|
|
10168
10301
|
view.get('classNames'); // ['ember-view', 'bar', 'foo', 'baz']
|
10169
10302
|
```
|
10170
10303
|
Adding a single property that is not an array will just add it in the array:
|
10171
|
-
|
10304
|
+
|
10172
10305
|
```javascript
|
10173
10306
|
var view = App.FooBarView.create({
|
10174
10307
|
classNames: 'baz'
|
10175
10308
|
})
|
10176
10309
|
view.get('classNames'); // ['ember-view', 'bar', 'foo', 'baz']
|
10177
10310
|
```
|
10178
|
-
|
10311
|
+
|
10179
10312
|
Using the `concatenatedProperties` property, we can tell to Ember that mix
|
10180
10313
|
the content of the properties.
|
10181
10314
|
|
@@ -10274,7 +10407,7 @@ CoreObject.PrototypeMixin = Mixin.create({
|
|
10274
10407
|
}
|
10275
10408
|
});
|
10276
10409
|
teacher = App.Teacher.create()
|
10277
|
-
teacher.toString();
|
10410
|
+
teacher.toString(); //=> "<App.Teacher:ember1026:Tom Dale>"
|
10278
10411
|
|
10279
10412
|
@method toString
|
10280
10413
|
@return {String} string representation
|
@@ -10453,687 +10586,723 @@ Ember.CoreObject = CoreObject;
|
|
10453
10586
|
@submodule ember-runtime
|
10454
10587
|
*/
|
10455
10588
|
|
10456
|
-
var get = Ember.get, set = Ember.set, guidFor = Ember.guidFor, none = Ember.isNone;
|
10457
|
-
|
10458
10589
|
/**
|
10459
|
-
|
10590
|
+
`Ember.Object` is the main base class for all Ember objects. It is a subclass
|
10591
|
+
of `Ember.CoreObject` with the `Ember.Observable` mixin applied. For details,
|
10592
|
+
see the documentation for each of these.
|
10460
10593
|
|
10461
|
-
|
10462
|
-
|
10463
|
-
|
10464
|
-
|
10594
|
+
@class Object
|
10595
|
+
@namespace Ember
|
10596
|
+
@extends Ember.CoreObject
|
10597
|
+
@uses Ember.Observable
|
10598
|
+
*/
|
10599
|
+
Ember.Object = Ember.CoreObject.extend(Ember.Observable);
|
10600
|
+
Ember.Object.toString = function() { return "Ember.Object"; };
|
10465
10601
|
|
10466
|
-
|
10467
|
-
on any enumerable object including both Sets and Arrays.
|
10602
|
+
})();
|
10468
10603
|
|
10469
|
-
## Creating a Set
|
10470
10604
|
|
10471
|
-
You can create a set like you would most objects using
|
10472
|
-
`new Ember.Set()`. Most new sets you create will be empty, but you can
|
10473
|
-
also initialize the set with some content by passing an array or other
|
10474
|
-
enumerable of objects to the constructor.
|
10475
10605
|
|
10476
|
-
|
10477
|
-
|
10606
|
+
(function() {
|
10607
|
+
/**
|
10608
|
+
@module ember
|
10609
|
+
@submodule ember-runtime
|
10610
|
+
*/
|
10478
10611
|
|
10479
|
-
|
10480
|
-
// creates a new empty set
|
10481
|
-
var foundNames = new Ember.Set();
|
10612
|
+
var get = Ember.get, indexOf = Ember.ArrayPolyfills.indexOf;
|
10482
10613
|
|
10483
|
-
|
10484
|
-
|
10614
|
+
/**
|
10615
|
+
A Namespace is an object usually used to contain other objects or methods
|
10616
|
+
such as an application or framework. Create a namespace anytime you want
|
10617
|
+
to define one of these new containers.
|
10485
10618
|
|
10486
|
-
|
10487
|
-
var namesCopy = new Ember.Set(names);
|
10619
|
+
# Example Usage
|
10488
10620
|
|
10489
|
-
|
10490
|
-
|
10621
|
+
```javascript
|
10622
|
+
MyFramework = Ember.Namespace.create({
|
10623
|
+
VERSION: '1.0.0'
|
10624
|
+
});
|
10491
10625
|
```
|
10492
10626
|
|
10493
|
-
|
10494
|
-
|
10495
|
-
|
10496
|
-
|
10497
|
-
|
10627
|
+
@class Namespace
|
10628
|
+
@namespace Ember
|
10629
|
+
@extends Ember.Object
|
10630
|
+
*/
|
10631
|
+
var Namespace = Ember.Namespace = Ember.Object.extend({
|
10632
|
+
isNamespace: true,
|
10498
10633
|
|
10499
|
-
|
10500
|
-
|
10501
|
-
|
10502
|
-
|
10503
|
-
you add the object to the set again.
|
10634
|
+
init: function() {
|
10635
|
+
Ember.Namespace.NAMESPACES.push(this);
|
10636
|
+
Ember.Namespace.PROCESSED = false;
|
10637
|
+
},
|
10504
10638
|
|
10505
|
-
|
10506
|
-
|
10639
|
+
toString: function() {
|
10640
|
+
var name = get(this, 'name');
|
10641
|
+
if (name) { return name; }
|
10507
10642
|
|
10508
|
-
|
10509
|
-
|
10510
|
-
|
10511
|
-
queue when you don't care which order the jobs are executed in.
|
10643
|
+
findNamespaces();
|
10644
|
+
return this[Ember.GUID_KEY+'_name'];
|
10645
|
+
},
|
10512
10646
|
|
10513
|
-
|
10647
|
+
nameClasses: function() {
|
10648
|
+
processNamespace([this.toString()], this, {});
|
10649
|
+
},
|
10514
10650
|
|
10515
|
-
|
10516
|
-
|
10651
|
+
destroy: function() {
|
10652
|
+
var namespaces = Ember.Namespace.NAMESPACES;
|
10653
|
+
Ember.lookup[this.toString()] = undefined;
|
10654
|
+
namespaces.splice(indexOf.call(namespaces, this), 1);
|
10655
|
+
this._super();
|
10656
|
+
}
|
10657
|
+
});
|
10517
10658
|
|
10518
|
-
|
10659
|
+
Namespace.reopenClass({
|
10660
|
+
NAMESPACES: [Ember],
|
10661
|
+
NAMESPACES_BY_ID: {},
|
10662
|
+
PROCESSED: false,
|
10663
|
+
processAll: processAllNamespaces,
|
10664
|
+
byName: function(name) {
|
10665
|
+
if (!Ember.BOOTED) {
|
10666
|
+
processAllNamespaces();
|
10667
|
+
}
|
10519
10668
|
|
10520
|
-
|
10521
|
-
|
10522
|
-
|
10523
|
-
removed from the set. See `Ember.Enumerable` for more information on
|
10524
|
-
enumerables.
|
10669
|
+
return NAMESPACES_BY_ID[name];
|
10670
|
+
}
|
10671
|
+
});
|
10525
10672
|
|
10526
|
-
|
10527
|
-
it is very inefficient to re-filter all of the items each time the set
|
10528
|
-
changes. It would be better if you could just adjust the filtered set based
|
10529
|
-
on what was changed on the original set. The same issue applies to merging
|
10530
|
-
sets, as well.
|
10673
|
+
var NAMESPACES_BY_ID = Namespace.NAMESPACES_BY_ID;
|
10531
10674
|
|
10532
|
-
|
10675
|
+
var hasOwnProp = ({}).hasOwnProperty,
|
10676
|
+
guidFor = Ember.guidFor;
|
10533
10677
|
|
10534
|
-
|
10535
|
-
|
10536
|
-
The most useful ones will be `Ember.Enumerable` and
|
10537
|
-
`Ember.MutableEnumerable` which implement most of the common iterator
|
10538
|
-
methods you are used to on Array.
|
10678
|
+
function processNamespace(paths, root, seen) {
|
10679
|
+
var idx = paths.length;
|
10539
10680
|
|
10540
|
-
|
10541
|
-
APIs on `Ember.Set` as well. Once a set is frozen it can no longer be
|
10542
|
-
modified. The benefit of this is that when you call `frozenCopy()` on it,
|
10543
|
-
Ember will avoid making copies of the set. This allows you to write
|
10544
|
-
code that can know with certainty when the underlying set data will or
|
10545
|
-
will not be modified.
|
10681
|
+
NAMESPACES_BY_ID[paths.join('.')] = root;
|
10546
10682
|
|
10547
|
-
|
10548
|
-
|
10549
|
-
|
10550
|
-
|
10551
|
-
@uses Ember.Copyable
|
10552
|
-
@uses Ember.Freezable
|
10553
|
-
@since Ember 0.9
|
10554
|
-
*/
|
10555
|
-
Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Ember.Freezable,
|
10556
|
-
/** @scope Ember.Set.prototype */ {
|
10683
|
+
// Loop over all of the keys in the namespace, looking for classes
|
10684
|
+
for(var key in root) {
|
10685
|
+
if (!hasOwnProp.call(root, key)) { continue; }
|
10686
|
+
var obj = root[key];
|
10557
10687
|
|
10558
|
-
|
10559
|
-
|
10560
|
-
|
10688
|
+
// If we are processing the `Ember` namespace, for example, the
|
10689
|
+
// `paths` will start with `["Ember"]`. Every iteration through
|
10690
|
+
// the loop will update the **second** element of this list with
|
10691
|
+
// the key, so processing `Ember.View` will make the Array
|
10692
|
+
// `['Ember', 'View']`.
|
10693
|
+
paths[idx] = key;
|
10561
10694
|
|
10562
|
-
|
10563
|
-
|
10695
|
+
// If we have found an unprocessed class
|
10696
|
+
if (obj && obj.toString === classToString) {
|
10697
|
+
// Replace the class' `toString` with the dot-separated path
|
10698
|
+
// and set its `NAME_KEY`
|
10699
|
+
obj.toString = makeToString(paths.join('.'));
|
10700
|
+
obj[NAME_KEY] = paths.join('.');
|
10564
10701
|
|
10565
|
-
|
10566
|
-
|
10567
|
-
|
10568
|
-
|
10569
|
-
|
10702
|
+
// Support nested namespaces
|
10703
|
+
} else if (obj && obj.isNamespace) {
|
10704
|
+
// Skip aliased namespaces
|
10705
|
+
if (seen[guidFor(obj)]) { continue; }
|
10706
|
+
seen[guidFor(obj)] = true;
|
10570
10707
|
|
10571
|
-
|
10572
|
-
|
10573
|
-
|
10708
|
+
// Process the child namespace
|
10709
|
+
processNamespace(paths, obj, seen);
|
10710
|
+
}
|
10711
|
+
}
|
10574
10712
|
|
10575
|
-
|
10576
|
-
|
10577
|
-
colors.length; // 3
|
10578
|
-
colors.clear();
|
10579
|
-
colors.length; // 0
|
10580
|
-
```
|
10713
|
+
paths.length = idx; // cut out last item
|
10714
|
+
}
|
10581
10715
|
|
10582
|
-
|
10583
|
-
|
10584
|
-
*/
|
10585
|
-
clear: function() {
|
10586
|
-
if (this.isFrozen) { throw new Error(Ember.FROZEN_ERROR); }
|
10716
|
+
function findNamespaces() {
|
10717
|
+
var Namespace = Ember.Namespace, lookup = Ember.lookup, obj, isNamespace;
|
10587
10718
|
|
10588
|
-
|
10589
|
-
if (len === 0) { return this; }
|
10719
|
+
if (Namespace.PROCESSED) { return; }
|
10590
10720
|
|
10591
|
-
|
10721
|
+
for (var prop in lookup) {
|
10722
|
+
// These don't raise exceptions but can cause warnings
|
10723
|
+
if (prop === "parent" || prop === "top" || prop === "frameElement") { continue; }
|
10592
10724
|
|
10593
|
-
|
10594
|
-
|
10595
|
-
|
10725
|
+
// get(window.globalStorage, 'isNamespace') would try to read the storage for domain isNamespace and cause exception in Firefox.
|
10726
|
+
// globalStorage is a storage obsoleted by the WhatWG storage specification. See https://developer.mozilla.org/en/DOM/Storage#globalStorage
|
10727
|
+
if (prop === "globalStorage" && lookup.StorageList && lookup.globalStorage instanceof lookup.StorageList) { continue; }
|
10728
|
+
// Unfortunately, some versions of IE don't support window.hasOwnProperty
|
10729
|
+
if (lookup.hasOwnProperty && !lookup.hasOwnProperty(prop)) { continue; }
|
10596
10730
|
|
10597
|
-
|
10598
|
-
|
10599
|
-
|
10600
|
-
|
10731
|
+
// At times we are not allowed to access certain properties for security reasons.
|
10732
|
+
// There are also times where even if we can access them, we are not allowed to access their properties.
|
10733
|
+
try {
|
10734
|
+
obj = Ember.lookup[prop];
|
10735
|
+
isNamespace = obj && obj.isNamespace;
|
10736
|
+
} catch (e) {
|
10737
|
+
continue;
|
10601
10738
|
}
|
10602
10739
|
|
10603
|
-
|
10740
|
+
if (isNamespace) {
|
10741
|
+
Ember.deprecate("Namespaces should not begin with lowercase.", /^[A-Z]/.test(prop));
|
10742
|
+
obj[NAME_KEY] = prop;
|
10743
|
+
}
|
10744
|
+
}
|
10745
|
+
}
|
10604
10746
|
|
10605
|
-
|
10606
|
-
Ember.propertyDidChange(this, 'lastObject');
|
10607
|
-
this.enumerableContentDidChange(len, 0);
|
10747
|
+
var NAME_KEY = Ember.NAME_KEY = Ember.GUID_KEY + '_name';
|
10608
10748
|
|
10609
|
-
|
10610
|
-
|
10749
|
+
function superClassString(mixin) {
|
10750
|
+
var superclass = mixin.superclass;
|
10751
|
+
if (superclass) {
|
10752
|
+
if (superclass[NAME_KEY]) { return superclass[NAME_KEY]; }
|
10753
|
+
else { return superClassString(superclass); }
|
10754
|
+
} else {
|
10755
|
+
return;
|
10756
|
+
}
|
10757
|
+
}
|
10611
10758
|
|
10612
|
-
|
10613
|
-
|
10614
|
-
|
10759
|
+
function classToString() {
|
10760
|
+
if (!Ember.BOOTED && !this[NAME_KEY]) {
|
10761
|
+
processAllNamespaces();
|
10762
|
+
}
|
10615
10763
|
|
10616
|
-
|
10617
|
-
var colors = ["red", "green", "blue"],
|
10618
|
-
same_colors = new Ember.Set(colors);
|
10764
|
+
var ret;
|
10619
10765
|
|
10620
|
-
|
10621
|
-
|
10622
|
-
|
10766
|
+
if (this[NAME_KEY]) {
|
10767
|
+
ret = this[NAME_KEY];
|
10768
|
+
} else {
|
10769
|
+
var str = superClassString(this);
|
10770
|
+
if (str) {
|
10771
|
+
ret = "(subclass of " + str + ")";
|
10772
|
+
} else {
|
10773
|
+
ret = "(unknown mixin)";
|
10774
|
+
}
|
10775
|
+
this.toString = makeToString(ret);
|
10776
|
+
}
|
10623
10777
|
|
10624
|
-
|
10625
|
-
|
10626
|
-
@return {Boolean}
|
10627
|
-
*/
|
10628
|
-
isEqual: function(obj) {
|
10629
|
-
// fail fast
|
10630
|
-
if (!Ember.Enumerable.detect(obj)) return false;
|
10778
|
+
return ret;
|
10779
|
+
}
|
10631
10780
|
|
10632
|
-
|
10633
|
-
|
10781
|
+
function processAllNamespaces() {
|
10782
|
+
var unprocessedNamespaces = !Namespace.PROCESSED,
|
10783
|
+
unprocessedMixins = Ember.anyUnprocessedMixins;
|
10634
10784
|
|
10635
|
-
|
10636
|
-
|
10785
|
+
if (unprocessedNamespaces) {
|
10786
|
+
findNamespaces();
|
10787
|
+
Namespace.PROCESSED = true;
|
10788
|
+
}
|
10789
|
+
|
10790
|
+
if (unprocessedNamespaces || unprocessedMixins) {
|
10791
|
+
var namespaces = Namespace.NAMESPACES, namespace;
|
10792
|
+
for (var i=0, l=namespaces.length; i<l; i++) {
|
10793
|
+
namespace = namespaces[i];
|
10794
|
+
processNamespace([namespace.toString()], namespace, {});
|
10637
10795
|
}
|
10638
10796
|
|
10639
|
-
|
10640
|
-
}
|
10797
|
+
Ember.anyUnprocessedMixins = false;
|
10798
|
+
}
|
10799
|
+
}
|
10641
10800
|
|
10642
|
-
|
10643
|
-
|
10644
|
-
|
10645
|
-
the passed value is null this method will have no effect.
|
10801
|
+
function makeToString(ret) {
|
10802
|
+
return function() { return ret; };
|
10803
|
+
}
|
10646
10804
|
|
10647
|
-
|
10805
|
+
Ember.Mixin.prototype.toString = classToString;
|
10648
10806
|
|
10649
|
-
|
10650
|
-
var colors = new Ember.Set();
|
10651
|
-
colors.add("blue"); // ["blue"]
|
10652
|
-
colors.add("blue"); // ["blue"]
|
10653
|
-
colors.add("red"); // ["blue", "red"]
|
10654
|
-
colors.add(null); // ["blue", "red"]
|
10655
|
-
colors.add(undefined); // ["blue", "red"]
|
10656
|
-
```
|
10807
|
+
})();
|
10657
10808
|
|
10658
|
-
@method add
|
10659
|
-
@param {Object} obj The object to add.
|
10660
|
-
@return {Ember.Set} The set itself.
|
10661
|
-
*/
|
10662
|
-
add: Ember.aliasMethod('addObject'),
|
10663
10809
|
|
10664
|
-
/**
|
10665
|
-
Removes the object from the set if it is found. If you pass a `null` value
|
10666
|
-
or an object that is already not in the set, this method will have no
|
10667
|
-
effect. This is an alias for `Ember.MutableEnumerable.removeObject()`.
|
10668
10810
|
|
10669
|
-
|
10670
|
-
|
10671
|
-
colors.remove("red"); // ["blue", "green"]
|
10672
|
-
colors.remove("purple"); // ["blue", "green"]
|
10673
|
-
colors.remove(null); // ["blue", "green"]
|
10674
|
-
```
|
10811
|
+
(function() {
|
10812
|
+
Ember.Application = Ember.Namespace.extend();
|
10675
10813
|
|
10676
|
-
|
10677
|
-
@param {Object} obj The object to remove
|
10678
|
-
@return {Ember.Set} The set itself.
|
10679
|
-
*/
|
10680
|
-
remove: Ember.aliasMethod('removeObject'),
|
10814
|
+
})();
|
10681
10815
|
|
10682
|
-
/**
|
10683
|
-
Removes the last element from the set and returns it, or `null` if it's empty.
|
10684
10816
|
|
10685
|
-
```javascript
|
10686
|
-
var colors = new Ember.Set(["green", "blue"]);
|
10687
|
-
colors.pop(); // "blue"
|
10688
|
-
colors.pop(); // "green"
|
10689
|
-
colors.pop(); // null
|
10690
|
-
```
|
10691
10817
|
|
10692
|
-
|
10693
|
-
|
10694
|
-
|
10695
|
-
|
10696
|
-
|
10697
|
-
var obj = this.length > 0 ? this[this.length-1] : null;
|
10698
|
-
this.remove(obj);
|
10699
|
-
return obj;
|
10700
|
-
},
|
10818
|
+
(function() {
|
10819
|
+
/**
|
10820
|
+
@module ember
|
10821
|
+
@submodule ember-runtime
|
10822
|
+
*/
|
10701
10823
|
|
10702
|
-
|
10703
|
-
|
10704
|
-
the set itself.
|
10824
|
+
var OUT_OF_RANGE_EXCEPTION = "Index out of range";
|
10825
|
+
var EMPTY = [];
|
10705
10826
|
|
10706
|
-
|
10827
|
+
var get = Ember.get, set = Ember.set;
|
10707
10828
|
|
10708
|
-
|
10709
|
-
|
10710
|
-
|
10711
|
-
|
10712
|
-
|
10713
|
-
```
|
10829
|
+
/**
|
10830
|
+
An ArrayProxy wraps any other object that implements `Ember.Array` and/or
|
10831
|
+
`Ember.MutableArray,` forwarding all requests. This makes it very useful for
|
10832
|
+
a number of binding use cases or other cases where being able to swap
|
10833
|
+
out the underlying array is useful.
|
10714
10834
|
|
10715
|
-
|
10716
|
-
@return {Ember.Set} The set itself.
|
10717
|
-
*/
|
10718
|
-
push: Ember.aliasMethod('addObject'),
|
10835
|
+
A simple example of usage:
|
10719
10836
|
|
10720
|
-
|
10721
|
-
|
10837
|
+
```javascript
|
10838
|
+
var pets = ['dog', 'cat', 'fish'];
|
10839
|
+
var ap = Ember.ArrayProxy.create({ content: Ember.A(pets) });
|
10722
10840
|
|
10723
|
-
|
10841
|
+
ap.get('firstObject'); // 'dog'
|
10842
|
+
ap.set('content', ['amoeba', 'paramecium']);
|
10843
|
+
ap.get('firstObject'); // 'amoeba'
|
10844
|
+
```
|
10724
10845
|
|
10725
|
-
|
10726
|
-
|
10727
|
-
|
10728
|
-
colors.shift(); // "green"
|
10729
|
-
colors.shift(); // null
|
10730
|
-
```
|
10846
|
+
This class can also be useful as a layer to transform the contents of
|
10847
|
+
an array, as they are accessed. This can be done by overriding
|
10848
|
+
`objectAtContent`:
|
10731
10849
|
|
10732
|
-
|
10733
|
-
|
10734
|
-
|
10735
|
-
|
10850
|
+
```javascript
|
10851
|
+
var pets = ['dog', 'cat', 'fish'];
|
10852
|
+
var ap = Ember.ArrayProxy.create({
|
10853
|
+
content: Ember.A(pets),
|
10854
|
+
objectAtContent: function(idx) {
|
10855
|
+
return this.get('content').objectAt(idx).toUpperCase();
|
10856
|
+
}
|
10857
|
+
});
|
10736
10858
|
|
10737
|
-
|
10738
|
-
|
10739
|
-
the set itself.
|
10859
|
+
ap.get('firstObject'); // . 'DOG'
|
10860
|
+
```
|
10740
10861
|
|
10741
|
-
|
10862
|
+
@class ArrayProxy
|
10863
|
+
@namespace Ember
|
10864
|
+
@extends Ember.Object
|
10865
|
+
@uses Ember.MutableArray
|
10866
|
+
*/
|
10867
|
+
Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,
|
10868
|
+
/** @scope Ember.ArrayProxy.prototype */ {
|
10742
10869
|
|
10743
|
-
|
10744
|
-
|
10745
|
-
|
10746
|
-
colors.unshift("green"); // ["red", "green"]
|
10747
|
-
colors.unshift("blue"); // ["red", "green", "blue"]
|
10748
|
-
```
|
10870
|
+
/**
|
10871
|
+
The content array. Must be an object that implements `Ember.Array` and/or
|
10872
|
+
`Ember.MutableArray.`
|
10749
10873
|
|
10750
|
-
@
|
10751
|
-
@
|
10874
|
+
@property content
|
10875
|
+
@type Ember.Array
|
10752
10876
|
*/
|
10753
|
-
|
10877
|
+
content: null,
|
10754
10878
|
|
10755
10879
|
/**
|
10756
|
-
|
10757
|
-
|
10758
|
-
|
10759
|
-
|
10760
|
-
```javascript
|
10761
|
-
var colors = new Ember.Set();
|
10762
|
-
colors.addEach(["red", "green", "blue"]); // ["red", "green", "blue"]
|
10763
|
-
```
|
10880
|
+
The array that the proxy pretends to be. In the default `ArrayProxy`
|
10881
|
+
implementation, this and `content` are the same. Subclasses of `ArrayProxy`
|
10882
|
+
can override this property to provide things like sorting and filtering.
|
10764
10883
|
|
10765
|
-
|
10766
|
-
@param {Ember.Enumerable} objects the objects to add.
|
10767
|
-
@return {Ember.Set} The set itself.
|
10884
|
+
@property arrangedContent
|
10768
10885
|
*/
|
10769
|
-
|
10886
|
+
arrangedContent: Ember.computed.alias('content'),
|
10770
10887
|
|
10771
10888
|
/**
|
10772
|
-
|
10773
|
-
|
10774
|
-
|
10889
|
+
Should actually retrieve the object at the specified index from the
|
10890
|
+
content. You can override this method in subclasses to transform the
|
10891
|
+
content item to something new.
|
10775
10892
|
|
10776
|
-
|
10777
|
-
var colors = new Ember.Set(["red", "green", "blue"]);
|
10778
|
-
colors.removeEach(["red", "blue"]); // ["green"]
|
10779
|
-
```
|
10893
|
+
This method will only be called if content is non-`null`.
|
10780
10894
|
|
10781
|
-
@method
|
10782
|
-
@param {
|
10783
|
-
@return {
|
10895
|
+
@method objectAtContent
|
10896
|
+
@param {Number} idx The index to retrieve.
|
10897
|
+
@return {Object} the value or undefined if none found
|
10784
10898
|
*/
|
10785
|
-
|
10899
|
+
objectAtContent: function(idx) {
|
10900
|
+
return get(this, 'arrangedContent').objectAt(idx);
|
10901
|
+
},
|
10786
10902
|
|
10787
|
-
|
10788
|
-
|
10789
|
-
|
10903
|
+
/**
|
10904
|
+
Should actually replace the specified objects on the content array.
|
10905
|
+
You can override this method in subclasses to transform the content item
|
10906
|
+
into something new.
|
10790
10907
|
|
10791
|
-
|
10792
|
-
this._super();
|
10793
|
-
if (items) this.addObjects(items);
|
10794
|
-
},
|
10908
|
+
This method will only be called if content is non-`null`.
|
10795
10909
|
|
10796
|
-
|
10797
|
-
|
10798
|
-
|
10910
|
+
@method replaceContent
|
10911
|
+
@param {Number} idx The starting index
|
10912
|
+
@param {Number} amt The number of items to remove from the content.
|
10913
|
+
@param {Array} objects Optional array of objects to insert or null if no
|
10914
|
+
objects.
|
10915
|
+
@return {void}
|
10916
|
+
*/
|
10917
|
+
replaceContent: function(idx, amt, objects) {
|
10918
|
+
get(this, 'content').replace(idx, amt, objects);
|
10799
10919
|
},
|
10800
10920
|
|
10801
|
-
|
10802
|
-
|
10803
|
-
return this.length > 0 ? this[0] : undefined;
|
10804
|
-
}),
|
10921
|
+
/**
|
10922
|
+
@private
|
10805
10923
|
|
10806
|
-
|
10807
|
-
|
10808
|
-
return this.length > 0 ? this[this.length-1] : undefined;
|
10809
|
-
}),
|
10924
|
+
Invoked when the content property is about to change. Notifies observers that the
|
10925
|
+
entire array content will change.
|
10810
10926
|
|
10811
|
-
|
10812
|
-
|
10813
|
-
|
10814
|
-
|
10927
|
+
@method _contentWillChange
|
10928
|
+
*/
|
10929
|
+
_contentWillChange: Ember.beforeObserver(function() {
|
10930
|
+
this._teardownContent();
|
10931
|
+
}, 'content'),
|
10815
10932
|
|
10816
|
-
|
10817
|
-
|
10818
|
-
len = get(this, 'length'),
|
10819
|
-
added ;
|
10933
|
+
_teardownContent: function() {
|
10934
|
+
var content = get(this, 'content');
|
10820
10935
|
|
10821
|
-
if (
|
10936
|
+
if (content) {
|
10937
|
+
content.removeArrayObserver(this, {
|
10938
|
+
willChange: 'contentArrayWillChange',
|
10939
|
+
didChange: 'contentArrayDidChange'
|
10940
|
+
});
|
10941
|
+
}
|
10942
|
+
},
|
10822
10943
|
|
10823
|
-
|
10944
|
+
contentArrayWillChange: Ember.K,
|
10945
|
+
contentArrayDidChange: Ember.K,
|
10824
10946
|
|
10825
|
-
|
10826
|
-
|
10947
|
+
/**
|
10948
|
+
@private
|
10827
10949
|
|
10828
|
-
|
10829
|
-
|
10830
|
-
this[len] = obj;
|
10831
|
-
set(this, 'length', len+1);
|
10950
|
+
Invoked when the content property changes. Notifies observers that the
|
10951
|
+
entire array content has changed.
|
10832
10952
|
|
10833
|
-
|
10834
|
-
|
10953
|
+
@method _contentDidChange
|
10954
|
+
*/
|
10955
|
+
_contentDidChange: Ember.observer(function() {
|
10956
|
+
var content = get(this, 'content');
|
10835
10957
|
|
10836
|
-
|
10958
|
+
Ember.assert("Can't set ArrayProxy's content to itself", content !== this);
|
10959
|
+
|
10960
|
+
this._setupContent();
|
10961
|
+
}, 'content'),
|
10962
|
+
|
10963
|
+
_setupContent: function() {
|
10964
|
+
var content = get(this, 'content');
|
10965
|
+
|
10966
|
+
if (content) {
|
10967
|
+
content.addArrayObserver(this, {
|
10968
|
+
willChange: 'contentArrayWillChange',
|
10969
|
+
didChange: 'contentArrayDidChange'
|
10970
|
+
});
|
10971
|
+
}
|
10837
10972
|
},
|
10838
10973
|
|
10839
|
-
|
10840
|
-
|
10841
|
-
|
10842
|
-
if (none(obj)) return this; // nothing to do
|
10974
|
+
_arrangedContentWillChange: Ember.beforeObserver(function() {
|
10975
|
+
var arrangedContent = get(this, 'arrangedContent'),
|
10976
|
+
len = arrangedContent ? get(arrangedContent, 'length') : 0;
|
10843
10977
|
|
10844
|
-
|
10845
|
-
|
10846
|
-
len = get(this, 'length'),
|
10847
|
-
isFirst = idx === 0,
|
10848
|
-
isLast = idx === len-1,
|
10849
|
-
last, removed;
|
10978
|
+
this.arrangedContentArrayWillChange(this, 0, len, undefined);
|
10979
|
+
this.arrangedContentWillChange(this);
|
10850
10980
|
|
10981
|
+
this._teardownArrangedContent(arrangedContent);
|
10982
|
+
}, 'arrangedContent'),
|
10851
10983
|
|
10852
|
-
|
10853
|
-
|
10984
|
+
_arrangedContentDidChange: Ember.observer(function() {
|
10985
|
+
var arrangedContent = get(this, 'arrangedContent'),
|
10986
|
+
len = arrangedContent ? get(arrangedContent, 'length') : 0;
|
10854
10987
|
|
10855
|
-
|
10856
|
-
if (isFirst) { Ember.propertyWillChange(this, 'firstObject'); }
|
10857
|
-
if (isLast) { Ember.propertyWillChange(this, 'lastObject'); }
|
10988
|
+
Ember.assert("Can't set ArrayProxy's content to itself", arrangedContent !== this);
|
10858
10989
|
|
10859
|
-
|
10860
|
-
if (idx < len-1) {
|
10861
|
-
last = this[len-1];
|
10862
|
-
this[idx] = last;
|
10863
|
-
this[guidFor(last)] = idx;
|
10864
|
-
}
|
10990
|
+
this._setupArrangedContent();
|
10865
10991
|
|
10866
|
-
|
10867
|
-
|
10868
|
-
|
10992
|
+
this.arrangedContentDidChange(this);
|
10993
|
+
this.arrangedContentArrayDidChange(this, 0, undefined, len);
|
10994
|
+
}, 'arrangedContent'),
|
10869
10995
|
|
10870
|
-
|
10871
|
-
|
10872
|
-
this.enumerableContentDidChange(removed, null);
|
10873
|
-
}
|
10996
|
+
_setupArrangedContent: function() {
|
10997
|
+
var arrangedContent = get(this, 'arrangedContent');
|
10874
10998
|
|
10875
|
-
|
10999
|
+
if (arrangedContent) {
|
11000
|
+
arrangedContent.addArrayObserver(this, {
|
11001
|
+
willChange: 'arrangedContentArrayWillChange',
|
11002
|
+
didChange: 'arrangedContentArrayDidChange'
|
11003
|
+
});
|
11004
|
+
}
|
10876
11005
|
},
|
10877
11006
|
|
10878
|
-
|
10879
|
-
|
10880
|
-
return this[guidFor(obj)]>=0;
|
10881
|
-
},
|
11007
|
+
_teardownArrangedContent: function() {
|
11008
|
+
var arrangedContent = get(this, 'arrangedContent');
|
10882
11009
|
|
10883
|
-
|
10884
|
-
|
10885
|
-
|
10886
|
-
|
10887
|
-
|
10888
|
-
ret[guidFor(this[loc])] = loc;
|
11010
|
+
if (arrangedContent) {
|
11011
|
+
arrangedContent.removeArrayObserver(this, {
|
11012
|
+
willChange: 'arrangedContentArrayWillChange',
|
11013
|
+
didChange: 'arrangedContentArrayDidChange'
|
11014
|
+
});
|
10889
11015
|
}
|
10890
|
-
return ret;
|
10891
11016
|
},
|
10892
11017
|
|
10893
|
-
|
10894
|
-
|
10895
|
-
for(idx = 0; idx < len; idx++) {
|
10896
|
-
array[idx] = this[idx];
|
10897
|
-
}
|
10898
|
-
return "Ember.Set<%@>".fmt(array.join(','));
|
10899
|
-
}
|
11018
|
+
arrangedContentWillChange: Ember.K,
|
11019
|
+
arrangedContentDidChange: Ember.K,
|
10900
11020
|
|
10901
|
-
|
11021
|
+
objectAt: function(idx) {
|
11022
|
+
return get(this, 'content') && this.objectAtContent(idx);
|
11023
|
+
},
|
10902
11024
|
|
10903
|
-
|
11025
|
+
length: Ember.computed(function() {
|
11026
|
+
var arrangedContent = get(this, 'arrangedContent');
|
11027
|
+
return arrangedContent ? get(arrangedContent, 'length') : 0;
|
11028
|
+
// No dependencies since Enumerable notifies length of change
|
11029
|
+
}),
|
10904
11030
|
|
11031
|
+
_replace: function(idx, amt, objects) {
|
11032
|
+
var content = get(this, 'content');
|
11033
|
+
Ember.assert('The content property of '+ this.constructor + ' should be set before modifying it', content);
|
11034
|
+
if (content) this.replaceContent(idx, amt, objects);
|
11035
|
+
return this;
|
11036
|
+
},
|
10905
11037
|
|
11038
|
+
replace: function() {
|
11039
|
+
if (get(this, 'arrangedContent') === get(this, 'content')) {
|
11040
|
+
this._replace.apply(this, arguments);
|
11041
|
+
} else {
|
11042
|
+
throw new Ember.Error("Using replace on an arranged ArrayProxy is not allowed.");
|
11043
|
+
}
|
11044
|
+
},
|
10906
11045
|
|
10907
|
-
|
10908
|
-
|
10909
|
-
|
10910
|
-
|
10911
|
-
|
11046
|
+
_insertAt: function(idx, object) {
|
11047
|
+
if (idx > get(this, 'content.length')) throw new Error(OUT_OF_RANGE_EXCEPTION);
|
11048
|
+
this._replace(idx, 0, [object]);
|
11049
|
+
return this;
|
11050
|
+
},
|
10912
11051
|
|
10913
|
-
|
10914
|
-
|
10915
|
-
|
10916
|
-
|
11052
|
+
insertAt: function(idx, object) {
|
11053
|
+
if (get(this, 'arrangedContent') === get(this, 'content')) {
|
11054
|
+
return this._insertAt(idx, object);
|
11055
|
+
} else {
|
11056
|
+
throw new Ember.Error("Using insertAt on an arranged ArrayProxy is not allowed.");
|
11057
|
+
}
|
11058
|
+
},
|
10917
11059
|
|
10918
|
-
|
10919
|
-
|
10920
|
-
|
10921
|
-
|
10922
|
-
|
10923
|
-
Ember.Object = Ember.CoreObject.extend(Ember.Observable);
|
10924
|
-
Ember.Object.toString = function() { return "Ember.Object"; };
|
11060
|
+
removeAt: function(start, len) {
|
11061
|
+
if ('number' === typeof start) {
|
11062
|
+
var content = get(this, 'content'),
|
11063
|
+
arrangedContent = get(this, 'arrangedContent'),
|
11064
|
+
indices = [], i;
|
10925
11065
|
|
10926
|
-
|
11066
|
+
if ((start < 0) || (start >= get(this, 'length'))) {
|
11067
|
+
throw new Error(OUT_OF_RANGE_EXCEPTION);
|
11068
|
+
}
|
10927
11069
|
|
11070
|
+
if (len === undefined) len = 1;
|
10928
11071
|
|
11072
|
+
// Get a list of indices in original content to remove
|
11073
|
+
for (i=start; i<start+len; i++) {
|
11074
|
+
// Use arrangedContent here so we avoid confusion with objects transformed by objectAtContent
|
11075
|
+
indices.push(content.indexOf(arrangedContent.objectAt(i)));
|
11076
|
+
}
|
10929
11077
|
|
10930
|
-
|
10931
|
-
|
10932
|
-
@module ember
|
10933
|
-
@submodule ember-runtime
|
10934
|
-
*/
|
11078
|
+
// Replace in reverse order since indices will change
|
11079
|
+
indices.sort(function(a,b) { return b - a; });
|
10935
11080
|
|
10936
|
-
|
11081
|
+
Ember.beginPropertyChanges();
|
11082
|
+
for (i=0; i<indices.length; i++) {
|
11083
|
+
this._replace(indices[i], 1, EMPTY);
|
11084
|
+
}
|
11085
|
+
Ember.endPropertyChanges();
|
11086
|
+
}
|
10937
11087
|
|
10938
|
-
|
10939
|
-
|
10940
|
-
such as an application or framework. Create a namespace anytime you want
|
10941
|
-
to define one of these new containers.
|
11088
|
+
return this ;
|
11089
|
+
},
|
10942
11090
|
|
10943
|
-
|
11091
|
+
pushObject: function(obj) {
|
11092
|
+
this._insertAt(get(this, 'content.length'), obj) ;
|
11093
|
+
return obj ;
|
11094
|
+
},
|
10944
11095
|
|
10945
|
-
|
10946
|
-
|
10947
|
-
|
10948
|
-
}
|
10949
|
-
```
|
11096
|
+
pushObjects: function(objects) {
|
11097
|
+
this._replace(get(this, 'length'), 0, objects);
|
11098
|
+
return this;
|
11099
|
+
},
|
10950
11100
|
|
10951
|
-
|
10952
|
-
|
10953
|
-
@extends Ember.Object
|
10954
|
-
*/
|
10955
|
-
var Namespace = Ember.Namespace = Ember.Object.extend({
|
10956
|
-
isNamespace: true,
|
11101
|
+
setObjects: function(objects) {
|
11102
|
+
if (objects.length === 0) return this.clear();
|
10957
11103
|
|
10958
|
-
|
10959
|
-
|
10960
|
-
|
11104
|
+
var len = get(this, 'length');
|
11105
|
+
this._replace(0, len, objects);
|
11106
|
+
return this;
|
10961
11107
|
},
|
10962
11108
|
|
10963
|
-
|
10964
|
-
|
10965
|
-
|
11109
|
+
unshiftObject: function(obj) {
|
11110
|
+
this._insertAt(0, obj) ;
|
11111
|
+
return obj ;
|
11112
|
+
},
|
10966
11113
|
|
10967
|
-
|
10968
|
-
|
11114
|
+
unshiftObjects: function(objects) {
|
11115
|
+
this._replace(0, 0, objects);
|
11116
|
+
return this;
|
10969
11117
|
},
|
10970
11118
|
|
10971
|
-
|
10972
|
-
|
11119
|
+
slice: function() {
|
11120
|
+
var arr = this.toArray();
|
11121
|
+
return arr.slice.apply(arr, arguments);
|
10973
11122
|
},
|
10974
11123
|
|
10975
|
-
|
10976
|
-
|
10977
|
-
|
10978
|
-
|
11124
|
+
arrangedContentArrayWillChange: function(item, idx, removedCnt, addedCnt) {
|
11125
|
+
this.arrayContentWillChange(idx, removedCnt, addedCnt);
|
11126
|
+
},
|
11127
|
+
|
11128
|
+
arrangedContentArrayDidChange: function(item, idx, removedCnt, addedCnt) {
|
11129
|
+
this.arrayContentDidChange(idx, removedCnt, addedCnt);
|
11130
|
+
},
|
11131
|
+
|
11132
|
+
init: function() {
|
10979
11133
|
this._super();
|
11134
|
+
this._setupContent();
|
11135
|
+
this._setupArrangedContent();
|
11136
|
+
},
|
11137
|
+
|
11138
|
+
willDestroy: function() {
|
11139
|
+
this._teardownArrangedContent();
|
11140
|
+
this._teardownContent();
|
10980
11141
|
}
|
10981
11142
|
});
|
10982
11143
|
|
10983
|
-
Namespace.reopenClass({
|
10984
|
-
NAMESPACES: [Ember],
|
10985
|
-
NAMESPACES_BY_ID: {},
|
10986
|
-
PROCESSED: false,
|
10987
|
-
processAll: processAllNamespaces,
|
10988
|
-
byName: function(name) {
|
10989
|
-
if (!Ember.BOOTED) {
|
10990
|
-
processAllNamespaces();
|
10991
|
-
}
|
10992
|
-
|
10993
|
-
return NAMESPACES_BY_ID[name];
|
10994
|
-
}
|
10995
|
-
});
|
10996
|
-
|
10997
|
-
var NAMESPACES_BY_ID = Namespace.NAMESPACES_BY_ID;
|
10998
|
-
|
10999
|
-
var hasOwnProp = ({}).hasOwnProperty,
|
11000
|
-
guidFor = Ember.guidFor;
|
11001
|
-
|
11002
|
-
function processNamespace(paths, root, seen) {
|
11003
|
-
var idx = paths.length;
|
11004
11144
|
|
11005
|
-
|
11145
|
+
})();
|
11006
11146
|
|
11007
|
-
// Loop over all of the keys in the namespace, looking for classes
|
11008
|
-
for(var key in root) {
|
11009
|
-
if (!hasOwnProp.call(root, key)) { continue; }
|
11010
|
-
var obj = root[key];
|
11011
11147
|
|
11012
|
-
// If we are processing the `Ember` namespace, for example, the
|
11013
|
-
// `paths` will start with `["Ember"]`. Every iteration through
|
11014
|
-
// the loop will update the **second** element of this list with
|
11015
|
-
// the key, so processing `Ember.View` will make the Array
|
11016
|
-
// `['Ember', 'View']`.
|
11017
|
-
paths[idx] = key;
|
11018
11148
|
|
11019
|
-
|
11020
|
-
|
11021
|
-
|
11022
|
-
|
11023
|
-
|
11024
|
-
obj[NAME_KEY] = paths.join('.');
|
11149
|
+
(function() {
|
11150
|
+
/**
|
11151
|
+
@module ember
|
11152
|
+
@submodule ember-runtime
|
11153
|
+
*/
|
11025
11154
|
|
11026
|
-
|
11027
|
-
|
11028
|
-
|
11029
|
-
|
11030
|
-
|
11155
|
+
var get = Ember.get,
|
11156
|
+
set = Ember.set,
|
11157
|
+
fmt = Ember.String.fmt,
|
11158
|
+
addBeforeObserver = Ember.addBeforeObserver,
|
11159
|
+
addObserver = Ember.addObserver,
|
11160
|
+
removeBeforeObserver = Ember.removeBeforeObserver,
|
11161
|
+
removeObserver = Ember.removeObserver,
|
11162
|
+
propertyWillChange = Ember.propertyWillChange,
|
11163
|
+
propertyDidChange = Ember.propertyDidChange;
|
11031
11164
|
|
11032
|
-
|
11033
|
-
|
11034
|
-
|
11035
|
-
|
11165
|
+
function contentPropertyWillChange(content, contentKey) {
|
11166
|
+
var key = contentKey.slice(8); // remove "content."
|
11167
|
+
if (key in this) { return; } // if shadowed in proxy
|
11168
|
+
propertyWillChange(this, key);
|
11169
|
+
}
|
11036
11170
|
|
11037
|
-
|
11171
|
+
function contentPropertyDidChange(content, contentKey) {
|
11172
|
+
var key = contentKey.slice(8); // remove "content."
|
11173
|
+
if (key in this) { return; } // if shadowed in proxy
|
11174
|
+
propertyDidChange(this, key);
|
11038
11175
|
}
|
11039
11176
|
|
11040
|
-
|
11041
|
-
|
11177
|
+
/**
|
11178
|
+
`Ember.ObjectProxy` forwards all properties not defined by the proxy itself
|
11179
|
+
to a proxied `content` object.
|
11042
11180
|
|
11043
|
-
|
11181
|
+
```javascript
|
11182
|
+
object = Ember.Object.create({
|
11183
|
+
name: 'Foo'
|
11184
|
+
});
|
11044
11185
|
|
11045
|
-
|
11046
|
-
|
11047
|
-
|
11186
|
+
proxy = Ember.ObjectProxy.create({
|
11187
|
+
content: object
|
11188
|
+
});
|
11048
11189
|
|
11049
|
-
|
11050
|
-
|
11051
|
-
|
11052
|
-
|
11053
|
-
if (lookup.hasOwnProperty && !lookup.hasOwnProperty(prop)) { continue; }
|
11190
|
+
// Access and change existing properties
|
11191
|
+
proxy.get('name') // 'Foo'
|
11192
|
+
proxy.set('name', 'Bar');
|
11193
|
+
object.get('name') // 'Bar'
|
11054
11194
|
|
11055
|
-
|
11056
|
-
|
11057
|
-
|
11058
|
-
|
11059
|
-
isNamespace = obj && obj.isNamespace;
|
11060
|
-
} catch (e) {
|
11061
|
-
continue;
|
11062
|
-
}
|
11195
|
+
// Create new 'description' property on `object`
|
11196
|
+
proxy.set('description', 'Foo is a whizboo baz');
|
11197
|
+
object.get('description') // 'Foo is a whizboo baz'
|
11198
|
+
```
|
11063
11199
|
|
11064
|
-
|
11065
|
-
|
11066
|
-
obj[NAME_KEY] = prop;
|
11067
|
-
}
|
11068
|
-
}
|
11069
|
-
}
|
11200
|
+
While `content` is unset, setting a property to be delegated will throw an
|
11201
|
+
Error.
|
11070
11202
|
|
11071
|
-
|
11203
|
+
```javascript
|
11204
|
+
proxy = Ember.ObjectProxy.create({
|
11205
|
+
content: null,
|
11206
|
+
flag: null
|
11207
|
+
});
|
11208
|
+
proxy.set('flag', true);
|
11209
|
+
proxy.get('flag'); // true
|
11210
|
+
proxy.get('foo'); // undefined
|
11211
|
+
proxy.set('foo', 'data'); // throws Error
|
11212
|
+
```
|
11072
11213
|
|
11073
|
-
|
11074
|
-
var superclass = mixin.superclass;
|
11075
|
-
if (superclass) {
|
11076
|
-
if (superclass[NAME_KEY]) { return superclass[NAME_KEY]; }
|
11077
|
-
else { return superClassString(superclass); }
|
11078
|
-
} else {
|
11079
|
-
return;
|
11080
|
-
}
|
11081
|
-
}
|
11214
|
+
Delegated properties can be bound to and will change when content is updated.
|
11082
11215
|
|
11083
|
-
|
11084
|
-
if (!Ember.BOOTED && !this[NAME_KEY]) {
|
11085
|
-
processAllNamespaces();
|
11086
|
-
}
|
11216
|
+
Computed properties on the proxy itself can depend on delegated properties.
|
11087
11217
|
|
11088
|
-
|
11218
|
+
```javascript
|
11219
|
+
ProxyWithComputedProperty = Ember.ObjectProxy.extend({
|
11220
|
+
fullName: function () {
|
11221
|
+
var firstName = this.get('firstName'),
|
11222
|
+
lastName = this.get('lastName');
|
11223
|
+
if (firstName && lastName) {
|
11224
|
+
return firstName + ' ' + lastName;
|
11225
|
+
}
|
11226
|
+
return firstName || lastName;
|
11227
|
+
}.property('firstName', 'lastName')
|
11228
|
+
});
|
11089
11229
|
|
11090
|
-
|
11091
|
-
ret = this[NAME_KEY];
|
11092
|
-
} else {
|
11093
|
-
var str = superClassString(this);
|
11094
|
-
if (str) {
|
11095
|
-
ret = "(subclass of " + str + ")";
|
11096
|
-
} else {
|
11097
|
-
ret = "(unknown mixin)";
|
11098
|
-
}
|
11099
|
-
this.toString = makeToString(ret);
|
11100
|
-
}
|
11230
|
+
proxy = ProxyWithComputedProperty.create();
|
11101
11231
|
|
11102
|
-
|
11103
|
-
|
11232
|
+
proxy.get('fullName'); // undefined
|
11233
|
+
proxy.set('content', {
|
11234
|
+
firstName: 'Tom', lastName: 'Dale'
|
11235
|
+
}); // triggers property change for fullName on proxy
|
11104
11236
|
|
11105
|
-
|
11106
|
-
|
11107
|
-
unprocessedMixins = Ember.anyUnprocessedMixins;
|
11237
|
+
proxy.get('fullName'); // 'Tom Dale'
|
11238
|
+
```
|
11108
11239
|
|
11109
|
-
|
11110
|
-
|
11111
|
-
|
11112
|
-
|
11240
|
+
@class ObjectProxy
|
11241
|
+
@namespace Ember
|
11242
|
+
@extends Ember.Object
|
11243
|
+
*/
|
11244
|
+
Ember.ObjectProxy = Ember.Object.extend(
|
11245
|
+
/** @scope Ember.ObjectProxy.prototype */ {
|
11246
|
+
/**
|
11247
|
+
The object whose properties will be forwarded.
|
11113
11248
|
|
11114
|
-
|
11115
|
-
|
11116
|
-
|
11117
|
-
|
11118
|
-
|
11119
|
-
|
11249
|
+
@property content
|
11250
|
+
@type Ember.Object
|
11251
|
+
@default null
|
11252
|
+
*/
|
11253
|
+
content: null,
|
11254
|
+
_contentDidChange: Ember.observer(function() {
|
11255
|
+
Ember.assert("Can't set ObjectProxy's content to itself", this.get('content') !== this);
|
11256
|
+
}, 'content'),
|
11120
11257
|
|
11121
|
-
|
11122
|
-
}
|
11123
|
-
}
|
11258
|
+
isTruthy: Ember.computed.bool('content'),
|
11124
11259
|
|
11125
|
-
|
11126
|
-
return function() { return ret; };
|
11127
|
-
}
|
11260
|
+
_debugContainerKey: null,
|
11128
11261
|
|
11129
|
-
|
11262
|
+
willWatchProperty: function (key) {
|
11263
|
+
var contentKey = 'content.' + key;
|
11264
|
+
addBeforeObserver(this, contentKey, null, contentPropertyWillChange);
|
11265
|
+
addObserver(this, contentKey, null, contentPropertyDidChange);
|
11266
|
+
},
|
11130
11267
|
|
11131
|
-
|
11268
|
+
didUnwatchProperty: function (key) {
|
11269
|
+
var contentKey = 'content.' + key;
|
11270
|
+
removeBeforeObserver(this, contentKey, null, contentPropertyWillChange);
|
11271
|
+
removeObserver(this, contentKey, null, contentPropertyDidChange);
|
11272
|
+
},
|
11132
11273
|
|
11274
|
+
unknownProperty: function (key) {
|
11275
|
+
var content = get(this, 'content');
|
11276
|
+
if (content) {
|
11277
|
+
return get(content, key);
|
11278
|
+
}
|
11279
|
+
},
|
11133
11280
|
|
11281
|
+
setUnknownProperty: function (key, value) {
|
11282
|
+
var content = get(this, 'content');
|
11283
|
+
Ember.assert(fmt("Cannot delegate set('%@', %@) to the 'content' property of object proxy %@: its 'content' is undefined.", [key, value, this]), content);
|
11284
|
+
return set(content, key, value);
|
11285
|
+
}
|
11286
|
+
});
|
11134
11287
|
|
11135
|
-
(
|
11136
|
-
|
11288
|
+
Ember.ObjectProxy.reopenClass({
|
11289
|
+
create: function () {
|
11290
|
+
var mixin, prototype, i, l, properties, keyName;
|
11291
|
+
if (arguments.length) {
|
11292
|
+
prototype = this.proto();
|
11293
|
+
for (i = 0, l = arguments.length; i < l; i++) {
|
11294
|
+
properties = arguments[i];
|
11295
|
+
for (keyName in properties) {
|
11296
|
+
if (!properties.hasOwnProperty(keyName) || keyName in prototype) { continue; }
|
11297
|
+
if (!mixin) mixin = {};
|
11298
|
+
mixin[keyName] = null;
|
11299
|
+
}
|
11300
|
+
}
|
11301
|
+
if (mixin) this._initMixins([mixin]);
|
11302
|
+
}
|
11303
|
+
return this._super.apply(this, arguments);
|
11304
|
+
}
|
11305
|
+
});
|
11137
11306
|
|
11138
11307
|
})();
|
11139
11308
|
|
@@ -11146,237 +11315,203 @@ Ember.Application = Ember.Namespace.extend();
|
|
11146
11315
|
*/
|
11147
11316
|
|
11148
11317
|
|
11149
|
-
var get = Ember.get,
|
11150
|
-
|
11151
|
-
/**
|
11152
|
-
An ArrayProxy wraps any other object that implements `Ember.Array` and/or
|
11153
|
-
`Ember.MutableArray,` forwarding all requests. This makes it very useful for
|
11154
|
-
a number of binding use cases or other cases where being able to swap
|
11155
|
-
out the underlying array is useful.
|
11318
|
+
var set = Ember.set, get = Ember.get, guidFor = Ember.guidFor;
|
11319
|
+
var forEach = Ember.EnumerableUtils.forEach;
|
11156
11320
|
|
11157
|
-
|
11321
|
+
var EachArray = Ember.Object.extend(Ember.Array, {
|
11158
11322
|
|
11159
|
-
|
11160
|
-
|
11161
|
-
|
11162
|
-
|
11163
|
-
|
11164
|
-
|
11165
|
-
ap.get('firstObject'); // 'amoeba'
|
11166
|
-
```
|
11323
|
+
init: function(content, keyName, owner) {
|
11324
|
+
this._super();
|
11325
|
+
this._keyName = keyName;
|
11326
|
+
this._owner = owner;
|
11327
|
+
this._content = content;
|
11328
|
+
},
|
11167
11329
|
|
11168
|
-
|
11169
|
-
|
11170
|
-
|
11330
|
+
objectAt: function(idx) {
|
11331
|
+
var item = this._content.objectAt(idx);
|
11332
|
+
return item && get(item, this._keyName);
|
11333
|
+
},
|
11171
11334
|
|
11172
|
-
|
11173
|
-
|
11174
|
-
|
11175
|
-
|
11176
|
-
objectAtContent: function(idx) {
|
11177
|
-
return this.get('content').objectAt(idx).toUpperCase();
|
11178
|
-
}
|
11179
|
-
});
|
11335
|
+
length: Ember.computed(function() {
|
11336
|
+
var content = this._content;
|
11337
|
+
return content ? get(content, 'length') : 0;
|
11338
|
+
})
|
11180
11339
|
|
11181
|
-
|
11182
|
-
```
|
11340
|
+
});
|
11183
11341
|
|
11184
|
-
|
11185
|
-
@namespace Ember
|
11186
|
-
@extends Ember.Object
|
11187
|
-
@uses Ember.MutableArray
|
11188
|
-
*/
|
11189
|
-
Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,
|
11190
|
-
/** @scope Ember.ArrayProxy.prototype */ {
|
11342
|
+
var IS_OBSERVER = /^.+:(before|change)$/;
|
11191
11343
|
|
11192
|
-
|
11193
|
-
|
11194
|
-
|
11344
|
+
function addObserverForContentKey(content, keyName, proxy, idx, loc) {
|
11345
|
+
var objects = proxy._objects, guid;
|
11346
|
+
if (!objects) objects = proxy._objects = {};
|
11195
11347
|
|
11196
|
-
|
11197
|
-
|
11198
|
-
|
11199
|
-
|
11348
|
+
while(--loc>=idx) {
|
11349
|
+
var item = content.objectAt(loc);
|
11350
|
+
if (item) {
|
11351
|
+
Ember.addBeforeObserver(item, keyName, proxy, 'contentKeyWillChange');
|
11352
|
+
Ember.addObserver(item, keyName, proxy, 'contentKeyDidChange');
|
11200
11353
|
|
11201
|
-
|
11202
|
-
|
11203
|
-
|
11204
|
-
|
11354
|
+
// keep track of the index each item was found at so we can map
|
11355
|
+
// it back when the obj changes.
|
11356
|
+
guid = guidFor(item);
|
11357
|
+
if (!objects[guid]) objects[guid] = [];
|
11358
|
+
objects[guid].push(loc);
|
11359
|
+
}
|
11360
|
+
}
|
11361
|
+
}
|
11205
11362
|
|
11206
|
-
|
11207
|
-
|
11208
|
-
|
11363
|
+
function removeObserverForContentKey(content, keyName, proxy, idx, loc) {
|
11364
|
+
var objects = proxy._objects;
|
11365
|
+
if (!objects) objects = proxy._objects = {};
|
11366
|
+
var indicies, guid;
|
11209
11367
|
|
11210
|
-
|
11211
|
-
|
11212
|
-
|
11213
|
-
|
11368
|
+
while(--loc>=idx) {
|
11369
|
+
var item = content.objectAt(loc);
|
11370
|
+
if (item) {
|
11371
|
+
Ember.removeBeforeObserver(item, keyName, proxy, 'contentKeyWillChange');
|
11372
|
+
Ember.removeObserver(item, keyName, proxy, 'contentKeyDidChange');
|
11214
11373
|
|
11215
|
-
|
11374
|
+
guid = guidFor(item);
|
11375
|
+
indicies = objects[guid];
|
11376
|
+
indicies[indicies.indexOf(loc)] = null;
|
11377
|
+
}
|
11378
|
+
}
|
11379
|
+
}
|
11216
11380
|
|
11217
|
-
|
11218
|
-
|
11219
|
-
|
11220
|
-
|
11221
|
-
objectAtContent: function(idx) {
|
11222
|
-
return get(this, 'arrangedContent').objectAt(idx);
|
11223
|
-
},
|
11381
|
+
/**
|
11382
|
+
This is the object instance returned when you get the `@each` property on an
|
11383
|
+
array. It uses the unknownProperty handler to automatically create
|
11384
|
+
EachArray instances for property names.
|
11224
11385
|
|
11225
|
-
|
11226
|
-
|
11227
|
-
|
11228
|
-
|
11386
|
+
@private
|
11387
|
+
@class EachProxy
|
11388
|
+
@namespace Ember
|
11389
|
+
@extends Ember.Object
|
11390
|
+
*/
|
11391
|
+
Ember.EachProxy = Ember.Object.extend({
|
11229
11392
|
|
11230
|
-
|
11393
|
+
init: function(content) {
|
11394
|
+
this._super();
|
11395
|
+
this._content = content;
|
11396
|
+
content.addArrayObserver(this);
|
11231
11397
|
|
11232
|
-
|
11233
|
-
|
11234
|
-
|
11235
|
-
|
11236
|
-
|
11237
|
-
@return {void}
|
11238
|
-
*/
|
11239
|
-
replaceContent: function(idx, amt, objects) {
|
11240
|
-
get(this, 'content').replace(idx, amt, objects);
|
11398
|
+
// in case someone is already observing some keys make sure they are
|
11399
|
+
// added
|
11400
|
+
forEach(Ember.watchedEvents(this), function(eventName) {
|
11401
|
+
this.didAddListener(eventName);
|
11402
|
+
}, this);
|
11241
11403
|
},
|
11242
11404
|
|
11243
11405
|
/**
|
11244
|
-
|
11245
|
-
|
11246
|
-
Invoked when the content property is about to change. Notifies observers that the
|
11247
|
-
entire array content will change.
|
11406
|
+
You can directly access mapped properties by simply requesting them.
|
11407
|
+
The `unknownProperty` handler will generate an EachArray of each item.
|
11248
11408
|
|
11249
|
-
@method
|
11409
|
+
@method unknownProperty
|
11410
|
+
@param keyName {String}
|
11411
|
+
@param value {anything}
|
11250
11412
|
*/
|
11251
|
-
|
11252
|
-
|
11253
|
-
|
11254
|
-
|
11255
|
-
|
11256
|
-
|
11257
|
-
|
11258
|
-
if (content) {
|
11259
|
-
content.removeArrayObserver(this, {
|
11260
|
-
willChange: 'contentArrayWillChange',
|
11261
|
-
didChange: 'contentArrayDidChange'
|
11262
|
-
});
|
11263
|
-
}
|
11413
|
+
unknownProperty: function(keyName, value) {
|
11414
|
+
var ret;
|
11415
|
+
ret = new EachArray(this._content, keyName, this);
|
11416
|
+
Ember.defineProperty(this, keyName, null, ret);
|
11417
|
+
this.beginObservingContentKey(keyName);
|
11418
|
+
return ret;
|
11264
11419
|
},
|
11265
11420
|
|
11266
|
-
|
11267
|
-
|
11268
|
-
|
11269
|
-
/**
|
11270
|
-
@private
|
11271
|
-
|
11272
|
-
Invoked when the content property changes. Notifies observers that the
|
11273
|
-
entire array content has changed.
|
11421
|
+
// ..........................................................
|
11422
|
+
// ARRAY CHANGES
|
11423
|
+
// Invokes whenever the content array itself changes.
|
11274
11424
|
|
11275
|
-
|
11276
|
-
|
11277
|
-
_contentDidChange: Ember.observer(function() {
|
11278
|
-
var content = get(this, 'content');
|
11425
|
+
arrayWillChange: function(content, idx, removedCnt, addedCnt) {
|
11426
|
+
var keys = this._keys, key, lim;
|
11279
11427
|
|
11280
|
-
|
11428
|
+
lim = removedCnt>0 ? idx+removedCnt : -1;
|
11429
|
+
Ember.beginPropertyChanges(this);
|
11281
11430
|
|
11282
|
-
|
11283
|
-
|
11431
|
+
for(key in keys) {
|
11432
|
+
if (!keys.hasOwnProperty(key)) { continue; }
|
11284
11433
|
|
11285
|
-
|
11286
|
-
var content = get(this, 'content');
|
11434
|
+
if (lim>0) removeObserverForContentKey(content, key, this, idx, lim);
|
11287
11435
|
|
11288
|
-
|
11289
|
-
content.addArrayObserver(this, {
|
11290
|
-
willChange: 'contentArrayWillChange',
|
11291
|
-
didChange: 'contentArrayDidChange'
|
11292
|
-
});
|
11436
|
+
Ember.propertyWillChange(this, key);
|
11293
11437
|
}
|
11294
|
-
},
|
11295
11438
|
|
11296
|
-
|
11297
|
-
|
11298
|
-
|
11439
|
+
Ember.propertyWillChange(this._content, '@each');
|
11440
|
+
Ember.endPropertyChanges(this);
|
11441
|
+
},
|
11299
11442
|
|
11300
|
-
|
11301
|
-
this.
|
11443
|
+
arrayDidChange: function(content, idx, removedCnt, addedCnt) {
|
11444
|
+
var keys = this._keys, key, lim;
|
11302
11445
|
|
11303
|
-
|
11304
|
-
|
11446
|
+
lim = addedCnt>0 ? idx+addedCnt : -1;
|
11447
|
+
Ember.beginPropertyChanges(this);
|
11305
11448
|
|
11306
|
-
|
11307
|
-
|
11308
|
-
len = arrangedContent ? get(arrangedContent, 'length') : 0;
|
11449
|
+
for(key in keys) {
|
11450
|
+
if (!keys.hasOwnProperty(key)) { continue; }
|
11309
11451
|
|
11310
|
-
|
11452
|
+
if (lim>0) addObserverForContentKey(content, key, this, idx, lim);
|
11311
11453
|
|
11312
|
-
|
11454
|
+
Ember.propertyDidChange(this, key);
|
11455
|
+
}
|
11313
11456
|
|
11314
|
-
|
11315
|
-
|
11316
|
-
},
|
11457
|
+
Ember.propertyDidChange(this._content, '@each');
|
11458
|
+
Ember.endPropertyChanges(this);
|
11459
|
+
},
|
11317
11460
|
|
11318
|
-
|
11319
|
-
|
11461
|
+
// ..........................................................
|
11462
|
+
// LISTEN FOR NEW OBSERVERS AND OTHER EVENT LISTENERS
|
11463
|
+
// Start monitoring keys based on who is listening...
|
11320
11464
|
|
11321
|
-
|
11322
|
-
|
11323
|
-
|
11324
|
-
didChange: 'arrangedContentArrayDidChange'
|
11325
|
-
});
|
11465
|
+
didAddListener: function(eventName) {
|
11466
|
+
if (IS_OBSERVER.test(eventName)) {
|
11467
|
+
this.beginObservingContentKey(eventName.slice(0, -7));
|
11326
11468
|
}
|
11327
11469
|
},
|
11328
11470
|
|
11329
|
-
|
11330
|
-
|
11331
|
-
|
11332
|
-
if (arrangedContent) {
|
11333
|
-
arrangedContent.removeArrayObserver(this, {
|
11334
|
-
willChange: 'arrangedContentArrayWillChange',
|
11335
|
-
didChange: 'arrangedContentArrayDidChange'
|
11336
|
-
});
|
11471
|
+
didRemoveListener: function(eventName) {
|
11472
|
+
if (IS_OBSERVER.test(eventName)) {
|
11473
|
+
this.stopObservingContentKey(eventName.slice(0, -7));
|
11337
11474
|
}
|
11338
11475
|
},
|
11339
11476
|
|
11340
|
-
|
11341
|
-
|
11342
|
-
|
11343
|
-
objectAt: function(idx) {
|
11344
|
-
return get(this, 'content') && this.objectAtContent(idx);
|
11345
|
-
},
|
11477
|
+
// ..........................................................
|
11478
|
+
// CONTENT KEY OBSERVING
|
11479
|
+
// Actual watch keys on the source content.
|
11346
11480
|
|
11347
|
-
|
11348
|
-
var
|
11349
|
-
|
11350
|
-
|
11351
|
-
|
11352
|
-
|
11353
|
-
|
11354
|
-
|
11355
|
-
|
11356
|
-
|
11357
|
-
|
11358
|
-
|
11359
|
-
arrangedContentArrayWillChange: function(item, idx, removedCnt, addedCnt) {
|
11360
|
-
this.arrayContentWillChange(idx, removedCnt, addedCnt);
|
11481
|
+
beginObservingContentKey: function(keyName) {
|
11482
|
+
var keys = this._keys;
|
11483
|
+
if (!keys) keys = this._keys = {};
|
11484
|
+
if (!keys[keyName]) {
|
11485
|
+
keys[keyName] = 1;
|
11486
|
+
var content = this._content,
|
11487
|
+
len = get(content, 'length');
|
11488
|
+
addObserverForContentKey(content, keyName, this, 0, len);
|
11489
|
+
} else {
|
11490
|
+
keys[keyName]++;
|
11491
|
+
}
|
11361
11492
|
},
|
11362
11493
|
|
11363
|
-
|
11364
|
-
this.
|
11494
|
+
stopObservingContentKey: function(keyName) {
|
11495
|
+
var keys = this._keys;
|
11496
|
+
if (keys && (keys[keyName]>0) && (--keys[keyName]<=0)) {
|
11497
|
+
var content = this._content,
|
11498
|
+
len = get(content, 'length');
|
11499
|
+
removeObserverForContentKey(content, keyName, this, 0, len);
|
11500
|
+
}
|
11365
11501
|
},
|
11366
11502
|
|
11367
|
-
|
11368
|
-
|
11369
|
-
this._setupContent();
|
11370
|
-
this._setupArrangedContent();
|
11503
|
+
contentKeyWillChange: function(obj, keyName) {
|
11504
|
+
Ember.propertyWillChange(this, keyName);
|
11371
11505
|
},
|
11372
11506
|
|
11373
|
-
|
11374
|
-
|
11375
|
-
this._teardownContent();
|
11507
|
+
contentKeyDidChange: function(obj, keyName) {
|
11508
|
+
Ember.propertyDidChange(this, keyName);
|
11376
11509
|
}
|
11510
|
+
|
11377
11511
|
});
|
11378
11512
|
|
11379
11513
|
|
11514
|
+
|
11380
11515
|
})();
|
11381
11516
|
|
11382
11517
|
|
@@ -11387,505 +11522,611 @@ Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,
|
|
11387
11522
|
@submodule ember-runtime
|
11388
11523
|
*/
|
11389
11524
|
|
11390
|
-
var get = Ember.get,
|
11391
|
-
set = Ember.set,
|
11392
|
-
fmt = Ember.String.fmt,
|
11393
|
-
addBeforeObserver = Ember.addBeforeObserver,
|
11394
|
-
addObserver = Ember.addObserver,
|
11395
|
-
removeBeforeObserver = Ember.removeBeforeObserver,
|
11396
|
-
removeObserver = Ember.removeObserver,
|
11397
|
-
propertyWillChange = Ember.propertyWillChange,
|
11398
|
-
propertyDidChange = Ember.propertyDidChange;
|
11399
|
-
|
11400
|
-
function contentPropertyWillChange(content, contentKey) {
|
11401
|
-
var key = contentKey.slice(8); // remove "content."
|
11402
|
-
if (key in this) { return; } // if shadowed in proxy
|
11403
|
-
propertyWillChange(this, key);
|
11404
|
-
}
|
11405
|
-
|
11406
|
-
function contentPropertyDidChange(content, contentKey) {
|
11407
|
-
var key = contentKey.slice(8); // remove "content."
|
11408
|
-
if (key in this) { return; } // if shadowed in proxy
|
11409
|
-
propertyDidChange(this, key);
|
11410
|
-
}
|
11411
|
-
|
11412
|
-
/**
|
11413
|
-
`Ember.ObjectProxy` forwards all properties not defined by the proxy itself
|
11414
|
-
to a proxied `content` object.
|
11415
|
-
|
11416
|
-
```javascript
|
11417
|
-
object = Ember.Object.create({
|
11418
|
-
name: 'Foo'
|
11419
|
-
});
|
11420
|
-
|
11421
|
-
proxy = Ember.ObjectProxy.create({
|
11422
|
-
content: object
|
11423
|
-
});
|
11424
11525
|
|
11425
|
-
|
11426
|
-
proxy.get('name') // 'Foo'
|
11427
|
-
proxy.set('name', 'Bar');
|
11428
|
-
object.get('name') // 'Bar'
|
11526
|
+
var get = Ember.get, set = Ember.set;
|
11429
11527
|
|
11430
|
-
|
11431
|
-
|
11432
|
-
|
11433
|
-
|
11528
|
+
// Add Ember.Array to Array.prototype. Remove methods with native
|
11529
|
+
// implementations and supply some more optimized versions of generic methods
|
11530
|
+
// because they are so common.
|
11531
|
+
var NativeArray = Ember.Mixin.create(Ember.MutableArray, Ember.Observable, Ember.Copyable, {
|
11434
11532
|
|
11435
|
-
|
11436
|
-
|
11533
|
+
// because length is a built-in property we need to know to just get the
|
11534
|
+
// original property.
|
11535
|
+
get: function(key) {
|
11536
|
+
if (key==='length') return this.length;
|
11537
|
+
else if ('number' === typeof key) return this[key];
|
11538
|
+
else return this._super(key);
|
11539
|
+
},
|
11437
11540
|
|
11438
|
-
|
11439
|
-
|
11440
|
-
|
11441
|
-
flag: null
|
11442
|
-
});
|
11443
|
-
proxy.set('flag', true);
|
11444
|
-
proxy.get('flag'); // true
|
11445
|
-
proxy.get('foo'); // undefined
|
11446
|
-
proxy.set('foo', 'data'); // throws Error
|
11447
|
-
```
|
11541
|
+
objectAt: function(idx) {
|
11542
|
+
return this[idx];
|
11543
|
+
},
|
11448
11544
|
|
11449
|
-
|
11545
|
+
// primitive for array support.
|
11546
|
+
replace: function(idx, amt, objects) {
|
11450
11547
|
|
11451
|
-
|
11548
|
+
if (this.isFrozen) throw Ember.FROZEN_ERROR ;
|
11452
11549
|
|
11453
|
-
|
11454
|
-
|
11455
|
-
|
11456
|
-
|
11457
|
-
|
11458
|
-
if (firstName && lastName) {
|
11459
|
-
return firstName + ' ' + lastName;
|
11460
|
-
}
|
11461
|
-
return firstName || lastName;
|
11462
|
-
}.property('firstName', 'lastName')
|
11463
|
-
});
|
11550
|
+
// if we replaced exactly the same number of items, then pass only the
|
11551
|
+
// replaced range. Otherwise, pass the full remaining array length
|
11552
|
+
// since everything has shifted
|
11553
|
+
var len = objects ? get(objects, 'length') : 0;
|
11554
|
+
this.arrayContentWillChange(idx, amt, len);
|
11464
11555
|
|
11465
|
-
|
11556
|
+
if (!objects || objects.length === 0) {
|
11557
|
+
this.splice(idx, amt) ;
|
11558
|
+
} else {
|
11559
|
+
var args = [idx, amt].concat(objects) ;
|
11560
|
+
this.splice.apply(this,args) ;
|
11561
|
+
}
|
11466
11562
|
|
11467
|
-
|
11468
|
-
|
11469
|
-
|
11470
|
-
}); // triggers property change for fullName on proxy
|
11563
|
+
this.arrayContentDidChange(idx, amt, len);
|
11564
|
+
return this ;
|
11565
|
+
},
|
11471
11566
|
|
11472
|
-
|
11473
|
-
|
11567
|
+
// If you ask for an unknown property, then try to collect the value
|
11568
|
+
// from member items.
|
11569
|
+
unknownProperty: function(key, value) {
|
11570
|
+
var ret;// = this.reducedProperty(key, value) ;
|
11571
|
+
if ((value !== undefined) && ret === undefined) {
|
11572
|
+
ret = this[key] = value;
|
11573
|
+
}
|
11574
|
+
return ret ;
|
11575
|
+
},
|
11474
11576
|
|
11475
|
-
|
11476
|
-
|
11477
|
-
|
11478
|
-
|
11479
|
-
Ember.ObjectProxy = Ember.Object.extend(
|
11480
|
-
/** @scope Ember.ObjectProxy.prototype */ {
|
11481
|
-
/**
|
11482
|
-
The object whose properties will be forwarded.
|
11577
|
+
// If browser did not implement indexOf natively, then override with
|
11578
|
+
// specialized version
|
11579
|
+
indexOf: function(object, startAt) {
|
11580
|
+
var idx, len = this.length;
|
11483
11581
|
|
11484
|
-
|
11485
|
-
|
11486
|
-
|
11487
|
-
*/
|
11488
|
-
content: null,
|
11489
|
-
_contentDidChange: Ember.observer(function() {
|
11490
|
-
Ember.assert("Can't set ObjectProxy's content to itself", this.get('content') !== this);
|
11491
|
-
}, 'content'),
|
11582
|
+
if (startAt === undefined) startAt = 0;
|
11583
|
+
else startAt = (startAt < 0) ? Math.ceil(startAt) : Math.floor(startAt);
|
11584
|
+
if (startAt < 0) startAt += len;
|
11492
11585
|
|
11493
|
-
|
11586
|
+
for(idx=startAt;idx<len;idx++) {
|
11587
|
+
if (this[idx] === object) return idx ;
|
11588
|
+
}
|
11589
|
+
return -1;
|
11590
|
+
},
|
11494
11591
|
|
11495
|
-
|
11592
|
+
lastIndexOf: function(object, startAt) {
|
11593
|
+
var idx, len = this.length;
|
11496
11594
|
|
11497
|
-
|
11498
|
-
|
11499
|
-
|
11500
|
-
addObserver(this, contentKey, null, contentPropertyDidChange);
|
11501
|
-
},
|
11595
|
+
if (startAt === undefined) startAt = len-1;
|
11596
|
+
else startAt = (startAt < 0) ? Math.ceil(startAt) : Math.floor(startAt);
|
11597
|
+
if (startAt < 0) startAt += len;
|
11502
11598
|
|
11503
|
-
|
11504
|
-
|
11505
|
-
|
11506
|
-
|
11599
|
+
for(idx=startAt;idx>=0;idx--) {
|
11600
|
+
if (this[idx] === object) return idx ;
|
11601
|
+
}
|
11602
|
+
return -1;
|
11507
11603
|
},
|
11508
11604
|
|
11509
|
-
|
11510
|
-
|
11511
|
-
|
11512
|
-
return get(content, key);
|
11605
|
+
copy: function(deep) {
|
11606
|
+
if (deep) {
|
11607
|
+
return this.map(function(item){ return Ember.copy(item, true); });
|
11513
11608
|
}
|
11514
|
-
},
|
11515
11609
|
|
11516
|
-
|
11517
|
-
var content = get(this, 'content');
|
11518
|
-
Ember.assert(fmt("Cannot delegate set('%@', %@) to the 'content' property of object proxy %@: its 'content' is undefined.", [key, value, this]), content);
|
11519
|
-
return set(content, key, value);
|
11610
|
+
return this.slice();
|
11520
11611
|
}
|
11521
11612
|
});
|
11522
11613
|
|
11523
|
-
|
11524
|
-
|
11614
|
+
// Remove any methods implemented natively so we don't override them
|
11615
|
+
var ignore = ['length'];
|
11616
|
+
Ember.EnumerableUtils.forEach(NativeArray.keys(), function(methodName) {
|
11617
|
+
if (Array.prototype[methodName]) ignore.push(methodName);
|
11618
|
+
});
|
11525
11619
|
|
11620
|
+
if (ignore.length>0) {
|
11621
|
+
NativeArray = NativeArray.without.apply(NativeArray, ignore);
|
11622
|
+
}
|
11526
11623
|
|
11527
|
-
(function() {
|
11528
11624
|
/**
|
11529
|
-
|
11530
|
-
|
11531
|
-
|
11532
|
-
|
11625
|
+
The NativeArray mixin contains the properties needed to to make the native
|
11626
|
+
Array support Ember.MutableArray and all of its dependent APIs. Unless you
|
11627
|
+
have `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Array` set to
|
11628
|
+
false, this will be applied automatically. Otherwise you can apply the mixin
|
11629
|
+
at anytime by calling `Ember.NativeArray.activate`.
|
11533
11630
|
|
11534
|
-
|
11535
|
-
|
11631
|
+
@class NativeArray
|
11632
|
+
@namespace Ember
|
11633
|
+
@extends Ember.Mixin
|
11634
|
+
@uses Ember.MutableArray
|
11635
|
+
@uses Ember.MutableEnumerable
|
11636
|
+
@uses Ember.Copyable
|
11637
|
+
@uses Ember.Freezable
|
11638
|
+
*/
|
11639
|
+
Ember.NativeArray = NativeArray;
|
11536
11640
|
|
11537
|
-
|
11641
|
+
/**
|
11642
|
+
Creates an `Ember.NativeArray` from an Array like object.
|
11643
|
+
Does not modify the original object.
|
11538
11644
|
|
11539
|
-
|
11540
|
-
|
11541
|
-
|
11542
|
-
|
11543
|
-
|
11544
|
-
}
|
11645
|
+
@method A
|
11646
|
+
@for Ember
|
11647
|
+
@return {Ember.NativeArray}
|
11648
|
+
*/
|
11649
|
+
Ember.A = function(arr){
|
11650
|
+
if (arr === undefined) { arr = []; }
|
11651
|
+
return Ember.Array.detect(arr) ? arr : Ember.NativeArray.apply(arr);
|
11652
|
+
};
|
11545
11653
|
|
11546
|
-
|
11547
|
-
|
11548
|
-
|
11549
|
-
},
|
11654
|
+
/**
|
11655
|
+
Activates the mixin on the Array.prototype if not already applied. Calling
|
11656
|
+
this method more than once is safe.
|
11550
11657
|
|
11551
|
-
|
11552
|
-
|
11553
|
-
|
11554
|
-
}
|
11658
|
+
@method activate
|
11659
|
+
@for Ember.NativeArray
|
11660
|
+
@static
|
11661
|
+
@return {void}
|
11662
|
+
*/
|
11663
|
+
Ember.NativeArray.activate = function() {
|
11664
|
+
NativeArray.apply(Array.prototype);
|
11555
11665
|
|
11556
|
-
|
11666
|
+
Ember.A = function(arr) { return arr || []; };
|
11667
|
+
};
|
11557
11668
|
|
11558
|
-
|
11669
|
+
if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Array) {
|
11670
|
+
Ember.NativeArray.activate();
|
11671
|
+
}
|
11559
11672
|
|
11560
|
-
function addObserverForContentKey(content, keyName, proxy, idx, loc) {
|
11561
|
-
var objects = proxy._objects, guid;
|
11562
|
-
if (!objects) objects = proxy._objects = {};
|
11563
11673
|
|
11564
|
-
|
11565
|
-
var item = content.objectAt(loc);
|
11566
|
-
if (item) {
|
11567
|
-
Ember.addBeforeObserver(item, keyName, proxy, 'contentKeyWillChange');
|
11568
|
-
Ember.addObserver(item, keyName, proxy, 'contentKeyDidChange');
|
11674
|
+
})();
|
11569
11675
|
|
11570
|
-
// keep track of the indicies each item was found at so we can map
|
11571
|
-
// it back when the obj changes.
|
11572
|
-
guid = guidFor(item);
|
11573
|
-
if (!objects[guid]) objects[guid] = [];
|
11574
|
-
objects[guid].push(loc);
|
11575
|
-
}
|
11576
|
-
}
|
11577
|
-
}
|
11578
11676
|
|
11579
|
-
function removeObserverForContentKey(content, keyName, proxy, idx, loc) {
|
11580
|
-
var objects = proxy._objects;
|
11581
|
-
if (!objects) objects = proxy._objects = {};
|
11582
|
-
var indicies, guid;
|
11583
11677
|
|
11584
|
-
|
11585
|
-
|
11586
|
-
|
11587
|
-
|
11588
|
-
|
11678
|
+
(function() {
|
11679
|
+
/**
|
11680
|
+
@module ember
|
11681
|
+
@submodule ember-runtime
|
11682
|
+
*/
|
11589
11683
|
|
11590
|
-
|
11591
|
-
indicies = objects[guid];
|
11592
|
-
indicies[indicies.indexOf(loc)] = null;
|
11593
|
-
}
|
11594
|
-
}
|
11595
|
-
}
|
11684
|
+
var get = Ember.get, set = Ember.set, guidFor = Ember.guidFor, none = Ember.isNone, fmt = Ember.String.fmt;
|
11596
11685
|
|
11597
11686
|
/**
|
11598
|
-
|
11599
|
-
array. It uses the unknownProperty handler to automatically create
|
11600
|
-
EachArray instances for property names.
|
11687
|
+
An unordered collection of objects.
|
11601
11688
|
|
11602
|
-
|
11603
|
-
|
11689
|
+
A Set works a bit like an array except that its items are not ordered. You
|
11690
|
+
can create a set to efficiently test for membership for an object. You can
|
11691
|
+
also iterate through a set just like an array, even accessing objects by
|
11692
|
+
index, however there is no guarantee as to their order.
|
11693
|
+
|
11694
|
+
All Sets are observable via the Enumerable Observer API - which works
|
11695
|
+
on any enumerable object including both Sets and Arrays.
|
11696
|
+
|
11697
|
+
## Creating a Set
|
11698
|
+
|
11699
|
+
You can create a set like you would most objects using
|
11700
|
+
`new Ember.Set()`. Most new sets you create will be empty, but you can
|
11701
|
+
also initialize the set with some content by passing an array or other
|
11702
|
+
enumerable of objects to the constructor.
|
11703
|
+
|
11704
|
+
Finally, you can pass in an existing set and the set will be copied. You
|
11705
|
+
can also create a copy of a set by calling `Ember.Set#copy()`.
|
11706
|
+
|
11707
|
+
```javascript
|
11708
|
+
// creates a new empty set
|
11709
|
+
var foundNames = new Ember.Set();
|
11710
|
+
|
11711
|
+
// creates a set with four names in it.
|
11712
|
+
var names = new Ember.Set(["Charles", "Tom", "Juan", "Alex"]); // :P
|
11713
|
+
|
11714
|
+
// creates a copy of the names set.
|
11715
|
+
var namesCopy = new Ember.Set(names);
|
11716
|
+
|
11717
|
+
// same as above.
|
11718
|
+
var anotherNamesCopy = names.copy();
|
11719
|
+
```
|
11720
|
+
|
11721
|
+
## Adding/Removing Objects
|
11722
|
+
|
11723
|
+
You generally add or remove objects from a set using `add()` or
|
11724
|
+
`remove()`. You can add any type of object including primitives such as
|
11725
|
+
numbers, strings, and booleans.
|
11726
|
+
|
11727
|
+
Unlike arrays, objects can only exist one time in a set. If you call `add()`
|
11728
|
+
on a set with the same object multiple times, the object will only be added
|
11729
|
+
once. Likewise, calling `remove()` with the same object multiple times will
|
11730
|
+
remove the object the first time and have no effect on future calls until
|
11731
|
+
you add the object to the set again.
|
11732
|
+
|
11733
|
+
NOTE: You cannot add/remove `null` or `undefined` to a set. Any attempt to do
|
11734
|
+
so will be ignored.
|
11735
|
+
|
11736
|
+
In addition to add/remove you can also call `push()`/`pop()`. Push behaves
|
11737
|
+
just like `add()` but `pop()`, unlike `remove()` will pick an arbitrary
|
11738
|
+
object, remove it and return it. This is a good way to use a set as a job
|
11739
|
+
queue when you don't care which order the jobs are executed in.
|
11740
|
+
|
11741
|
+
## Testing for an Object
|
11742
|
+
|
11743
|
+
To test for an object's presence in a set you simply call
|
11744
|
+
`Ember.Set#contains()`.
|
11745
|
+
|
11746
|
+
## Observing changes
|
11747
|
+
|
11748
|
+
When using `Ember.Set`, you can observe the `"[]"` property to be
|
11749
|
+
alerted whenever the content changes. You can also add an enumerable
|
11750
|
+
observer to the set to be notified of specific objects that are added and
|
11751
|
+
removed from the set. See `Ember.Enumerable` for more information on
|
11752
|
+
enumerables.
|
11753
|
+
|
11754
|
+
This is often unhelpful. If you are filtering sets of objects, for instance,
|
11755
|
+
it is very inefficient to re-filter all of the items each time the set
|
11756
|
+
changes. It would be better if you could just adjust the filtered set based
|
11757
|
+
on what was changed on the original set. The same issue applies to merging
|
11758
|
+
sets, as well.
|
11759
|
+
|
11760
|
+
## Other Methods
|
11761
|
+
|
11762
|
+
`Ember.Set` primary implements other mixin APIs. For a complete reference
|
11763
|
+
on the methods you will use with `Ember.Set`, please consult these mixins.
|
11764
|
+
The most useful ones will be `Ember.Enumerable` and
|
11765
|
+
`Ember.MutableEnumerable` which implement most of the common iterator
|
11766
|
+
methods you are used to on Array.
|
11767
|
+
|
11768
|
+
Note that you can also use the `Ember.Copyable` and `Ember.Freezable`
|
11769
|
+
APIs on `Ember.Set` as well. Once a set is frozen it can no longer be
|
11770
|
+
modified. The benefit of this is that when you call `frozenCopy()` on it,
|
11771
|
+
Ember will avoid making copies of the set. This allows you to write
|
11772
|
+
code that can know with certainty when the underlying set data will or
|
11773
|
+
will not be modified.
|
11774
|
+
|
11775
|
+
@class Set
|
11604
11776
|
@namespace Ember
|
11605
|
-
@extends Ember.
|
11777
|
+
@extends Ember.CoreObject
|
11778
|
+
@uses Ember.MutableEnumerable
|
11779
|
+
@uses Ember.Copyable
|
11780
|
+
@uses Ember.Freezable
|
11781
|
+
@since Ember 0.9
|
11606
11782
|
*/
|
11607
|
-
Ember.
|
11608
|
-
|
11609
|
-
init: function(content) {
|
11610
|
-
this._super();
|
11611
|
-
this._content = content;
|
11612
|
-
content.addArrayObserver(this);
|
11783
|
+
Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Ember.Freezable,
|
11784
|
+
/** @scope Ember.Set.prototype */ {
|
11613
11785
|
|
11614
|
-
|
11615
|
-
|
11616
|
-
|
11617
|
-
this.didAddListener(eventName);
|
11618
|
-
}, this);
|
11619
|
-
},
|
11786
|
+
// ..........................................................
|
11787
|
+
// IMPLEMENT ENUMERABLE APIS
|
11788
|
+
//
|
11620
11789
|
|
11621
11790
|
/**
|
11622
|
-
|
11623
|
-
The `unknownProperty` handler will generate an EachArray of each item.
|
11791
|
+
This property will change as the number of objects in the set changes.
|
11624
11792
|
|
11625
|
-
@
|
11626
|
-
@
|
11627
|
-
@
|
11793
|
+
@property length
|
11794
|
+
@type number
|
11795
|
+
@default 0
|
11628
11796
|
*/
|
11629
|
-
|
11630
|
-
var ret;
|
11631
|
-
ret = new EachArray(this._content, keyName, this);
|
11632
|
-
Ember.defineProperty(this, keyName, null, ret);
|
11633
|
-
this.beginObservingContentKey(keyName);
|
11634
|
-
return ret;
|
11635
|
-
},
|
11797
|
+
length: 0,
|
11636
11798
|
|
11637
|
-
|
11638
|
-
|
11639
|
-
|
11799
|
+
/**
|
11800
|
+
Clears the set. This is useful if you want to reuse an existing set
|
11801
|
+
without having to recreate it.
|
11640
11802
|
|
11641
|
-
|
11642
|
-
var
|
11803
|
+
```javascript
|
11804
|
+
var colors = new Ember.Set(["red", "green", "blue"]);
|
11805
|
+
colors.length; // 3
|
11806
|
+
colors.clear();
|
11807
|
+
colors.length; // 0
|
11808
|
+
```
|
11643
11809
|
|
11644
|
-
|
11645
|
-
Ember.
|
11810
|
+
@method clear
|
11811
|
+
@return {Ember.Set} An empty Set
|
11812
|
+
*/
|
11813
|
+
clear: function() {
|
11814
|
+
if (this.isFrozen) { throw new Error(Ember.FROZEN_ERROR); }
|
11646
11815
|
|
11647
|
-
|
11648
|
-
|
11816
|
+
var len = get(this, 'length');
|
11817
|
+
if (len === 0) { return this; }
|
11649
11818
|
|
11650
|
-
|
11819
|
+
var guid;
|
11651
11820
|
|
11652
|
-
|
11821
|
+
this.enumerableContentWillChange(len, 0);
|
11822
|
+
Ember.propertyWillChange(this, 'firstObject');
|
11823
|
+
Ember.propertyWillChange(this, 'lastObject');
|
11824
|
+
|
11825
|
+
for (var i=0; i < len; i++){
|
11826
|
+
guid = guidFor(this[i]);
|
11827
|
+
delete this[guid];
|
11828
|
+
delete this[i];
|
11653
11829
|
}
|
11654
11830
|
|
11655
|
-
|
11656
|
-
|
11831
|
+
set(this, 'length', 0);
|
11832
|
+
|
11833
|
+
Ember.propertyDidChange(this, 'firstObject');
|
11834
|
+
Ember.propertyDidChange(this, 'lastObject');
|
11835
|
+
this.enumerableContentDidChange(len, 0);
|
11836
|
+
|
11837
|
+
return this;
|
11657
11838
|
},
|
11658
11839
|
|
11659
|
-
|
11660
|
-
|
11840
|
+
/**
|
11841
|
+
Returns true if the passed object is also an enumerable that contains the
|
11842
|
+
same objects as the receiver.
|
11661
11843
|
|
11662
|
-
|
11663
|
-
|
11844
|
+
```javascript
|
11845
|
+
var colors = ["red", "green", "blue"],
|
11846
|
+
same_colors = new Ember.Set(colors);
|
11664
11847
|
|
11665
|
-
|
11666
|
-
|
11848
|
+
same_colors.isEqual(colors); // true
|
11849
|
+
same_colors.isEqual(["purple", "brown"]); // false
|
11850
|
+
```
|
11667
11851
|
|
11668
|
-
|
11852
|
+
@method isEqual
|
11853
|
+
@param {Ember.Set} obj the other object.
|
11854
|
+
@return {Boolean}
|
11855
|
+
*/
|
11856
|
+
isEqual: function(obj) {
|
11857
|
+
// fail fast
|
11858
|
+
if (!Ember.Enumerable.detect(obj)) return false;
|
11669
11859
|
|
11670
|
-
|
11860
|
+
var loc = get(this, 'length');
|
11861
|
+
if (get(obj, 'length') !== loc) return false;
|
11862
|
+
|
11863
|
+
while(--loc >= 0) {
|
11864
|
+
if (!obj.contains(this[loc])) return false;
|
11671
11865
|
}
|
11672
11866
|
|
11673
|
-
|
11674
|
-
Ember.endPropertyChanges(this);
|
11867
|
+
return true;
|
11675
11868
|
},
|
11676
11869
|
|
11677
|
-
|
11678
|
-
|
11679
|
-
|
11870
|
+
/**
|
11871
|
+
Adds an object to the set. Only non-`null` objects can be added to a set
|
11872
|
+
and those can only be added once. If the object is already in the set or
|
11873
|
+
the passed value is null this method will have no effect.
|
11680
11874
|
|
11681
|
-
|
11682
|
-
if (IS_OBSERVER.test(eventName)) {
|
11683
|
-
this.beginObservingContentKey(eventName.slice(0, -7));
|
11684
|
-
}
|
11685
|
-
},
|
11875
|
+
This is an alias for `Ember.MutableEnumerable.addObject()`.
|
11686
11876
|
|
11687
|
-
|
11688
|
-
|
11689
|
-
|
11690
|
-
|
11691
|
-
|
11877
|
+
```javascript
|
11878
|
+
var colors = new Ember.Set();
|
11879
|
+
colors.add("blue"); // ["blue"]
|
11880
|
+
colors.add("blue"); // ["blue"]
|
11881
|
+
colors.add("red"); // ["blue", "red"]
|
11882
|
+
colors.add(null); // ["blue", "red"]
|
11883
|
+
colors.add(undefined); // ["blue", "red"]
|
11884
|
+
```
|
11692
11885
|
|
11693
|
-
|
11694
|
-
|
11695
|
-
|
11886
|
+
@method add
|
11887
|
+
@param {Object} obj The object to add.
|
11888
|
+
@return {Ember.Set} The set itself.
|
11889
|
+
*/
|
11890
|
+
add: Ember.aliasMethod('addObject'),
|
11696
11891
|
|
11697
|
-
|
11698
|
-
|
11699
|
-
|
11700
|
-
|
11701
|
-
keys[keyName] = 1;
|
11702
|
-
var content = this._content,
|
11703
|
-
len = get(content, 'length');
|
11704
|
-
addObserverForContentKey(content, keyName, this, 0, len);
|
11705
|
-
} else {
|
11706
|
-
keys[keyName]++;
|
11707
|
-
}
|
11708
|
-
},
|
11892
|
+
/**
|
11893
|
+
Removes the object from the set if it is found. If you pass a `null` value
|
11894
|
+
or an object that is already not in the set, this method will have no
|
11895
|
+
effect. This is an alias for `Ember.MutableEnumerable.removeObject()`.
|
11709
11896
|
|
11710
|
-
|
11711
|
-
var
|
11712
|
-
|
11713
|
-
|
11714
|
-
|
11715
|
-
|
11716
|
-
|
11897
|
+
```javascript
|
11898
|
+
var colors = new Ember.Set(["red", "green", "blue"]);
|
11899
|
+
colors.remove("red"); // ["blue", "green"]
|
11900
|
+
colors.remove("purple"); // ["blue", "green"]
|
11901
|
+
colors.remove(null); // ["blue", "green"]
|
11902
|
+
```
|
11903
|
+
|
11904
|
+
@method remove
|
11905
|
+
@param {Object} obj The object to remove
|
11906
|
+
@return {Ember.Set} The set itself.
|
11907
|
+
*/
|
11908
|
+
remove: Ember.aliasMethod('removeObject'),
|
11909
|
+
|
11910
|
+
/**
|
11911
|
+
Removes the last element from the set and returns it, or `null` if it's empty.
|
11912
|
+
|
11913
|
+
```javascript
|
11914
|
+
var colors = new Ember.Set(["green", "blue"]);
|
11915
|
+
colors.pop(); // "blue"
|
11916
|
+
colors.pop(); // "green"
|
11917
|
+
colors.pop(); // null
|
11918
|
+
```
|
11919
|
+
|
11920
|
+
@method pop
|
11921
|
+
@return {Object} The removed object from the set or null.
|
11922
|
+
*/
|
11923
|
+
pop: function() {
|
11924
|
+
if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
|
11925
|
+
var obj = this.length > 0 ? this[this.length-1] : null;
|
11926
|
+
this.remove(obj);
|
11927
|
+
return obj;
|
11717
11928
|
},
|
11718
11929
|
|
11719
|
-
|
11720
|
-
|
11721
|
-
|
11930
|
+
/**
|
11931
|
+
Inserts the given object on to the end of the set. It returns
|
11932
|
+
the set itself.
|
11933
|
+
|
11934
|
+
This is an alias for `Ember.MutableEnumerable.addObject()`.
|
11935
|
+
|
11936
|
+
```javascript
|
11937
|
+
var colors = new Ember.Set();
|
11938
|
+
colors.push("red"); // ["red"]
|
11939
|
+
colors.push("green"); // ["red", "green"]
|
11940
|
+
colors.push("blue"); // ["red", "green", "blue"]
|
11941
|
+
```
|
11942
|
+
|
11943
|
+
@method push
|
11944
|
+
@return {Ember.Set} The set itself.
|
11945
|
+
*/
|
11946
|
+
push: Ember.aliasMethod('addObject'),
|
11947
|
+
|
11948
|
+
/**
|
11949
|
+
Removes the last element from the set and returns it, or `null` if it's empty.
|
11950
|
+
|
11951
|
+
This is an alias for `Ember.Set.pop()`.
|
11952
|
+
|
11953
|
+
```javascript
|
11954
|
+
var colors = new Ember.Set(["green", "blue"]);
|
11955
|
+
colors.shift(); // "blue"
|
11956
|
+
colors.shift(); // "green"
|
11957
|
+
colors.shift(); // null
|
11958
|
+
```
|
11959
|
+
|
11960
|
+
@method shift
|
11961
|
+
@return {Object} The removed object from the set or null.
|
11962
|
+
*/
|
11963
|
+
shift: Ember.aliasMethod('pop'),
|
11964
|
+
|
11965
|
+
/**
|
11966
|
+
Inserts the given object on to the end of the set. It returns
|
11967
|
+
the set itself.
|
11722
11968
|
|
11723
|
-
|
11724
|
-
Ember.propertyDidChange(this, keyName);
|
11725
|
-
}
|
11969
|
+
This is an alias of `Ember.Set.push()`
|
11726
11970
|
|
11727
|
-
|
11971
|
+
```javascript
|
11972
|
+
var colors = new Ember.Set();
|
11973
|
+
colors.unshift("red"); // ["red"]
|
11974
|
+
colors.unshift("green"); // ["red", "green"]
|
11975
|
+
colors.unshift("blue"); // ["red", "green", "blue"]
|
11976
|
+
```
|
11728
11977
|
|
11978
|
+
@method unshift
|
11979
|
+
@return {Ember.Set} The set itself.
|
11980
|
+
*/
|
11981
|
+
unshift: Ember.aliasMethod('push'),
|
11729
11982
|
|
11983
|
+
/**
|
11984
|
+
Adds each object in the passed enumerable to the set.
|
11730
11985
|
|
11731
|
-
|
11986
|
+
This is an alias of `Ember.MutableEnumerable.addObjects()`
|
11732
11987
|
|
11988
|
+
```javascript
|
11989
|
+
var colors = new Ember.Set();
|
11990
|
+
colors.addEach(["red", "green", "blue"]); // ["red", "green", "blue"]
|
11991
|
+
```
|
11733
11992
|
|
11993
|
+
@method addEach
|
11994
|
+
@param {Ember.Enumerable} objects the objects to add.
|
11995
|
+
@return {Ember.Set} The set itself.
|
11996
|
+
*/
|
11997
|
+
addEach: Ember.aliasMethod('addObjects'),
|
11734
11998
|
|
11735
|
-
|
11736
|
-
|
11737
|
-
@module ember
|
11738
|
-
@submodule ember-runtime
|
11739
|
-
*/
|
11999
|
+
/**
|
12000
|
+
Removes each object in the passed enumerable to the set.
|
11740
12001
|
|
12002
|
+
This is an alias of `Ember.MutableEnumerable.removeObjects()`
|
11741
12003
|
|
11742
|
-
|
12004
|
+
```javascript
|
12005
|
+
var colors = new Ember.Set(["red", "green", "blue"]);
|
12006
|
+
colors.removeEach(["red", "blue"]); // ["green"]
|
12007
|
+
```
|
11743
12008
|
|
11744
|
-
|
11745
|
-
|
11746
|
-
|
11747
|
-
|
12009
|
+
@method removeEach
|
12010
|
+
@param {Ember.Enumerable} objects the objects to remove.
|
12011
|
+
@return {Ember.Set} The set itself.
|
12012
|
+
*/
|
12013
|
+
removeEach: Ember.aliasMethod('removeObjects'),
|
11748
12014
|
|
11749
|
-
//
|
11750
|
-
//
|
11751
|
-
|
11752
|
-
|
11753
|
-
|
11754
|
-
|
12015
|
+
// ..........................................................
|
12016
|
+
// PRIVATE ENUMERABLE SUPPORT
|
12017
|
+
//
|
12018
|
+
|
12019
|
+
init: function(items) {
|
12020
|
+
this._super();
|
12021
|
+
if (items) this.addObjects(items);
|
11755
12022
|
},
|
11756
12023
|
|
11757
|
-
|
12024
|
+
// implement Ember.Enumerable
|
12025
|
+
nextObject: function(idx) {
|
11758
12026
|
return this[idx];
|
11759
12027
|
},
|
11760
12028
|
|
11761
|
-
//
|
11762
|
-
|
11763
|
-
|
11764
|
-
|
11765
|
-
|
11766
|
-
// if we replaced exactly the same number of items, then pass only the
|
11767
|
-
// replaced range. Otherwise, pass the full remaining array length
|
11768
|
-
// since everything has shifted
|
11769
|
-
var len = objects ? get(objects, 'length') : 0;
|
11770
|
-
this.arrayContentWillChange(idx, amt, len);
|
12029
|
+
// more optimized version
|
12030
|
+
firstObject: Ember.computed(function() {
|
12031
|
+
return this.length > 0 ? this[0] : undefined;
|
12032
|
+
}),
|
11771
12033
|
|
11772
|
-
|
11773
|
-
|
11774
|
-
|
11775
|
-
|
11776
|
-
this.splice.apply(this,args) ;
|
11777
|
-
}
|
12034
|
+
// more optimized version
|
12035
|
+
lastObject: Ember.computed(function() {
|
12036
|
+
return this.length > 0 ? this[this.length-1] : undefined;
|
12037
|
+
}),
|
11778
12038
|
|
11779
|
-
|
11780
|
-
|
11781
|
-
|
12039
|
+
// implements Ember.MutableEnumerable
|
12040
|
+
addObject: function(obj) {
|
12041
|
+
if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
|
12042
|
+
if (none(obj)) return this; // nothing to do
|
11782
12043
|
|
11783
|
-
|
11784
|
-
|
11785
|
-
|
11786
|
-
|
11787
|
-
if ((value !== undefined) && ret === undefined) {
|
11788
|
-
ret = this[key] = value;
|
11789
|
-
}
|
11790
|
-
return ret ;
|
11791
|
-
},
|
12044
|
+
var guid = guidFor(obj),
|
12045
|
+
idx = this[guid],
|
12046
|
+
len = get(this, 'length'),
|
12047
|
+
added ;
|
11792
12048
|
|
11793
|
-
|
11794
|
-
// specialized version
|
11795
|
-
indexOf: function(object, startAt) {
|
11796
|
-
var idx, len = this.length;
|
12049
|
+
if (idx>=0 && idx<len && (this[idx] === obj)) return this; // added
|
11797
12050
|
|
11798
|
-
|
11799
|
-
else startAt = (startAt < 0) ? Math.ceil(startAt) : Math.floor(startAt);
|
11800
|
-
if (startAt < 0) startAt += len;
|
12051
|
+
added = [obj];
|
11801
12052
|
|
11802
|
-
|
11803
|
-
|
11804
|
-
}
|
11805
|
-
return -1;
|
11806
|
-
},
|
12053
|
+
this.enumerableContentWillChange(null, added);
|
12054
|
+
Ember.propertyWillChange(this, 'lastObject');
|
11807
12055
|
|
11808
|
-
|
11809
|
-
|
12056
|
+
len = get(this, 'length');
|
12057
|
+
this[guid] = len;
|
12058
|
+
this[len] = obj;
|
12059
|
+
set(this, 'length', len+1);
|
11810
12060
|
|
11811
|
-
|
11812
|
-
|
11813
|
-
if (startAt < 0) startAt += len;
|
12061
|
+
Ember.propertyDidChange(this, 'lastObject');
|
12062
|
+
this.enumerableContentDidChange(null, added);
|
11814
12063
|
|
11815
|
-
|
11816
|
-
if (this[idx] === object) return idx ;
|
11817
|
-
}
|
11818
|
-
return -1;
|
12064
|
+
return this;
|
11819
12065
|
},
|
11820
12066
|
|
11821
|
-
|
11822
|
-
|
11823
|
-
|
11824
|
-
|
12067
|
+
// implements Ember.MutableEnumerable
|
12068
|
+
removeObject: function(obj) {
|
12069
|
+
if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
|
12070
|
+
if (none(obj)) return this; // nothing to do
|
11825
12071
|
|
11826
|
-
|
11827
|
-
|
11828
|
-
|
12072
|
+
var guid = guidFor(obj),
|
12073
|
+
idx = this[guid],
|
12074
|
+
len = get(this, 'length'),
|
12075
|
+
isFirst = idx === 0,
|
12076
|
+
isLast = idx === len-1,
|
12077
|
+
last, removed;
|
11829
12078
|
|
11830
|
-
// Remove any methods implemented natively so we don't override them
|
11831
|
-
var ignore = ['length'];
|
11832
|
-
Ember.EnumerableUtils.forEach(NativeArray.keys(), function(methodName) {
|
11833
|
-
if (Array.prototype[methodName]) ignore.push(methodName);
|
11834
|
-
});
|
11835
12079
|
|
11836
|
-
if (
|
11837
|
-
|
11838
|
-
}
|
12080
|
+
if (idx>=0 && idx<len && (this[idx] === obj)) {
|
12081
|
+
removed = [obj];
|
11839
12082
|
|
11840
|
-
|
11841
|
-
|
11842
|
-
|
11843
|
-
have `Ember.EXTEND_PROTOTYPES or `Ember.EXTEND_PROTOTYPES.Array` set to
|
11844
|
-
false, this will be applied automatically. Otherwise you can apply the mixin
|
11845
|
-
at anytime by calling `Ember.NativeArray.activate`.
|
12083
|
+
this.enumerableContentWillChange(removed, null);
|
12084
|
+
if (isFirst) { Ember.propertyWillChange(this, 'firstObject'); }
|
12085
|
+
if (isLast) { Ember.propertyWillChange(this, 'lastObject'); }
|
11846
12086
|
|
11847
|
-
|
11848
|
-
|
11849
|
-
|
11850
|
-
|
11851
|
-
|
11852
|
-
|
11853
|
-
@uses Ember.Freezable
|
11854
|
-
*/
|
11855
|
-
Ember.NativeArray = NativeArray;
|
12087
|
+
// swap items - basically move the item to the end so it can be removed
|
12088
|
+
if (idx < len-1) {
|
12089
|
+
last = this[len-1];
|
12090
|
+
this[idx] = last;
|
12091
|
+
this[guidFor(last)] = idx;
|
12092
|
+
}
|
11856
12093
|
|
11857
|
-
|
11858
|
-
|
11859
|
-
|
12094
|
+
delete this[guid];
|
12095
|
+
delete this[len-1];
|
12096
|
+
set(this, 'length', len-1);
|
11860
12097
|
|
11861
|
-
|
11862
|
-
|
11863
|
-
|
11864
|
-
|
11865
|
-
Ember.A = function(arr){
|
11866
|
-
if (arr === undefined) { arr = []; }
|
11867
|
-
return Ember.Array.detect(arr) ? arr : Ember.NativeArray.apply(arr);
|
11868
|
-
};
|
12098
|
+
if (isFirst) { Ember.propertyDidChange(this, 'firstObject'); }
|
12099
|
+
if (isLast) { Ember.propertyDidChange(this, 'lastObject'); }
|
12100
|
+
this.enumerableContentDidChange(removed, null);
|
12101
|
+
}
|
11869
12102
|
|
11870
|
-
|
11871
|
-
|
11872
|
-
this method more than once is safe.
|
12103
|
+
return this;
|
12104
|
+
},
|
11873
12105
|
|
11874
|
-
|
11875
|
-
|
11876
|
-
|
11877
|
-
|
11878
|
-
*/
|
11879
|
-
Ember.NativeArray.activate = function() {
|
11880
|
-
NativeArray.apply(Array.prototype);
|
12106
|
+
// optimized version
|
12107
|
+
contains: function(obj) {
|
12108
|
+
return this[guidFor(obj)]>=0;
|
12109
|
+
},
|
11881
12110
|
|
11882
|
-
|
11883
|
-
|
12111
|
+
copy: function() {
|
12112
|
+
var C = this.constructor, ret = new C(), loc = get(this, 'length');
|
12113
|
+
set(ret, 'length', loc);
|
12114
|
+
while(--loc>=0) {
|
12115
|
+
ret[loc] = this[loc];
|
12116
|
+
ret[guidFor(this[loc])] = loc;
|
12117
|
+
}
|
12118
|
+
return ret;
|
12119
|
+
},
|
11884
12120
|
|
11885
|
-
|
11886
|
-
|
11887
|
-
|
12121
|
+
toString: function() {
|
12122
|
+
var len = this.length, idx, array = [];
|
12123
|
+
for(idx = 0; idx < len; idx++) {
|
12124
|
+
array[idx] = this[idx];
|
12125
|
+
}
|
12126
|
+
return fmt("Ember.Set<%@>", [array.join(',')]);
|
12127
|
+
}
|
11888
12128
|
|
12129
|
+
});
|
11889
12130
|
|
11890
12131
|
})();
|
11891
12132
|
|
@@ -11893,7 +12134,6 @@ if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Array) {
|
|
11893
12134
|
|
11894
12135
|
(function() {
|
11895
12136
|
var DeferredMixin = Ember.DeferredMixin, // mixins/deferred
|
11896
|
-
EmberObject = Ember.Object, // system/object
|
11897
12137
|
get = Ember.get;
|
11898
12138
|
|
11899
12139
|
var Deferred = Ember.Object.extend(DeferredMixin);
|
@@ -12217,7 +12457,6 @@ Ember.SortableMixin = Ember.Mixin.create(Ember.MutableEnumerable, {
|
|
12217
12457
|
|
12218
12458
|
if (isSorted) {
|
12219
12459
|
var addedObjects = array.slice(idx, idx+addedCount);
|
12220
|
-
var arrangedContent = get(this, 'arrangedContent');
|
12221
12460
|
|
12222
12461
|
forEach(addedObjects, function(item) {
|
12223
12462
|
this.insertItemSorted(item);
|
@@ -12287,8 +12526,8 @@ Ember.SortableMixin = Ember.Mixin.create(Ember.MutableEnumerable, {
|
|
12287
12526
|
@submodule ember-runtime
|
12288
12527
|
*/
|
12289
12528
|
|
12290
|
-
var get = Ember.get, set = Ember.set,
|
12291
|
-
|
12529
|
+
var get = Ember.get, set = Ember.set, forEach = Ember.EnumerableUtils.forEach,
|
12530
|
+
replace = Ember.EnumerableUtils.replace;
|
12292
12531
|
|
12293
12532
|
/**
|
12294
12533
|
`Ember.ArrayController` provides a way for you to publish a collection of
|
@@ -12611,7 +12850,7 @@ Ember.State = Ember.Object.extend(Ember.Evented,
|
|
12611
12850
|
},
|
12612
12851
|
|
12613
12852
|
init: function() {
|
12614
|
-
var states = get(this, 'states')
|
12853
|
+
var states = get(this, 'states');
|
12615
12854
|
set(this, 'childStates', Ember.A());
|
12616
12855
|
set(this, 'eventTransitions', get(this, 'eventTransitions') || {});
|
12617
12856
|
|
@@ -12761,7 +13000,7 @@ Ember.State.reopenClass({
|
|
12761
13000
|
transitionTo: function(target) {
|
12762
13001
|
|
12763
13002
|
var transitionFunction = function(stateManager, contextOrEvent) {
|
12764
|
-
var contexts = [],
|
13003
|
+
var contexts = [],
|
12765
13004
|
Event = Ember.$ && Ember.$.Event;
|
12766
13005
|
|
12767
13006
|
if (contextOrEvent && (Event && contextOrEvent instanceof Event)) {
|