embient 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +29 -29
- data/lib/embient/version.rb +1 -1
- data/vendor/assets/javascripts/embient/ember-data.js +1457 -731
- data/vendor/assets/javascripts/embient/ember-routemanager.js +13 -17
- data/vendor/assets/javascripts/embient/ember.js +2223 -456
- data/vendor/assets/javascripts/embient/ember.min.js +5 -5
- data/vendor/assets/javascripts/embient/ember.prod.js +18594 -0
- metadata +20 -9
@@ -42,7 +42,7 @@ Ember.RouteManager = Ember.StateManager.extend({
|
|
42
42
|
|
43
43
|
You will also need to make sure that baseURI is properly configured, as
|
44
44
|
well as your server so that your routes are properly pointing to your
|
45
|
-
|
45
|
+
Ember application.
|
46
46
|
|
47
47
|
@see http://dev.w3.org/html5/spec/history.html#the-history-interface
|
48
48
|
@property
|
@@ -193,13 +193,12 @@ Ember.RouteManager = Ember.StateManager.extend({
|
|
193
193
|
},
|
194
194
|
|
195
195
|
/**
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
It registers for the hashchange event if available. If not, it creates a
|
196
|
+
Start this routemanager.
|
197
|
+
|
198
|
+
Registers for the hashchange event if available. If not, it creates a
|
200
199
|
timer that looks for location changes every 150ms.
|
201
200
|
*/
|
202
|
-
|
201
|
+
start: function() {
|
203
202
|
if(!this._didSetup) {
|
204
203
|
this._didSetup = true;
|
205
204
|
var state;
|
@@ -250,8 +249,11 @@ Ember.RouteManager = Ember.StateManager.extend({
|
|
250
249
|
}
|
251
250
|
}
|
252
251
|
},
|
253
|
-
|
254
|
-
|
252
|
+
|
253
|
+
/**
|
254
|
+
Stop this routemanager
|
255
|
+
*/
|
256
|
+
stop: function() {
|
255
257
|
if(this._didSetup) {
|
256
258
|
if(get(this, 'wantsHistory') && supportsHistory) {
|
257
259
|
jQuery(window).unbind('popstate', this.popState);
|
@@ -262,19 +264,13 @@ Ember.RouteManager = Ember.StateManager.extend({
|
|
262
264
|
clearTimeout(this._timerId);
|
263
265
|
}
|
264
266
|
}
|
267
|
+
this._didSetup = false;
|
265
268
|
}
|
266
|
-
this._super();
|
267
269
|
},
|
268
270
|
|
269
|
-
|
270
|
-
|
271
|
-
for browser location changes when created.
|
272
|
-
*/
|
273
|
-
init: function() {
|
271
|
+
destroy: function() {
|
272
|
+
this.stop();
|
274
273
|
this._super();
|
275
|
-
if(!this._didSetup) {
|
276
|
-
this.ping();
|
277
|
-
}
|
278
274
|
},
|
279
275
|
|
280
276
|
/**
|
@@ -1,4 +1,4 @@
|
|
1
|
-
(function(
|
1
|
+
(function() {
|
2
2
|
/*global __fail__*/
|
3
3
|
/**
|
4
4
|
Define an assertion that will throw an exception if the condition is not
|
@@ -31,7 +31,7 @@
|
|
31
31
|
will be executed. If the function returns false an exception will be
|
32
32
|
thrown.
|
33
33
|
*/
|
34
|
-
window.ember_assert =
|
34
|
+
window.ember_assert = function ember_assert(desc, test) {
|
35
35
|
if ('function' === typeof test) test = test()!==false;
|
36
36
|
if (!test) throw new Error("assertion failed: "+desc);
|
37
37
|
};
|
@@ -126,9 +126,9 @@ window.ember_deprecateFunc = function(message, func) {
|
|
126
126
|
};
|
127
127
|
};
|
128
128
|
|
129
|
-
})(
|
129
|
+
})();
|
130
130
|
|
131
|
-
(function(
|
131
|
+
(function() {
|
132
132
|
// lib/handlebars/base.js
|
133
133
|
var Handlebars = {};
|
134
134
|
|
@@ -367,7 +367,7 @@ parse: function parse(input) {
|
|
367
367
|
|
368
368
|
var symbol, preErrorSymbol, state, action, a, r, yyval={},p,len,newState, expected;
|
369
369
|
while (true) {
|
370
|
-
//
|
370
|
+
// retrieve state number from top of stack
|
371
371
|
state = stack[stack.length-1];
|
372
372
|
|
373
373
|
// use default actions if available
|
@@ -1723,9 +1723,9 @@ Handlebars.template = Handlebars.VM.template;
|
|
1723
1723
|
;
|
1724
1724
|
|
1725
1725
|
|
1726
|
-
})(
|
1726
|
+
})();
|
1727
1727
|
|
1728
|
-
(function(
|
1728
|
+
(function() {
|
1729
1729
|
// ==========================================================================
|
1730
1730
|
// Project: Ember Metal
|
1731
1731
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -1737,7 +1737,7 @@ if ('undefined' === typeof Ember) {
|
|
1737
1737
|
/**
|
1738
1738
|
@namespace
|
1739
1739
|
@name Ember
|
1740
|
-
@version 0.9.
|
1740
|
+
@version 0.9.6
|
1741
1741
|
|
1742
1742
|
All Ember methods and functions are defined inside of this namespace.
|
1743
1743
|
You generally should not add new properties to this namespace as it may be
|
@@ -1769,10 +1769,10 @@ if ('undefined' !== typeof window) {
|
|
1769
1769
|
/**
|
1770
1770
|
@static
|
1771
1771
|
@type String
|
1772
|
-
@default '0.9.
|
1772
|
+
@default '0.9.6'
|
1773
1773
|
@constant
|
1774
1774
|
*/
|
1775
|
-
Ember.VERSION = '0.9.
|
1775
|
+
Ember.VERSION = '0.9.6';
|
1776
1776
|
|
1777
1777
|
/**
|
1778
1778
|
@static
|
@@ -1861,9 +1861,11 @@ if ('undefined' === typeof ember_deprecateFunc) {
|
|
1861
1861
|
*/
|
1862
1862
|
Ember.Logger = window.console || { log: Ember.K, warn: Ember.K, error: Ember.K };
|
1863
1863
|
|
1864
|
-
})(
|
1864
|
+
})();
|
1865
|
+
|
1866
|
+
|
1865
1867
|
|
1866
|
-
(function(
|
1868
|
+
(function() {
|
1867
1869
|
// ==========================================================================
|
1868
1870
|
// Project: Ember Metal
|
1869
1871
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -2015,9 +2017,11 @@ if (!platform.defineProperty) {
|
|
2015
2017
|
platform.defineProperty.isSimulated = true;
|
2016
2018
|
}
|
2017
2019
|
|
2018
|
-
})(
|
2020
|
+
})();
|
2021
|
+
|
2022
|
+
|
2019
2023
|
|
2020
|
-
(function(
|
2024
|
+
(function() {
|
2021
2025
|
// ==========================================================================
|
2022
2026
|
// Project: Ember Metal
|
2023
2027
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -2318,8 +2322,6 @@ Ember.wrap = function(func, superFunc) {
|
|
2318
2322
|
};
|
2319
2323
|
|
2320
2324
|
/**
|
2321
|
-
@function
|
2322
|
-
|
2323
2325
|
Returns true if the passed object is an array or Array-like.
|
2324
2326
|
|
2325
2327
|
Ember Array Protocol:
|
@@ -2331,6 +2333,11 @@ Ember.wrap = function(func, superFunc) {
|
|
2331
2333
|
Unlike Ember.typeOf this method returns true even if the passed object is
|
2332
2334
|
not formally array but appears to be array-like (i.e. implements Ember.Array)
|
2333
2335
|
|
2336
|
+
Ember.isArray(); // false
|
2337
|
+
Ember.isArray([]); // true
|
2338
|
+
Ember.isArray( Ember.ArrayProxy.create({ content: [] }) ); // true
|
2339
|
+
|
2340
|
+
@name Ember.isArray
|
2334
2341
|
@param {Object} obj The object to test
|
2335
2342
|
@returns {Boolean}
|
2336
2343
|
*/
|
@@ -2347,6 +2354,15 @@ Ember.isArray = function(obj) {
|
|
2347
2354
|
an array or array-like, returns the object. Otherwise adds the object to
|
2348
2355
|
an array. If obj is null or undefined, returns an empty array.
|
2349
2356
|
|
2357
|
+
Ember.makeArray(); => []
|
2358
|
+
Ember.makeArray(null); => []
|
2359
|
+
Ember.makeArray(undefined); => []
|
2360
|
+
Ember.makeArray('lindsay'); => ['lindsay']
|
2361
|
+
Ember.makeArray([1,2,42]); => [1,2,42]
|
2362
|
+
|
2363
|
+
var controller = Ember.ArrayProxy.create({ content: [] });
|
2364
|
+
Ember.makeArray(controller) === controller; => true
|
2365
|
+
|
2350
2366
|
@param {Object} obj the object
|
2351
2367
|
@returns {Array}
|
2352
2368
|
*/
|
@@ -2357,9 +2373,11 @@ Ember.makeArray = function(obj) {
|
|
2357
2373
|
|
2358
2374
|
|
2359
2375
|
|
2360
|
-
})(
|
2376
|
+
})();
|
2377
|
+
|
2378
|
+
|
2361
2379
|
|
2362
|
-
(function(
|
2380
|
+
(function() {
|
2363
2381
|
// ==========================================================================
|
2364
2382
|
// Project: Ember Metal
|
2365
2383
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -2746,9 +2764,11 @@ Ember.isGlobalPath = function(path) {
|
|
2746
2764
|
return !HAS_THIS.test(path) && IS_GLOBAL.test(path);
|
2747
2765
|
};
|
2748
2766
|
|
2749
|
-
})(
|
2767
|
+
})();
|
2768
|
+
|
2750
2769
|
|
2751
|
-
|
2770
|
+
|
2771
|
+
(function() {
|
2752
2772
|
// ==========================================================================
|
2753
2773
|
// Project: Ember Metal
|
2754
2774
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -3108,7 +3128,7 @@ Ember.defineProperty = function(obj, keyName, desc, val) {
|
|
3108
3128
|
that support it, this uses the built in Object.create method. Else one is
|
3109
3129
|
simulated for you.
|
3110
3130
|
|
3111
|
-
This method is a better choice
|
3131
|
+
This method is a better choice than Object.create() because it will make
|
3112
3132
|
sure that any observers, event listeners, and computed properties are
|
3113
3133
|
inherited from the parent as well.
|
3114
3134
|
|
@@ -3157,9 +3177,11 @@ Ember.createPrototype = function(obj, props) {
|
|
3157
3177
|
return ret;
|
3158
3178
|
};
|
3159
3179
|
|
3160
|
-
})(
|
3180
|
+
})();
|
3181
|
+
|
3161
3182
|
|
3162
|
-
|
3183
|
+
|
3184
|
+
(function() {
|
3163
3185
|
// ==========================================================================
|
3164
3186
|
// Project: Ember Metal
|
3165
3187
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -3499,9 +3521,30 @@ Ember.computed = function(func) {
|
|
3499
3521
|
return cp;
|
3500
3522
|
};
|
3501
3523
|
|
3502
|
-
|
3524
|
+
/**
|
3525
|
+
Returns the cached value for a property, if one exists.
|
3526
|
+
This can be useful for peeking at the value of a computed
|
3527
|
+
property that is generated lazily, without accidentally causing
|
3528
|
+
it to be created.
|
3529
|
+
|
3530
|
+
@param {Object} obj the object whose property you want to check
|
3531
|
+
@param {String} key the name of the property whose cached value you want
|
3532
|
+
to return
|
3533
|
+
|
3534
|
+
*/
|
3535
|
+
Ember.cacheFor = function(obj, key) {
|
3536
|
+
var cache = meta(obj, false).cache;
|
3537
|
+
|
3538
|
+
if (cache && cache[key]) {
|
3539
|
+
return cache[key];
|
3540
|
+
}
|
3541
|
+
};
|
3542
|
+
|
3543
|
+
})();
|
3544
|
+
|
3503
3545
|
|
3504
|
-
|
3546
|
+
|
3547
|
+
(function() {
|
3505
3548
|
/*jshint newcap:false*/
|
3506
3549
|
|
3507
3550
|
// NOTE: There is a bug in jshint that doesn't recognize `Object()` without `new`
|
@@ -3592,6 +3635,13 @@ Ember.ArrayUtils = {
|
|
3592
3635
|
return obj.indexOf ? obj.indexOf.apply(obj, args) : arrayIndexOf.apply(obj, args);
|
3593
3636
|
},
|
3594
3637
|
|
3638
|
+
indexesOf: function(obj) {
|
3639
|
+
var args = Array.prototype.slice.call(arguments, 1);
|
3640
|
+
return args[0] === undefined ? [] : Ember.ArrayUtils.map(args[0], function(item) {
|
3641
|
+
return Ember.ArrayUtils.indexOf(obj, item);
|
3642
|
+
});
|
3643
|
+
},
|
3644
|
+
|
3595
3645
|
removeObject: function(array, item) {
|
3596
3646
|
var index = this.indexOf(array, item);
|
3597
3647
|
if (index !== -1) { array.splice(index, 1); }
|
@@ -3616,9 +3666,11 @@ if (Ember.SHIM_ES5) {
|
|
3616
3666
|
}
|
3617
3667
|
}
|
3618
3668
|
|
3619
|
-
})(
|
3669
|
+
})();
|
3670
|
+
|
3620
3671
|
|
3621
|
-
|
3672
|
+
|
3673
|
+
(function() {
|
3622
3674
|
// ==========================================================================
|
3623
3675
|
// Project: Ember Metal
|
3624
3676
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -3870,9 +3922,11 @@ Ember.notifyBeforeObservers = function(obj, keyName) {
|
|
3870
3922
|
};
|
3871
3923
|
|
3872
3924
|
|
3873
|
-
})(
|
3925
|
+
})();
|
3926
|
+
|
3927
|
+
|
3874
3928
|
|
3875
|
-
(function(
|
3929
|
+
(function() {
|
3876
3930
|
// ==========================================================================
|
3877
3931
|
// Project: Ember Metal
|
3878
3932
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -4482,9 +4536,11 @@ Ember.destroy = function (obj) {
|
|
4482
4536
|
}
|
4483
4537
|
};
|
4484
4538
|
|
4485
|
-
})(
|
4539
|
+
})();
|
4540
|
+
|
4486
4541
|
|
4487
|
-
|
4542
|
+
|
4543
|
+
(function() {
|
4488
4544
|
// ==========================================================================
|
4489
4545
|
// Project: Ember Metal
|
4490
4546
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -4698,6 +4754,7 @@ function sendEvent(obj, eventName) {
|
|
4698
4754
|
return true;
|
4699
4755
|
}
|
4700
4756
|
|
4757
|
+
/** @memberOf Ember */
|
4701
4758
|
function deferEvent(obj, eventName) {
|
4702
4759
|
var targetSet = targetSetFor(obj, eventName), actions = [], params = arguments;
|
4703
4760
|
iterateSet(targetSet, function (action) {
|
@@ -4746,9 +4803,11 @@ Ember.hasListeners = hasListeners;
|
|
4746
4803
|
Ember.watchedEvents = watchedEvents;
|
4747
4804
|
Ember.listenersFor = listenersFor;
|
4748
4805
|
Ember.deferEvent = deferEvent;
|
4749
|
-
})(
|
4806
|
+
})();
|
4750
4807
|
|
4751
|
-
|
4808
|
+
|
4809
|
+
|
4810
|
+
(function() {
|
4752
4811
|
// ==========================================================================
|
4753
4812
|
// Project: Ember Runtime
|
4754
4813
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -5179,14 +5238,17 @@ function findNamespaces() {
|
|
5179
5238
|
// get(window.globalStorage, 'isNamespace') would try to read the storage for domain isNamespace and cause exception in Firefox.
|
5180
5239
|
// globalStorage is a storage obsoleted by the WhatWG storage specification. See https://developer.mozilla.org/en/DOM/Storage#globalStorage
|
5181
5240
|
if (prop === "globalStorage" && window.StorageList && window.globalStorage instanceof window.StorageList) { continue; }
|
5182
|
-
// Don't access properties on parent window, which will throw "Access/Permission Denied" in IE/Firefox for windows on different domains
|
5183
|
-
if (prop === "parent" || prop === "top" || prop === "frameElement" || prop === "content") { continue; }
|
5184
5241
|
// Unfortunately, some versions of IE don't support window.hasOwnProperty
|
5185
5242
|
if (window.hasOwnProperty && !window.hasOwnProperty(prop)) { continue; }
|
5186
5243
|
|
5187
|
-
|
5244
|
+
try {
|
5245
|
+
obj = window[prop];
|
5246
|
+
} catch (e) {
|
5247
|
+
continue;
|
5248
|
+
}
|
5188
5249
|
|
5189
5250
|
if (obj && get(obj, 'isNamespace')) {
|
5251
|
+
ember_deprecate("Namespaces should not begin with lowercase.", /^[A-Z]/.test(prop));
|
5190
5252
|
obj[NAME_KEY] = prop;
|
5191
5253
|
}
|
5192
5254
|
}
|
@@ -5305,9 +5367,11 @@ Ember.beforeObserver = function(func) {
|
|
5305
5367
|
|
5306
5368
|
|
5307
5369
|
|
5308
|
-
})(
|
5370
|
+
})();
|
5371
|
+
|
5372
|
+
|
5309
5373
|
|
5310
|
-
(function(
|
5374
|
+
(function() {
|
5311
5375
|
// ==========================================================================
|
5312
5376
|
// Project: Ember Runtime
|
5313
5377
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -5425,7 +5489,7 @@ RunLoop.prototype = {
|
|
5425
5489
|
while (this._queues && (queue = this._queues[queueName])) {
|
5426
5490
|
this._queues[queueName] = null;
|
5427
5491
|
|
5428
|
-
// the sync phase is to allow property changes to
|
5492
|
+
// the sync phase is to allow property changes to propagate. don't
|
5429
5493
|
// invoke observers until that is finished.
|
5430
5494
|
if (queueName === 'sync') {
|
5431
5495
|
log = Ember.LOG_BINDINGS;
|
@@ -5455,7 +5519,7 @@ RunLoop.prototype = {
|
|
5455
5519
|
queue = queues[queueName];
|
5456
5520
|
|
5457
5521
|
if (queue) {
|
5458
|
-
// the sync phase is to allow property changes to
|
5522
|
+
// the sync phase is to allow property changes to propagate. don't
|
5459
5523
|
// invoke observers until that is finished.
|
5460
5524
|
if (queueName === 'sync') {
|
5461
5525
|
log = Ember.LOG_BINDINGS;
|
@@ -5489,9 +5553,14 @@ Ember.RunLoop = RunLoop;
|
|
5489
5553
|
// ..........................................................
|
5490
5554
|
// Ember.run - this is ideally the only public API the dev sees
|
5491
5555
|
//
|
5556
|
+
/**
|
5557
|
+
* @namespace Ember.run is both a function and a namespace for
|
5558
|
+
* RunLoop-related functions.
|
5559
|
+
* @name Ember.run
|
5560
|
+
*/
|
5492
5561
|
|
5493
5562
|
/**
|
5494
|
-
Runs the passed target and method inside of a
|
5563
|
+
Runs the passed target and method inside of a RunLoop, ensuring any
|
5495
5564
|
deferred actions including bindings and views updates are flushed at the
|
5496
5565
|
end.
|
5497
5566
|
|
@@ -5500,7 +5569,12 @@ Ember.RunLoop = RunLoop;
|
|
5500
5569
|
libraries or plugins, you should probably wrap all of your code inside this
|
5501
5570
|
call.
|
5502
5571
|
|
5503
|
-
|
5572
|
+
Ember.run(function(){
|
5573
|
+
// code to be execute within a RunLoop
|
5574
|
+
});
|
5575
|
+
|
5576
|
+
@name run^2
|
5577
|
+
@methodOf Ember.run
|
5504
5578
|
@param {Object} target
|
5505
5579
|
(Optional) target of method to call
|
5506
5580
|
|
@@ -5534,6 +5608,11 @@ var run = Ember.run;
|
|
5534
5608
|
be buffered until you invoke a matching call to Ember.run.end(). This is
|
5535
5609
|
an lower-level way to use a RunLoop instead of using Ember.run().
|
5536
5610
|
|
5611
|
+
Ember.run.begin();
|
5612
|
+
// code to be execute within a RunLoop
|
5613
|
+
Ember.run.end();
|
5614
|
+
|
5615
|
+
|
5537
5616
|
@returns {void}
|
5538
5617
|
*/
|
5539
5618
|
Ember.run.begin = function() {
|
@@ -5545,6 +5624,10 @@ Ember.run.begin = function() {
|
|
5545
5624
|
to flush any deferred actions. This is a lower-level way to use a RunLoop
|
5546
5625
|
instead of using Ember.run().
|
5547
5626
|
|
5627
|
+
Ember.run.begin();
|
5628
|
+
// code to be execute within a RunLoop
|
5629
|
+
Ember.run.end();
|
5630
|
+
|
5548
5631
|
@returns {void}
|
5549
5632
|
*/
|
5550
5633
|
Ember.run.end = function() {
|
@@ -5564,6 +5647,7 @@ Ember.run.end = function() {
|
|
5564
5647
|
to inspect or modify this property.
|
5565
5648
|
|
5566
5649
|
@property {String}
|
5650
|
+
@default ['sync', 'actions', 'destroy', 'timers']
|
5567
5651
|
*/
|
5568
5652
|
Ember.run.queues = ['sync', 'actions', 'destroy', 'timers'];
|
5569
5653
|
|
@@ -5577,6 +5661,18 @@ Ember.run.queues = ['sync', 'actions', 'destroy', 'timers'];
|
|
5577
5661
|
Methods will be invoked in an order matching the named queues defined in
|
5578
5662
|
the run.queues property.
|
5579
5663
|
|
5664
|
+
Ember.run.schedule('timers', this, function(){
|
5665
|
+
// this will be executed at the end of the RunLoop, when timers are run
|
5666
|
+
console.log("scheduled on timers queue");
|
5667
|
+
});
|
5668
|
+
Ember.run.schedule('sync', this, function(){
|
5669
|
+
// this will be executed at the end of the RunLoop, when bindings are synced
|
5670
|
+
console.log("scheduled on sync queue");
|
5671
|
+
});
|
5672
|
+
// Note the functions will be run in order based on the run queues order. Output would be:
|
5673
|
+
// scheduled on sync queue
|
5674
|
+
// scheduled on timers queue
|
5675
|
+
|
5580
5676
|
@param {String} queue
|
5581
5677
|
The name of the queue to schedule against. Default queues are 'sync' and
|
5582
5678
|
'actions'
|
@@ -5613,6 +5709,8 @@ function autorun() {
|
|
5613
5709
|
ensure the RunLoop always finishes. You normally do not need to call this
|
5614
5710
|
method directly. Instead use Ember.run().
|
5615
5711
|
|
5712
|
+
Ember.run.autorun();
|
5713
|
+
|
5616
5714
|
@returns {Ember.RunLoop} the new current RunLoop
|
5617
5715
|
*/
|
5618
5716
|
Ember.run.autorun = function() {
|
@@ -5636,9 +5734,11 @@ Ember.run.autorun = function() {
|
|
5636
5734
|
use this queue so this method is a useful way to immediately force all
|
5637
5735
|
bindings in the application to sync.
|
5638
5736
|
|
5639
|
-
You should call this method anytime you need any changed state to
|
5737
|
+
You should call this method anytime you need any changed state to propagate
|
5640
5738
|
throughout the app immediately without repainting the UI.
|
5641
5739
|
|
5740
|
+
Ember.run.sync();
|
5741
|
+
|
5642
5742
|
@returns {void}
|
5643
5743
|
*/
|
5644
5744
|
Ember.run.sync = function() {
|
@@ -5679,10 +5779,14 @@ function invokeLaterTimers() {
|
|
5679
5779
|
of milliseconds.
|
5680
5780
|
|
5681
5781
|
You should use this method whenever you need to run some action after a
|
5682
|
-
period of time
|
5782
|
+
period of time instead of using setTimeout(). This method will ensure that
|
5683
5783
|
items that expire during the same script execution cycle all execute
|
5684
5784
|
together, which is often more efficient than using a real setTimeout.
|
5685
5785
|
|
5786
|
+
Ember.run.later(myContext, function(){
|
5787
|
+
// code here will execute within a RunLoop in about 500ms with this == myContext
|
5788
|
+
}, 500);
|
5789
|
+
|
5686
5790
|
@param {Object} target
|
5687
5791
|
(optional) target of method to invoke
|
5688
5792
|
|
@@ -5736,6 +5840,13 @@ function invokeOnceTimer(guid, onceTimers) {
|
|
5736
5840
|
considered when looking for duplicates. New arguments will replace previous
|
5737
5841
|
calls.
|
5738
5842
|
|
5843
|
+
Ember.run(function(){
|
5844
|
+
var doFoo = function() { foo(); }
|
5845
|
+
Ember.run.once(myContext, doFoo);
|
5846
|
+
Ember.run.once(myContext, doFoo);
|
5847
|
+
// doFoo will only be executed once at the end of the RunLoop
|
5848
|
+
});
|
5849
|
+
|
5739
5850
|
@param {Object} target
|
5740
5851
|
(optional) target of method to invoke
|
5741
5852
|
|
@@ -5795,6 +5906,10 @@ function invokeNextTimers() {
|
|
5795
5906
|
Schedules an item to run after control has been returned to the system.
|
5796
5907
|
This is often equivalent to calling setTimeout(function...,1).
|
5797
5908
|
|
5909
|
+
Ember.run.next(myContext, function(){
|
5910
|
+
// code to be executed in the next RunLoop, which will be scheduled after the current one
|
5911
|
+
});
|
5912
|
+
|
5798
5913
|
@param {Object} target
|
5799
5914
|
(optional) target of method to invoke
|
5800
5915
|
|
@@ -5828,6 +5943,21 @@ Ember.run.next = function(target, method) {
|
|
5828
5943
|
Cancels a scheduled item. Must be a value returned by `Ember.run.later()`,
|
5829
5944
|
`Ember.run.once()`, or `Ember.run.next()`.
|
5830
5945
|
|
5946
|
+
var runNext = Ember.run.next(myContext, function(){
|
5947
|
+
// will not be executed
|
5948
|
+
});
|
5949
|
+
Ember.run.cancel(runNext);
|
5950
|
+
|
5951
|
+
var runLater = Ember.run.next(myContext, function(){
|
5952
|
+
// will not be executed
|
5953
|
+
}, 500);
|
5954
|
+
Ember.run.cancel(runLater);
|
5955
|
+
|
5956
|
+
var runOnce = Ember.run.once(myContext, function(){
|
5957
|
+
// will not be executed
|
5958
|
+
});
|
5959
|
+
Ember.run.cancel(runOnce);
|
5960
|
+
|
5831
5961
|
@param {Object} timer
|
5832
5962
|
Timer object to cancel
|
5833
5963
|
|
@@ -5842,10 +5972,9 @@ Ember.run.cancel = function(timer) {
|
|
5842
5972
|
//
|
5843
5973
|
|
5844
5974
|
/**
|
5845
|
-
@namespace
|
5975
|
+
@namespace Compatibility for Ember.run
|
5846
5976
|
@name Ember.RunLoop
|
5847
5977
|
@deprecated
|
5848
|
-
@description Compatibility for Ember.run
|
5849
5978
|
*/
|
5850
5979
|
|
5851
5980
|
/**
|
@@ -5866,9 +5995,11 @@ Ember.RunLoop.end = ember_deprecateFunc("Use Ember.run.end instead of Ember.RunL
|
|
5866
5995
|
|
5867
5996
|
|
5868
5997
|
|
5869
|
-
})(
|
5998
|
+
})();
|
5999
|
+
|
6000
|
+
|
5870
6001
|
|
5871
|
-
(function(
|
6002
|
+
(function() {
|
5872
6003
|
// ==========================================================================
|
5873
6004
|
// Project: Ember Runtime
|
5874
6005
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -6097,7 +6228,7 @@ Binding.prototype = /** @scope Ember.Binding.prototype */ {
|
|
6097
6228
|
|
6098
6229
|
/**
|
6099
6230
|
This will set the "to" property path to the specified value. It will not
|
6100
|
-
attempt to
|
6231
|
+
attempt to resolve this property path to an actual object until you
|
6101
6232
|
connect the binding.
|
6102
6233
|
|
6103
6234
|
The binding will search for the property path starting at the root object
|
@@ -6470,9 +6601,9 @@ mixinProperties(Binding,
|
|
6470
6601
|
/**
|
6471
6602
|
@see Ember.Binding.prototype.single
|
6472
6603
|
*/
|
6473
|
-
single: function(from) {
|
6604
|
+
single: function(from, placeholder) {
|
6474
6605
|
var C = this, binding = new C(null, from);
|
6475
|
-
return binding.single();
|
6606
|
+
return binding.single(placeholder);
|
6476
6607
|
},
|
6477
6608
|
|
6478
6609
|
/**
|
@@ -6486,8 +6617,12 @@ mixinProperties(Binding,
|
|
6486
6617
|
/**
|
6487
6618
|
@see Ember.Binding.prototype.transform
|
6488
6619
|
*/
|
6489
|
-
transform: function(func) {
|
6490
|
-
|
6620
|
+
transform: function(from, func) {
|
6621
|
+
if (!func) {
|
6622
|
+
func = from;
|
6623
|
+
from = null;
|
6624
|
+
}
|
6625
|
+
var C = this, binding = new C(null, from);
|
6491
6626
|
return binding.transform(func);
|
6492
6627
|
},
|
6493
6628
|
|
@@ -6499,6 +6634,15 @@ mixinProperties(Binding,
|
|
6499
6634
|
return binding.notEmpty(placeholder);
|
6500
6635
|
},
|
6501
6636
|
|
6637
|
+
/**
|
6638
|
+
@see Ember.Binding.prototype.notNull
|
6639
|
+
*/
|
6640
|
+
notNull: function(from, placeholder) {
|
6641
|
+
var C = this, binding = new C(null, from);
|
6642
|
+
return binding.notNull(placeholder);
|
6643
|
+
},
|
6644
|
+
|
6645
|
+
|
6502
6646
|
/**
|
6503
6647
|
@see Ember.Binding.prototype.bool
|
6504
6648
|
*/
|
@@ -6515,6 +6659,14 @@ mixinProperties(Binding,
|
|
6515
6659
|
return binding.not();
|
6516
6660
|
},
|
6517
6661
|
|
6662
|
+
/**
|
6663
|
+
@see Ember.Binding.prototype.isNull
|
6664
|
+
*/
|
6665
|
+
isNull: function(from) {
|
6666
|
+
var C = this, binding = new C(null, from);
|
6667
|
+
return binding.isNull();
|
6668
|
+
},
|
6669
|
+
|
6518
6670
|
/**
|
6519
6671
|
Adds a transform that forwards the logical 'AND' of values at 'pathA' and
|
6520
6672
|
'pathB' whenever either source changes. Note that the transform acts
|
@@ -6756,18 +6908,20 @@ Ember.oneWay = function(obj, to, from) {
|
|
6756
6908
|
return new Ember.Binding(to, from).oneWay().connect(obj);
|
6757
6909
|
};
|
6758
6910
|
|
6759
|
-
})(
|
6911
|
+
})();
|
6912
|
+
|
6760
6913
|
|
6761
|
-
|
6914
|
+
|
6915
|
+
(function() {
|
6762
6916
|
// ==========================================================================
|
6763
6917
|
// Project: Ember Metal
|
6764
6918
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
6765
6919
|
// License: Licensed under MIT license (see license.js)
|
6766
6920
|
// ==========================================================================
|
6767
6921
|
|
6768
|
-
})(
|
6922
|
+
})();
|
6769
6923
|
|
6770
|
-
(function(
|
6924
|
+
(function() {
|
6771
6925
|
/**
|
6772
6926
|
* @license
|
6773
6927
|
* ==========================================================================
|
@@ -6798,9 +6952,11 @@ Ember.oneWay = function(obj, to, from) {
|
|
6798
6952
|
* ==========================================================================
|
6799
6953
|
*/
|
6800
6954
|
|
6801
|
-
})(
|
6955
|
+
})();
|
6956
|
+
|
6802
6957
|
|
6803
|
-
|
6958
|
+
|
6959
|
+
(function() {
|
6804
6960
|
// ==========================================================================
|
6805
6961
|
// Project: Ember Runtime
|
6806
6962
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -6839,18 +6995,36 @@ var toString = Object.prototype.toString;
|
|
6839
6995
|
It will return the same result across all browsers and includes a bit
|
6840
6996
|
more detail. Here is what will be returned:
|
6841
6997
|
|
6842
|
-
|
6843
|
-
|
6844
|
-
|
6845
|
-
|
6846
|
-
|
6847
|
-
|
6848
|
-
|
6849
|
-
|
6850
|
-
|
6851
|
-
|
6852
|
-
|
6853
|
-
|
6998
|
+
| Return Value | Meaning |
|
6999
|
+
|---------------|------------------------------------------------------|
|
7000
|
+
| 'string' | String primitive |
|
7001
|
+
| 'number' | Number primitive |
|
7002
|
+
| 'boolean' | Boolean primitive |
|
7003
|
+
| 'null' | Null value |
|
7004
|
+
| 'undefined' | Undefined value |
|
7005
|
+
| 'function' | A function |
|
7006
|
+
| 'array' | An instance of Array |
|
7007
|
+
| 'class' | A Ember class (created using Ember.Object.extend()) |
|
7008
|
+
| 'instance' | A Ember object instance |
|
7009
|
+
| 'error' | An instance of the Error object |
|
7010
|
+
| 'object' | A JavaScript object not inheriting from Ember.Object |
|
7011
|
+
|
7012
|
+
Examples:
|
7013
|
+
|
7014
|
+
Ember.typeOf(); => 'undefined'
|
7015
|
+
Ember.typeOf(null); => 'null'
|
7016
|
+
Ember.typeOf(undefined); => 'undefined'
|
7017
|
+
Ember.typeOf('michael'); => 'string'
|
7018
|
+
Ember.typeOf(101); => 'number'
|
7019
|
+
Ember.typeOf(true); => 'boolean'
|
7020
|
+
Ember.typeOf(Ember.makeArray); => 'function'
|
7021
|
+
Ember.typeOf([1,2,90]); => 'array'
|
7022
|
+
Ember.typeOf(Ember.Object.extend()); => 'class'
|
7023
|
+
Ember.typeOf(Ember.Object.create()); => 'instance'
|
7024
|
+
Ember.typeOf(new Error('teamocil')); => 'error'
|
7025
|
+
|
7026
|
+
// "normal" JavaScript object
|
7027
|
+
Ember.typeOf({a: 'b'}); => 'object'
|
6854
7028
|
|
6855
7029
|
@param item {Object} the item to check
|
6856
7030
|
@returns {String} the type
|
@@ -6876,6 +7050,13 @@ Ember.typeOf = function(item) {
|
|
6876
7050
|
from JSLint complaining about use of ==, which can be technically
|
6877
7051
|
confusing.
|
6878
7052
|
|
7053
|
+
Ember.none(); => true
|
7054
|
+
Ember.none(null); => true
|
7055
|
+
Ember.none(undefined); => true
|
7056
|
+
Ember.none(''); => false
|
7057
|
+
Ember.none([]); => false
|
7058
|
+
Ember.none(function(){}); => false
|
7059
|
+
|
6879
7060
|
@param {Object} obj Value to test
|
6880
7061
|
@returns {Boolean}
|
6881
7062
|
*/
|
@@ -6886,6 +7067,17 @@ Ember.none = function(obj) {
|
|
6886
7067
|
/**
|
6887
7068
|
Verifies that a value is null or an empty string | array | function.
|
6888
7069
|
|
7070
|
+
Constrains the rules on `Ember.none` by returning false for empty
|
7071
|
+
string and empty arrays.
|
7072
|
+
|
7073
|
+
Ember.empty(); => true
|
7074
|
+
Ember.empty(null); => true
|
7075
|
+
Ember.empty(undefined); => true
|
7076
|
+
Ember.empty(''); => true
|
7077
|
+
Ember.empty([]); => true
|
7078
|
+
Ember.empty('tobias fünke'); => false
|
7079
|
+
Ember.empty([0,1,2]); => false
|
7080
|
+
|
6889
7081
|
@param {Object} obj Value to test
|
6890
7082
|
@returns {Boolean}
|
6891
7083
|
*/
|
@@ -6893,10 +7085,6 @@ Ember.empty = function(obj) {
|
|
6893
7085
|
return obj === null || obj === undefined || (obj.length === 0 && typeof obj !== 'function');
|
6894
7086
|
};
|
6895
7087
|
|
6896
|
-
/**
|
6897
|
-
Ember.isArray defined in ember-metal/lib/utils
|
6898
|
-
**/
|
6899
|
-
|
6900
7088
|
/**
|
6901
7089
|
This will compare two javascript values of possibly different types.
|
6902
7090
|
It will tell you which one is greater than the other by returning:
|
@@ -6908,6 +7096,10 @@ Ember.empty = function(obj) {
|
|
6908
7096
|
The order is calculated based on Ember.ORDER_DEFINITION, if types are different.
|
6909
7097
|
In case they have the same type an appropriate comparison for this type is made.
|
6910
7098
|
|
7099
|
+
Ember.compare('hello', 'hello'); => 0
|
7100
|
+
Ember.compare('abc', 'dfg'); => -1
|
7101
|
+
Ember.compare(2, 1); => 1
|
7102
|
+
|
6911
7103
|
@param {Object} v First value to compare
|
6912
7104
|
@param {Object} w Second value to compare
|
6913
7105
|
@returns {Number} -1 if v < w, 0 if v = w and 1 if v > w.
|
@@ -7077,6 +7269,10 @@ Ember.inspect = function(obj) {
|
|
7077
7269
|
internal objects. For any other object that implements `isEqual()` it will
|
7078
7270
|
respect that method.
|
7079
7271
|
|
7272
|
+
Ember.isEqual('hello', 'hello'); => true
|
7273
|
+
Ember.isEqual(1, 2); => false
|
7274
|
+
Ember.isEqual([4,2], [4,2]); => false
|
7275
|
+
|
7080
7276
|
@param {Object} a first object to compare
|
7081
7277
|
@param {Object} b second object to compare
|
7082
7278
|
@returns {Boolean}
|
@@ -7144,9 +7340,11 @@ Ember.Error = function() {
|
|
7144
7340
|
|
7145
7341
|
Ember.Error.prototype = Ember.create(Error.prototype);
|
7146
7342
|
|
7147
|
-
})(
|
7343
|
+
})();
|
7344
|
+
|
7148
7345
|
|
7149
|
-
|
7346
|
+
|
7347
|
+
(function() {
|
7150
7348
|
// ==========================================================================
|
7151
7349
|
// Project: Ember Runtime
|
7152
7350
|
// Copyright: ©2011 Strobe Inc.
|
@@ -7339,9 +7537,11 @@ Ember.String = {
|
|
7339
7537
|
replace(STRING_UNDERSCORE_REGEXP_2, '_').toLowerCase();
|
7340
7538
|
}
|
7341
7539
|
};
|
7342
|
-
})(
|
7540
|
+
})();
|
7541
|
+
|
7343
7542
|
|
7344
|
-
|
7543
|
+
|
7544
|
+
(function() {
|
7345
7545
|
// ==========================================================================
|
7346
7546
|
// Project: Ember Runtime
|
7347
7547
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -7410,9 +7610,11 @@ if (Ember.EXTEND_PROTOTYPES) {
|
|
7410
7610
|
}
|
7411
7611
|
|
7412
7612
|
|
7413
|
-
})(
|
7613
|
+
})();
|
7614
|
+
|
7414
7615
|
|
7415
|
-
|
7616
|
+
|
7617
|
+
(function() {
|
7416
7618
|
// ==========================================================================
|
7417
7619
|
// Project: Ember Runtime
|
7418
7620
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -7520,9 +7722,11 @@ if (Ember.EXTEND_PROTOTYPES) {
|
|
7520
7722
|
}
|
7521
7723
|
|
7522
7724
|
|
7523
|
-
})(
|
7725
|
+
})();
|
7726
|
+
|
7524
7727
|
|
7525
|
-
|
7728
|
+
|
7729
|
+
(function() {
|
7526
7730
|
// ==========================================================================
|
7527
7731
|
// Project: Ember Runtime
|
7528
7732
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -7556,18 +7760,22 @@ Ember._mixinBindings = function(obj, key, value, m) {
|
|
7556
7760
|
return value;
|
7557
7761
|
};
|
7558
7762
|
|
7559
|
-
})(
|
7763
|
+
})();
|
7764
|
+
|
7560
7765
|
|
7561
|
-
|
7766
|
+
|
7767
|
+
(function() {
|
7562
7768
|
// ==========================================================================
|
7563
7769
|
// Project: Ember Runtime
|
7564
7770
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
7565
7771
|
// License: Licensed under MIT license (see license.js)
|
7566
7772
|
// ==========================================================================
|
7567
7773
|
|
7568
|
-
})(
|
7774
|
+
})();
|
7775
|
+
|
7569
7776
|
|
7570
|
-
|
7777
|
+
|
7778
|
+
(function() {
|
7571
7779
|
// ==========================================================================
|
7572
7780
|
// Project: Ember Runtime
|
7573
7781
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -7679,7 +7887,7 @@ Ember.Enumerable = Ember.Mixin.create( /** @lends Ember.Enumerable */ {
|
|
7679
7887
|
reaches the your current length-1. If you run out of data before this
|
7680
7888
|
time for some reason, you should simply return undefined.
|
7681
7889
|
|
7682
|
-
The default
|
7890
|
+
The default implementation of this method simply looks up the index.
|
7683
7891
|
This works great on any Array-like objects.
|
7684
7892
|
|
7685
7893
|
@param index {Number} the current index of the iteration
|
@@ -8304,7 +8512,7 @@ Ember.Enumerable = Ember.Mixin.create( /** @lends Ember.Enumerable */ {
|
|
8304
8512
|
|
8305
8513
|
@param {Enumerable} removes
|
8306
8514
|
optional enumerable containing items that were removed from the set.
|
8307
|
-
For ordered enumerables, this
|
8515
|
+
For ordered enumerables, this should be an ordered array of items. If
|
8308
8516
|
no items were removed you can pass null.
|
8309
8517
|
|
8310
8518
|
@returns {Object} receiver
|
@@ -8336,9 +8544,11 @@ Ember.Enumerable = Ember.Mixin.create( /** @lends Ember.Enumerable */ {
|
|
8336
8544
|
|
8337
8545
|
|
8338
8546
|
|
8339
|
-
})(
|
8547
|
+
})();
|
8548
|
+
|
8340
8549
|
|
8341
|
-
|
8550
|
+
|
8551
|
+
(function() {
|
8342
8552
|
// ==========================================================================
|
8343
8553
|
// Project: Ember Runtime
|
8344
8554
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -8346,9 +8556,9 @@ Ember.Enumerable = Ember.Mixin.create( /** @lends Ember.Enumerable */ {
|
|
8346
8556
|
// ==========================================================================
|
8347
8557
|
// ..........................................................
|
8348
8558
|
// HELPERS
|
8349
|
-
//
|
8559
|
+
//
|
8350
8560
|
|
8351
|
-
var get = Ember.get, set = Ember.set, meta = Ember.meta;
|
8561
|
+
var get = Ember.get, set = Ember.set, meta = Ember.meta, map = Ember.ArrayUtils.map;
|
8352
8562
|
|
8353
8563
|
/** @private */
|
8354
8564
|
function none(obj) { return obj===null || obj===undefined; }
|
@@ -8360,7 +8570,7 @@ function xform(target, method, params) {
|
|
8360
8570
|
|
8361
8571
|
// ..........................................................
|
8362
8572
|
// ARRAY
|
8363
|
-
//
|
8573
|
+
//
|
8364
8574
|
/**
|
8365
8575
|
@namespace
|
8366
8576
|
|
@@ -8397,7 +8607,7 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
|
8397
8607
|
|
8398
8608
|
/** @private - compatibility */
|
8399
8609
|
isSCArray: true,
|
8400
|
-
|
8610
|
+
|
8401
8611
|
/**
|
8402
8612
|
@field {Number} length
|
8403
8613
|
|
@@ -8421,11 +8631,22 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
|
8421
8631
|
return get(this, idx);
|
8422
8632
|
},
|
8423
8633
|
|
8634
|
+
/**
|
8635
|
+
This returns the objects at the specified indexes, using objectAt.
|
8636
|
+
|
8637
|
+
@param {Array} indexes
|
8638
|
+
An array of indexes of items to return.
|
8639
|
+
*/
|
8640
|
+
objectsAt: function(indexes) {
|
8641
|
+
var self = this;
|
8642
|
+
return map(indexes, function(idx){ return self.objectAt(idx); });
|
8643
|
+
},
|
8644
|
+
|
8424
8645
|
/** @private (nodoc) - overrides Ember.Enumerable version */
|
8425
8646
|
nextObject: function(idx) {
|
8426
8647
|
return this.objectAt(idx);
|
8427
8648
|
},
|
8428
|
-
|
8649
|
+
|
8429
8650
|
/**
|
8430
8651
|
@field []
|
8431
8652
|
|
@@ -8474,21 +8695,20 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
|
8474
8695
|
/**
|
8475
8696
|
Returns the index of the given object's first occurrence.
|
8476
8697
|
If no startAt argument is given, the starting location to
|
8477
|
-
search is 0. If it's negative, will count backward from
|
8698
|
+
search is 0. If it's negative, will count backward from
|
8478
8699
|
the end of the array. Returns -1 if no match is found.
|
8479
8700
|
|
8701
|
+
var arr = ["a", "b", "c", "d", "a"];
|
8702
|
+
arr.indexOf("a"); => 0
|
8703
|
+
arr.indexOf("z"); => -1
|
8704
|
+
arr.indexOf("a", 2); => 4
|
8705
|
+
arr.indexOf("a", -1); => 4
|
8706
|
+
arr.indexOf("b", 3); => -1
|
8707
|
+
arr.indexOf("a", 100); => -1
|
8708
|
+
|
8480
8709
|
@param {Object} object the item to search for
|
8481
8710
|
@param {Number} startAt optional starting location to search, default 0
|
8482
8711
|
@returns {Number} index or -1 if not found
|
8483
|
-
|
8484
|
-
@example
|
8485
|
-
var arr = ["a", "b", "c", "d", "a"];
|
8486
|
-
arr.indexOf("a"); => 0
|
8487
|
-
arr.indexOf("z"); => -1
|
8488
|
-
arr.indexOf("a", 2); => 4
|
8489
|
-
arr.indexOf("a", -1); => 4
|
8490
|
-
arr.indexOf("b", 3); => -1
|
8491
|
-
arr.indexOf("a", 100); => -1
|
8492
8712
|
*/
|
8493
8713
|
indexOf: function(object, startAt) {
|
8494
8714
|
var idx, len = get(this, 'length');
|
@@ -8505,21 +8725,20 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
|
8505
8725
|
/**
|
8506
8726
|
Returns the index of the given object's last occurrence.
|
8507
8727
|
If no startAt argument is given, the search starts from
|
8508
|
-
the last position. If it's negative, will count backward
|
8728
|
+
the last position. If it's negative, will count backward
|
8509
8729
|
from the end of the array. Returns -1 if no match is found.
|
8510
8730
|
|
8731
|
+
var arr = ["a", "b", "c", "d", "a"];
|
8732
|
+
arr.lastIndexOf("a"); => 4
|
8733
|
+
arr.lastIndexOf("z"); => -1
|
8734
|
+
arr.lastIndexOf("a", 2); => 0
|
8735
|
+
arr.lastIndexOf("a", -1); => 4
|
8736
|
+
arr.lastIndexOf("b", 3); => 1
|
8737
|
+
arr.lastIndexOf("a", 100); => 4
|
8738
|
+
|
8511
8739
|
@param {Object} object the item to search for
|
8512
8740
|
@param {Number} startAt optional starting location to search, default 0
|
8513
8741
|
@returns {Number} index or -1 if not found
|
8514
|
-
|
8515
|
-
@example
|
8516
|
-
var arr = ["a", "b", "c", "d", "a"];
|
8517
|
-
arr.lastIndexOf("a"); => 4
|
8518
|
-
arr.lastIndexOf("z"); => -1
|
8519
|
-
arr.lastIndexOf("a", 2); => 0
|
8520
|
-
arr.lastIndexOf("a", -1); => 4
|
8521
|
-
arr.lastIndexOf("b", 3); => 1
|
8522
|
-
arr.lastIndexOf("a", 100); => 4
|
8523
8742
|
*/
|
8524
8743
|
lastIndexOf: function(object, startAt) {
|
8525
8744
|
var idx, len = get(this, 'length');
|
@@ -8532,36 +8751,36 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
|
8532
8751
|
}
|
8533
8752
|
return -1;
|
8534
8753
|
},
|
8535
|
-
|
8754
|
+
|
8536
8755
|
// ..........................................................
|
8537
8756
|
// ARRAY OBSERVERS
|
8538
|
-
//
|
8539
|
-
|
8757
|
+
//
|
8758
|
+
|
8540
8759
|
/**
|
8541
8760
|
Adds an array observer to the receiving array. The array observer object
|
8542
8761
|
normally must implement two methods:
|
8543
|
-
|
8762
|
+
|
8544
8763
|
* `arrayWillChange(start, removeCount, addCount)` - This method will be
|
8545
8764
|
called just before the array is modified.
|
8546
8765
|
* `arrayDidChange(start, removeCount, addCount)` - This method will be
|
8547
8766
|
called just after the array is modified.
|
8548
|
-
|
8549
|
-
Both callbacks will be passed the starting index of the change as well a
|
8767
|
+
|
8768
|
+
Both callbacks will be passed the starting index of the change as well a
|
8550
8769
|
a count of the items to be removed and added. You can use these callbacks
|
8551
|
-
to optionally inspect the array during the change, clear caches, or do
|
8770
|
+
to optionally inspect the array during the change, clear caches, or do
|
8552
8771
|
any other bookkeeping necessary.
|
8553
|
-
|
8554
|
-
In addition to passing a target, you can also include an options hash
|
8772
|
+
|
8773
|
+
In addition to passing a target, you can also include an options hash
|
8555
8774
|
which you can use to override the method names that will be invoked on the
|
8556
8775
|
target.
|
8557
|
-
|
8776
|
+
|
8558
8777
|
@param {Object} target
|
8559
8778
|
The observer object.
|
8560
|
-
|
8779
|
+
|
8561
8780
|
@param {Hash} opts
|
8562
8781
|
Optional hash of configuration options including willChange, didChange,
|
8563
8782
|
and a context option.
|
8564
|
-
|
8783
|
+
|
8565
8784
|
@returns {Ember.Array} receiver
|
8566
8785
|
*/
|
8567
8786
|
addArrayObserver: function(target, opts) {
|
@@ -8575,15 +8794,15 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
|
8575
8794
|
if (!hasObservers) Ember.propertyDidChange(this, 'hasArrayObservers');
|
8576
8795
|
return this;
|
8577
8796
|
},
|
8578
|
-
|
8797
|
+
|
8579
8798
|
/**
|
8580
|
-
Removes an array observer from the object if the observer is current
|
8799
|
+
Removes an array observer from the object if the observer is current
|
8581
8800
|
registered. Calling this method multiple times with the same object will
|
8582
8801
|
have no effect.
|
8583
|
-
|
8802
|
+
|
8584
8803
|
@param {Object} target
|
8585
8804
|
The object observing the array.
|
8586
|
-
|
8805
|
+
|
8587
8806
|
@returns {Ember.Array} receiver
|
8588
8807
|
*/
|
8589
8808
|
removeArrayObserver: function(target, opts) {
|
@@ -8597,32 +8816,32 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
|
8597
8816
|
if (hasObservers) Ember.propertyDidChange(this, 'hasArrayObservers');
|
8598
8817
|
return this;
|
8599
8818
|
},
|
8600
|
-
|
8819
|
+
|
8601
8820
|
/**
|
8602
8821
|
Becomes true whenever the array currently has observers watching changes
|
8603
8822
|
on the array.
|
8604
|
-
|
8823
|
+
|
8605
8824
|
@property {Boolean}
|
8606
8825
|
*/
|
8607
8826
|
hasArrayObservers: Ember.computed(function() {
|
8608
8827
|
return Ember.hasListeners(this, '@array:change') || Ember.hasListeners(this, '@array:before');
|
8609
8828
|
}).property().cacheable(),
|
8610
|
-
|
8829
|
+
|
8611
8830
|
/**
|
8612
|
-
If you are implementing an object that supports Ember.Array, call this
|
8831
|
+
If you are implementing an object that supports Ember.Array, call this
|
8613
8832
|
method just before the array content changes to notify any observers and
|
8614
8833
|
invalidate any related properties. Pass the starting index of the change
|
8615
8834
|
as well as a delta of the amounts to change.
|
8616
|
-
|
8835
|
+
|
8617
8836
|
@param {Number} startIdx
|
8618
8837
|
The starting index in the array that will change.
|
8619
|
-
|
8838
|
+
|
8620
8839
|
@param {Number} removeAmt
|
8621
8840
|
The number of items that will be removed. If you pass null assumes 0
|
8622
|
-
|
8841
|
+
|
8623
8842
|
@param {Number} addAmt
|
8624
8843
|
The number of items that will be added. If you pass null assumes 0.
|
8625
|
-
|
8844
|
+
|
8626
8845
|
@returns {Ember.Array} receiver
|
8627
8846
|
*/
|
8628
8847
|
arrayContentWillChange: function(startIdx, removeAmt, addAmt) {
|
@@ -8646,14 +8865,14 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
|
8646
8865
|
} else {
|
8647
8866
|
removing = removeAmt;
|
8648
8867
|
}
|
8649
|
-
|
8868
|
+
|
8650
8869
|
this.enumerableContentWillChange(removing, addAmt);
|
8651
8870
|
|
8652
8871
|
// Make sure the @each proxy is set up if anyone is observing @each
|
8653
8872
|
if (Ember.isWatching(this, '@each')) { get(this, '@each'); }
|
8654
8873
|
return this;
|
8655
8874
|
},
|
8656
|
-
|
8875
|
+
|
8657
8876
|
arrayContentDidChange: function(startIdx, removeAmt, addAmt) {
|
8658
8877
|
|
8659
8878
|
// if no args are passed assume everything changes
|
@@ -8664,7 +8883,7 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
|
8664
8883
|
if (!removeAmt) removeAmt=0;
|
8665
8884
|
if (!addAmt) addAmt=0;
|
8666
8885
|
}
|
8667
|
-
|
8886
|
+
|
8668
8887
|
var adding, lim;
|
8669
8888
|
if (startIdx>=0 && addAmt>=0 && get(this, 'hasEnumerableObservers')) {
|
8670
8889
|
adding = [];
|
@@ -8678,15 +8897,15 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
|
8678
8897
|
Ember.sendEvent(this, '@array:change', startIdx, removeAmt, addAmt);
|
8679
8898
|
return this;
|
8680
8899
|
},
|
8681
|
-
|
8900
|
+
|
8682
8901
|
// ..........................................................
|
8683
8902
|
// ENUMERATED PROPERTIES
|
8684
|
-
//
|
8685
|
-
|
8903
|
+
//
|
8904
|
+
|
8686
8905
|
/**
|
8687
8906
|
Returns a special object that can be used to observe individual properties
|
8688
8907
|
on the array. Just get an equivalent property on this object and it will
|
8689
|
-
return an enumerable that maps automatically to the named key on the
|
8908
|
+
return an enumerable that maps automatically to the named key on the
|
8690
8909
|
member objects.
|
8691
8910
|
*/
|
8692
8911
|
'@each': Ember.computed(function() {
|
@@ -8701,9 +8920,11 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
|
8701
8920
|
|
8702
8921
|
|
8703
8922
|
|
8704
|
-
})(
|
8923
|
+
})();
|
8924
|
+
|
8705
8925
|
|
8706
|
-
|
8926
|
+
|
8927
|
+
(function() {
|
8707
8928
|
// ==========================================================================
|
8708
8929
|
// Project: Ember Runtime
|
8709
8930
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -8750,9 +8971,11 @@ Ember.Comparable = Ember.Mixin.create( /** @scope Ember.Comparable.prototype */{
|
|
8750
8971
|
});
|
8751
8972
|
|
8752
8973
|
|
8753
|
-
})(
|
8974
|
+
})();
|
8975
|
+
|
8754
8976
|
|
8755
|
-
|
8977
|
+
|
8978
|
+
(function() {
|
8756
8979
|
// ==========================================================================
|
8757
8980
|
// Project: Ember Runtime
|
8758
8981
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -8812,9 +9035,11 @@ Ember.Copyable = Ember.Mixin.create(
|
|
8812
9035
|
|
8813
9036
|
|
8814
9037
|
|
8815
|
-
})(
|
9038
|
+
})();
|
9039
|
+
|
8816
9040
|
|
8817
|
-
|
9041
|
+
|
9042
|
+
(function() {
|
8818
9043
|
// ==========================================================================
|
8819
9044
|
// Project: Ember Runtime
|
8820
9045
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -8899,7 +9124,7 @@ Ember.Freezable = Ember.Mixin.create(
|
|
8899
9124
|
Freezes the object. Once this method has been called the object should
|
8900
9125
|
no longer allow any properties to be edited.
|
8901
9126
|
|
8902
|
-
@returns {Object}
|
9127
|
+
@returns {Object} receiver
|
8903
9128
|
*/
|
8904
9129
|
freeze: function() {
|
8905
9130
|
if (get(this, 'isFrozen')) return this;
|
@@ -8914,9 +9139,11 @@ Ember.FROZEN_ERROR = "Frozen object cannot be modified.";
|
|
8914
9139
|
|
8915
9140
|
|
8916
9141
|
|
8917
|
-
})(
|
9142
|
+
})();
|
9143
|
+
|
9144
|
+
|
8918
9145
|
|
8919
|
-
(function(
|
9146
|
+
(function() {
|
8920
9147
|
// ==========================================================================
|
8921
9148
|
// Project: Ember Runtime
|
8922
9149
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -8941,7 +9168,6 @@ var forEach = Ember.ArrayUtils.forEach;
|
|
8941
9168
|
method will only add the object to the enumerable if the object is not
|
8942
9169
|
already present and the object if of a type supported by the enumerable.
|
8943
9170
|
|
8944
|
-
javascript:
|
8945
9171
|
set.addObject(contact);
|
8946
9172
|
|
8947
9173
|
## Removing Objects
|
@@ -8950,7 +9176,6 @@ var forEach = Ember.ArrayUtils.forEach;
|
|
8950
9176
|
will only remove the object if it is already in the enumerable, otherwise
|
8951
9177
|
this method has no effect.
|
8952
9178
|
|
8953
|
-
javascript:
|
8954
9179
|
set.removeObject(contact);
|
8955
9180
|
|
8956
9181
|
## Implementing In Your Own Code
|
@@ -9028,9 +9253,11 @@ Ember.MutableEnumerable = Ember.Mixin.create(Ember.Enumerable,
|
|
9028
9253
|
|
9029
9254
|
});
|
9030
9255
|
|
9031
|
-
})(
|
9256
|
+
})();
|
9257
|
+
|
9258
|
+
|
9032
9259
|
|
9033
|
-
(function(
|
9260
|
+
(function() {
|
9034
9261
|
// ==========================================================================
|
9035
9262
|
// Project: Ember Runtime
|
9036
9263
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -9056,8 +9283,8 @@ var get = Ember.get, set = Ember.set, forEach = Ember.ArrayUtils.forEach;
|
|
9056
9283
|
can be applied only to a collection that keeps its items in an ordered set.
|
9057
9284
|
|
9058
9285
|
Note that an Array can change even if it does not implement this mixin.
|
9059
|
-
For example, a
|
9060
|
-
underlying enumerable changes, it will change also.
|
9286
|
+
For example, one might implement a SparseArray that cannot be directly
|
9287
|
+
modified, but if its underlying enumerable changes, it will change also.
|
9061
9288
|
|
9062
9289
|
@extends Ember.Mixin
|
9063
9290
|
@extends Ember.Array
|
@@ -9069,7 +9296,7 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,
|
|
9069
9296
|
/**
|
9070
9297
|
__Required.__ You must implement this method to apply this mixin.
|
9071
9298
|
|
9072
|
-
This is one of the
|
9299
|
+
This is one of the primitives you must implement to support Ember.Array. You
|
9073
9300
|
should replace amt objects started at idx with the objects in the passed
|
9074
9301
|
array. You should also call this.enumerableContentDidChange() ;
|
9075
9302
|
|
@@ -9087,6 +9314,24 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,
|
|
9087
9314
|
*/
|
9088
9315
|
replace: Ember.required(),
|
9089
9316
|
|
9317
|
+
/**
|
9318
|
+
Remove all elements from self. This is useful if you
|
9319
|
+
want to reuse an existing array without having to recreate it.
|
9320
|
+
|
9321
|
+
var colors = ["red", "green", "blue"];
|
9322
|
+
color.length(); => 3
|
9323
|
+
colors.clear(); => []
|
9324
|
+
colors.length(); => 0
|
9325
|
+
|
9326
|
+
@returns {Ember.Array} An empty Array.
|
9327
|
+
*/
|
9328
|
+
clear: function () {
|
9329
|
+
var len = get(this, 'length');
|
9330
|
+
if (len === 0) return this;
|
9331
|
+
this.replace(0, len, EMPTY);
|
9332
|
+
return this;
|
9333
|
+
},
|
9334
|
+
|
9090
9335
|
/**
|
9091
9336
|
This will use the primitive replace() method to insert an object at the
|
9092
9337
|
specified index.
|
@@ -9257,9 +9502,11 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,
|
|
9257
9502
|
});
|
9258
9503
|
|
9259
9504
|
|
9260
|
-
})(
|
9505
|
+
})();
|
9506
|
+
|
9507
|
+
|
9261
9508
|
|
9262
|
-
(function(
|
9509
|
+
(function() {
|
9263
9510
|
// ==========================================================================
|
9264
9511
|
// Project: Ember Runtime
|
9265
9512
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -9371,17 +9618,25 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ {
|
|
9371
9618
|
|
9372
9619
|
/**
|
9373
9620
|
To get multiple properties at once, call getProperties
|
9374
|
-
with a list of strings:
|
9621
|
+
with a list of strings or an array:
|
9375
9622
|
|
9376
9623
|
record.getProperties('firstName', 'lastName', 'zipCode'); // => { firstName: 'John', lastName: 'Doe', zipCode: '10011' }
|
9377
9624
|
|
9378
|
-
|
9379
|
-
|
9625
|
+
is equivalent to:
|
9626
|
+
|
9627
|
+
record.getProperties(['firstName', 'lastName', 'zipCode']); // => { firstName: 'John', lastName: 'Doe', zipCode: '10011' }
|
9628
|
+
|
9629
|
+
@param {String...|Array} list of keys to get
|
9630
|
+
@returns {Hash}
|
9380
9631
|
*/
|
9381
9632
|
getProperties: function() {
|
9382
9633
|
var ret = {};
|
9383
|
-
|
9384
|
-
|
9634
|
+
var propertyNames = arguments;
|
9635
|
+
if (arguments.length === 1 && Ember.typeOf(arguments[0]) === 'array') {
|
9636
|
+
propertyNames = arguments[0];
|
9637
|
+
}
|
9638
|
+
for(var i = 0; i < propertyNames.length; i++) {
|
9639
|
+
ret[propertyNames[i]] = get(this, propertyNames[i]);
|
9385
9640
|
}
|
9386
9641
|
return ret;
|
9387
9642
|
},
|
@@ -9407,7 +9662,7 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ {
|
|
9407
9662
|
If you try to set a value on a key that is undefined in the target
|
9408
9663
|
object, then the unknownProperty() handler will be called instead. This
|
9409
9664
|
gives you an opportunity to implement complex "virtual" properties that
|
9410
|
-
are not predefined on the
|
9665
|
+
are not predefined on the object. If unknownProperty() returns
|
9411
9666
|
undefined, then set() will simply set the value on the object.
|
9412
9667
|
|
9413
9668
|
### Property Observers
|
@@ -9418,7 +9673,7 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ {
|
|
9418
9673
|
observers (i.e. observer methods declared on the same object), will be
|
9419
9674
|
called immediately. Any "remote" observers (i.e. observer methods
|
9420
9675
|
declared on another object) will be placed in a queue and called at a
|
9421
|
-
later time in a
|
9676
|
+
later time in a coalesced manner.
|
9422
9677
|
|
9423
9678
|
### Chaining
|
9424
9679
|
|
@@ -9593,7 +9848,7 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ {
|
|
9593
9848
|
@param {String} key The key to observer
|
9594
9849
|
@param {Object} target The target object to invoke
|
9595
9850
|
@param {String|Function} method The method to invoke.
|
9596
|
-
@returns {Ember.Observable}
|
9851
|
+
@returns {Ember.Observable} receiver
|
9597
9852
|
*/
|
9598
9853
|
removeObserver: function(key, target, method) {
|
9599
9854
|
Ember.removeObserver(this, key, target, method);
|
@@ -9730,19 +9985,33 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ {
|
|
9730
9985
|
return get(this, keyName);
|
9731
9986
|
},
|
9732
9987
|
|
9988
|
+
/**
|
9989
|
+
Returns the cached value of a computed property, if it exists.
|
9990
|
+
This allows you to inspect the value of a computed property
|
9991
|
+
without accidentally invoking it if it is intended to be
|
9992
|
+
generated lazily.
|
9993
|
+
|
9994
|
+
@param {String} keyName
|
9995
|
+
@returns {Object} The cached value of the computed property, if any
|
9996
|
+
*/
|
9997
|
+
cacheFor: function(keyName) {
|
9998
|
+
return Ember.cacheFor(this, keyName);
|
9999
|
+
},
|
10000
|
+
|
9733
10001
|
/** @private - intended for debugging purposes */
|
9734
10002
|
observersForKey: function(keyName) {
|
9735
10003
|
return Ember.observersFor(this, keyName);
|
9736
10004
|
}
|
9737
|
-
|
9738
10005
|
});
|
9739
10006
|
|
9740
10007
|
|
9741
10008
|
|
9742
10009
|
|
9743
|
-
})(
|
10010
|
+
})();
|
10011
|
+
|
10012
|
+
|
9744
10013
|
|
9745
|
-
(function(
|
10014
|
+
(function() {
|
9746
10015
|
var get = Ember.get, set = Ember.set, getPath = Ember.getPath;
|
9747
10016
|
|
9748
10017
|
Ember.TargetActionSupport = Ember.Mixin.create({
|
@@ -9786,9 +10055,11 @@ Ember.TargetActionSupport = Ember.Mixin.create({
|
|
9786
10055
|
}
|
9787
10056
|
});
|
9788
10057
|
|
9789
|
-
})(
|
10058
|
+
})();
|
10059
|
+
|
9790
10060
|
|
9791
|
-
|
10061
|
+
|
10062
|
+
(function() {
|
9792
10063
|
var get = Ember.get, set = Ember.set, a_slice = Array.prototype.slice;
|
9793
10064
|
|
9794
10065
|
/** @private */
|
@@ -9816,18 +10087,22 @@ Ember.Evented = Ember.Mixin.create({
|
|
9816
10087
|
}
|
9817
10088
|
});
|
9818
10089
|
|
9819
|
-
})(
|
10090
|
+
})();
|
10091
|
+
|
9820
10092
|
|
9821
|
-
|
10093
|
+
|
10094
|
+
(function() {
|
9822
10095
|
// ==========================================================================
|
9823
10096
|
// Project: Ember Runtime
|
9824
10097
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
9825
10098
|
// License: Licensed under MIT license (see license.js)
|
9826
10099
|
// ==========================================================================
|
9827
10100
|
|
9828
|
-
})(
|
10101
|
+
})();
|
10102
|
+
|
9829
10103
|
|
9830
|
-
|
10104
|
+
|
10105
|
+
(function() {
|
9831
10106
|
// ==========================================================================
|
9832
10107
|
// Project: Ember Runtime
|
9833
10108
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -9856,18 +10131,9 @@ function makeCtor() {
|
|
9856
10131
|
// method a lot faster. This is glue code so we want it to be as fast as
|
9857
10132
|
// possible.
|
9858
10133
|
|
9859
|
-
var wasApplied = false, initMixins,
|
10134
|
+
var wasApplied = false, initMixins, init = false, hasChains = false;
|
9860
10135
|
|
9861
10136
|
var Class = function() {
|
9862
|
-
if (defaults) {
|
9863
|
-
for (var prop in defaults) {
|
9864
|
-
if (!defaults.hasOwnProperty(prop)) { continue; }
|
9865
|
-
Ember.defineProperty(this, prop, undefined, defaults[prop]);
|
9866
|
-
}
|
9867
|
-
|
9868
|
-
defaults = null;
|
9869
|
-
}
|
9870
|
-
|
9871
10137
|
if (!wasApplied) { Class.proto(); } // prepare prototype...
|
9872
10138
|
if (initMixins) {
|
9873
10139
|
this.reopen.apply(this, initMixins);
|
@@ -9897,7 +10163,6 @@ function makeCtor() {
|
|
9897
10163
|
wasApplied = false;
|
9898
10164
|
};
|
9899
10165
|
Class._initMixins = function(args) { initMixins = args; };
|
9900
|
-
Class._setDefaults = function(arg) { defaults = arg; };
|
9901
10166
|
|
9902
10167
|
Class.proto = function() {
|
9903
10168
|
var superclass = Class.superclass;
|
@@ -9929,9 +10194,13 @@ CoreObject.PrototypeMixin = Ember.Mixin.create(
|
|
9929
10194
|
|
9930
10195
|
isInstance: true,
|
9931
10196
|
|
10197
|
+
/** @private */
|
9932
10198
|
init: function() {},
|
9933
10199
|
|
10200
|
+
/** @field */
|
9934
10201
|
isDestroyed: false,
|
10202
|
+
|
10203
|
+
/** @field */
|
9935
10204
|
isDestroying: false,
|
9936
10205
|
|
9937
10206
|
/**
|
@@ -10025,30 +10294,6 @@ var ClassMixin = Ember.Mixin.create({
|
|
10025
10294
|
return new C();
|
10026
10295
|
},
|
10027
10296
|
|
10028
|
-
/**
|
10029
|
-
@private
|
10030
|
-
|
10031
|
-
Right now, when a key is passed in `create` that is not already
|
10032
|
-
present in the superclass, we need to create a mixin object and
|
10033
|
-
apply the mixin to the object we're creating. This is
|
10034
|
-
unnecessarily expensive. Because Ember views are created a lot,
|
10035
|
-
this is a temporary convenience that will allow us to create
|
10036
|
-
a new object and set properties before `init` time.
|
10037
|
-
|
10038
|
-
The correct solution is for the default init code to detect
|
10039
|
-
properties that do not need special handling and call
|
10040
|
-
`setProperties` on them when `create` occurs. This will
|
10041
|
-
massively speed up `create` calls that do not need any special
|
10042
|
-
Ember features (like bindings, observers or computed properties)
|
10043
|
-
and are not overriding a computed property with a regular value.
|
10044
|
-
*/
|
10045
|
-
createWith: function(defaults) {
|
10046
|
-
var C = this;
|
10047
|
-
if (arguments.length>0) { this._initMixins(a_slice.call(arguments, 1)); }
|
10048
|
-
if (defaults) { this._setDefaults(defaults); }
|
10049
|
-
return new C();
|
10050
|
-
},
|
10051
|
-
|
10052
10297
|
reopen: function() {
|
10053
10298
|
this.willReopen();
|
10054
10299
|
var PrototypeMixin = this.PrototypeMixin;
|
@@ -10135,9 +10380,11 @@ Ember.CoreObject = CoreObject;
|
|
10135
10380
|
|
10136
10381
|
|
10137
10382
|
|
10138
|
-
})(
|
10383
|
+
})();
|
10384
|
+
|
10385
|
+
|
10139
10386
|
|
10140
|
-
(function(
|
10387
|
+
(function() {
|
10141
10388
|
// ==========================================================================
|
10142
10389
|
// Project: Ember Runtime
|
10143
10390
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -10274,7 +10521,13 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
|
|
10274
10521
|
clear: function() {
|
10275
10522
|
if (this.isFrozen) { throw new Error(Ember.FROZEN_ERROR); }
|
10276
10523
|
var len = get(this, 'length');
|
10524
|
+
var guid;
|
10277
10525
|
this.enumerableContentWillChange(len, 0);
|
10526
|
+
for (var i=0; i < len; i++){
|
10527
|
+
guid = guidFor(this[i]);
|
10528
|
+
delete this[guid];
|
10529
|
+
delete this[i];
|
10530
|
+
}
|
10278
10531
|
set(this, 'length', 0);
|
10279
10532
|
this.enumerableContentDidChange(len, 0);
|
10280
10533
|
return this;
|
@@ -10574,9 +10827,11 @@ Ember.Set.create = function(items) {
|
|
10574
10827
|
}
|
10575
10828
|
};
|
10576
10829
|
|
10577
|
-
})(
|
10830
|
+
})();
|
10831
|
+
|
10832
|
+
|
10578
10833
|
|
10579
|
-
(function(
|
10834
|
+
(function() {
|
10580
10835
|
// ==========================================================================
|
10581
10836
|
// Project: Ember Runtime
|
10582
10837
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -10594,9 +10849,11 @@ Ember.Object = Ember.CoreObject.extend(Ember.Observable);
|
|
10594
10849
|
|
10595
10850
|
|
10596
10851
|
|
10597
|
-
})(
|
10852
|
+
})();
|
10853
|
+
|
10854
|
+
|
10598
10855
|
|
10599
|
-
(function(
|
10856
|
+
(function() {
|
10600
10857
|
// ==========================================================================
|
10601
10858
|
// Project: Ember Runtime
|
10602
10859
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -10641,9 +10898,11 @@ Ember.Namespace = Ember.Object.extend({
|
|
10641
10898
|
Ember.Namespace.NAMESPACES = [Ember];
|
10642
10899
|
Ember.Namespace.PROCESSED = false;
|
10643
10900
|
|
10644
|
-
})(
|
10901
|
+
})();
|
10902
|
+
|
10903
|
+
|
10645
10904
|
|
10646
|
-
(function(
|
10905
|
+
(function() {
|
10647
10906
|
// ==========================================================================
|
10648
10907
|
// Project: Ember Runtime
|
10649
10908
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -10675,9 +10934,11 @@ Ember.Namespace.PROCESSED = false;
|
|
10675
10934
|
Ember.Application = Ember.Namespace.extend();
|
10676
10935
|
|
10677
10936
|
|
10678
|
-
})(
|
10937
|
+
})();
|
10938
|
+
|
10939
|
+
|
10679
10940
|
|
10680
|
-
(function(
|
10941
|
+
(function() {
|
10681
10942
|
// ==========================================================================
|
10682
10943
|
// Project: Ember Runtime
|
10683
10944
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -10738,7 +10999,7 @@ Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,
|
|
10738
10999
|
This method will only be called if content is non-null.
|
10739
11000
|
|
10740
11001
|
@param {Number} idx
|
10741
|
-
The index to
|
11002
|
+
The index to retrieve.
|
10742
11003
|
|
10743
11004
|
@returns {Object} the value or undefined if none found
|
10744
11005
|
*/
|
@@ -10828,9 +11089,11 @@ Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,
|
|
10828
11089
|
|
10829
11090
|
|
10830
11091
|
|
10831
|
-
})(
|
11092
|
+
})();
|
11093
|
+
|
11094
|
+
|
10832
11095
|
|
10833
|
-
(function(
|
11096
|
+
(function() {
|
10834
11097
|
// ==========================================================================
|
10835
11098
|
// Project: Ember Runtime
|
10836
11099
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -11031,9 +11294,11 @@ Ember.EachProxy = Ember.Object.extend({
|
|
11031
11294
|
|
11032
11295
|
|
11033
11296
|
|
11034
|
-
})(
|
11297
|
+
})();
|
11298
|
+
|
11299
|
+
|
11035
11300
|
|
11036
|
-
(function(
|
11301
|
+
(function() {
|
11037
11302
|
// ==========================================================================
|
11038
11303
|
// Project: Ember Runtime
|
11039
11304
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -11177,9 +11442,11 @@ if (Ember.EXTEND_PROTOTYPES) Ember.NativeArray.activate();
|
|
11177
11442
|
|
11178
11443
|
|
11179
11444
|
|
11180
|
-
})(
|
11445
|
+
})();
|
11446
|
+
|
11447
|
+
|
11181
11448
|
|
11182
|
-
(function(
|
11449
|
+
(function() {
|
11183
11450
|
/**
|
11184
11451
|
JavaScript (before ES6) does not have a Map implementation. Objects,
|
11185
11452
|
which are often used as dictionaries, may only have Strings as keys.
|
@@ -11378,20 +11645,24 @@ Map.prototype = {
|
|
11378
11645
|
}
|
11379
11646
|
};
|
11380
11647
|
|
11381
|
-
})(
|
11648
|
+
})();
|
11649
|
+
|
11650
|
+
|
11382
11651
|
|
11383
|
-
(function(
|
11652
|
+
(function() {
|
11384
11653
|
// ==========================================================================
|
11385
11654
|
// Project: Ember Runtime
|
11386
11655
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
11387
11656
|
// License: Licensed under MIT license (see license.js)
|
11388
11657
|
// ==========================================================================
|
11389
11658
|
|
11390
|
-
})(
|
11659
|
+
})();
|
11660
|
+
|
11661
|
+
|
11391
11662
|
|
11392
|
-
(function(
|
11663
|
+
(function() {
|
11393
11664
|
// ==========================================================================
|
11394
|
-
// Project: Ember
|
11665
|
+
// Project: Ember Runtime
|
11395
11666
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
11396
11667
|
// License: Licensed under MIT license (see license.js)
|
11397
11668
|
// ==========================================================================
|
@@ -11436,22 +11707,26 @@ Map.prototype = {
|
|
11436
11707
|
|
11437
11708
|
Ember.ArrayController = Ember.ArrayProxy.extend();
|
11438
11709
|
|
11439
|
-
})(
|
11710
|
+
})();
|
11711
|
+
|
11712
|
+
|
11713
|
+
|
11714
|
+
(function() {
|
11715
|
+
|
11716
|
+
})();
|
11440
11717
|
|
11441
|
-
(function(exports) {
|
11442
11718
|
|
11443
|
-
})({});
|
11444
11719
|
|
11445
|
-
(function(
|
11720
|
+
(function() {
|
11446
11721
|
// ==========================================================================
|
11447
11722
|
// Project: Ember Runtime
|
11448
11723
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
11449
11724
|
// License: Licensed under MIT license (see license.js)
|
11450
11725
|
// ==========================================================================
|
11451
11726
|
|
11452
|
-
})(
|
11727
|
+
})();
|
11453
11728
|
|
11454
|
-
(function(
|
11729
|
+
(function() {
|
11455
11730
|
// ==========================================================================
|
11456
11731
|
// Project: Ember - JavaScript Application Framework
|
11457
11732
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -11459,12 +11734,14 @@ Ember.ArrayController = Ember.ArrayProxy.extend();
|
|
11459
11734
|
// License: Licensed under MIT license (see license.js)
|
11460
11735
|
// ==========================================================================
|
11461
11736
|
|
11462
|
-
ember_assert("Ember requires jQuery 1.6 or 1.7", window.jQuery && window.jQuery().jquery.match(/^1\.[67](
|
11737
|
+
ember_assert("Ember requires jQuery 1.6 or 1.7", window.jQuery && window.jQuery().jquery.match(/^1\.[67](\.\d+)?(pre|rc\d?)?/));
|
11463
11738
|
Ember.$ = window.jQuery;
|
11464
11739
|
|
11465
|
-
})(
|
11740
|
+
})();
|
11741
|
+
|
11742
|
+
|
11466
11743
|
|
11467
|
-
(function(
|
11744
|
+
(function() {
|
11468
11745
|
// ==========================================================================
|
11469
11746
|
// Project: Ember - JavaScript Application Framework
|
11470
11747
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -11476,6 +11753,7 @@ var get = Ember.get, set = Ember.set;
|
|
11476
11753
|
var forEach = Ember.ArrayUtils.forEach;
|
11477
11754
|
var indexOf = Ember.ArrayUtils.indexOf;
|
11478
11755
|
|
11756
|
+
/** @private */
|
11479
11757
|
var ClassSet = function() {
|
11480
11758
|
this.seen = {};
|
11481
11759
|
this.list = [];
|
@@ -11813,13 +12091,13 @@ Ember._RenderBuffer.prototype =
|
|
11813
12091
|
|
11814
12092
|
openTag = ["<" + tag];
|
11815
12093
|
|
11816
|
-
if (id) { openTag.push('id="' + id + '"'); }
|
11817
|
-
if (classes) { openTag.push('class="' + classes.toDOM() + '"'); }
|
12094
|
+
if (id) { openTag.push('id="' + this._escapeAttribute(id) + '"'); }
|
12095
|
+
if (classes) { openTag.push('class="' + this._escapeAttribute(classes.toDOM()) + '"'); }
|
11818
12096
|
|
11819
12097
|
if (style) {
|
11820
12098
|
for (prop in style) {
|
11821
12099
|
if (style.hasOwnProperty(prop)) {
|
11822
|
-
styleBuffer += (prop + ':' + style[prop] + ';');
|
12100
|
+
styleBuffer += (prop + ':' + this._escapeAttribute(style[prop]) + ';');
|
11823
12101
|
}
|
11824
12102
|
}
|
11825
12103
|
|
@@ -11829,7 +12107,7 @@ Ember._RenderBuffer.prototype =
|
|
11829
12107
|
if (attrs) {
|
11830
12108
|
for (prop in attrs) {
|
11831
12109
|
if (attrs.hasOwnProperty(prop)) {
|
11832
|
-
openTag.push(prop + '="' + attrs[prop] + '"');
|
12110
|
+
openTag.push(prop + '="' + this._escapeAttribute(attrs[prop]) + '"');
|
11833
12111
|
}
|
11834
12112
|
}
|
11835
12113
|
}
|
@@ -11849,13 +12127,24 @@ Ember._RenderBuffer.prototype =
|
|
11849
12127
|
} else {
|
11850
12128
|
return content;
|
11851
12129
|
}
|
12130
|
+
},
|
12131
|
+
|
12132
|
+
_escapeAttribute: function(string) {
|
12133
|
+
// Escaping only double quotes is probably sufficient, but it can't hurt to do a few more
|
12134
|
+
return string.replace(/&/g, '&')
|
12135
|
+
.replace(/</g, '<')
|
12136
|
+
.replace(/>/g, '>')
|
12137
|
+
.replace(/'/g, ''')
|
12138
|
+
.replace(/"/g, '"');
|
11852
12139
|
}
|
11853
12140
|
|
11854
12141
|
};
|
11855
12142
|
|
11856
|
-
})(
|
12143
|
+
})();
|
12144
|
+
|
11857
12145
|
|
11858
|
-
|
12146
|
+
|
12147
|
+
(function() {
|
11859
12148
|
// ==========================================================================
|
11860
12149
|
// Project: Ember - JavaScript Application Framework
|
11861
12150
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -12046,9 +12335,11 @@ Ember.EventDispatcher = Ember.Object.extend(
|
|
12046
12335
|
}
|
12047
12336
|
});
|
12048
12337
|
|
12049
|
-
})(
|
12338
|
+
})();
|
12339
|
+
|
12050
12340
|
|
12051
|
-
|
12341
|
+
|
12342
|
+
(function() {
|
12052
12343
|
// ==========================================================================
|
12053
12344
|
// Project: Ember - JavaScript Application Framework
|
12054
12345
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -12081,7 +12372,6 @@ var get = Ember.get, set = Ember.set;
|
|
12081
12372
|
You only need to specify the root if your page contains multiple instances
|
12082
12373
|
of Ember.Application.
|
12083
12374
|
|
12084
|
-
@since Ember 2.0
|
12085
12375
|
@extends Ember.Object
|
12086
12376
|
*/
|
12087
12377
|
Ember.Application = Ember.Namespace.extend(
|
@@ -12157,9 +12447,11 @@ Ember.Application = Ember.Namespace.extend(
|
|
12157
12447
|
|
12158
12448
|
|
12159
12449
|
|
12160
|
-
})(
|
12450
|
+
})();
|
12451
|
+
|
12161
12452
|
|
12162
|
-
|
12453
|
+
|
12454
|
+
(function() {
|
12163
12455
|
// ==========================================================================
|
12164
12456
|
// Project: Ember - JavaScript Application Framework
|
12165
12457
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -12172,9 +12464,11 @@ Ember.Application = Ember.Namespace.extend(
|
|
12172
12464
|
var queues = Ember.run.queues;
|
12173
12465
|
queues.splice(Ember.$.inArray('actions', queues)+1, 0, 'render');
|
12174
12466
|
|
12175
|
-
})(
|
12467
|
+
})();
|
12468
|
+
|
12176
12469
|
|
12177
|
-
|
12470
|
+
|
12471
|
+
(function() {
|
12178
12472
|
// ==========================================================================
|
12179
12473
|
// Project: Ember - JavaScript Application Framework
|
12180
12474
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -12182,9 +12476,11 @@ queues.splice(Ember.$.inArray('actions', queues)+1, 0, 'render');
|
|
12182
12476
|
// License: Licensed under MIT license (see license.js)
|
12183
12477
|
// ==========================================================================
|
12184
12478
|
|
12185
|
-
})(
|
12479
|
+
})();
|
12480
|
+
|
12186
12481
|
|
12187
|
-
|
12482
|
+
|
12483
|
+
(function() {
|
12188
12484
|
// ==========================================================================
|
12189
12485
|
// Project: Ember - JavaScript Application Framework
|
12190
12486
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -12306,9 +12602,17 @@ Ember.View = Ember.Object.extend(Ember.Evented,
|
|
12306
12602
|
return template || get(this, 'defaultTemplate');
|
12307
12603
|
}).property('templateName').cacheable(),
|
12308
12604
|
|
12605
|
+
/**
|
12606
|
+
The controller managing this view. If this property is set, it will be made
|
12607
|
+
made available for use by the template.
|
12608
|
+
|
12609
|
+
@type Object
|
12610
|
+
*/
|
12611
|
+
controller: null,
|
12612
|
+
|
12309
12613
|
/**
|
12310
12614
|
A view may contain a layout. A layout is a regular template but
|
12311
|
-
|
12615
|
+
supersedes the `template` property during rendering. It is the
|
12312
12616
|
responsibility of the layout template to retrieve the `template`
|
12313
12617
|
property from the view and render it in the correct location.
|
12314
12618
|
|
@@ -12353,9 +12657,39 @@ Ember.View = Ember.Object.extend(Ember.Evented,
|
|
12353
12657
|
@type Object
|
12354
12658
|
*/
|
12355
12659
|
templateContext: Ember.computed(function(key, value) {
|
12356
|
-
|
12660
|
+
if (arguments.length === 2) {
|
12661
|
+
set(this, '_templateContext', value);
|
12662
|
+
return value;
|
12663
|
+
} else {
|
12664
|
+
return get(this, '_templateContext');
|
12665
|
+
}
|
12357
12666
|
}).cacheable(),
|
12358
12667
|
|
12668
|
+
/**
|
12669
|
+
@private
|
12670
|
+
|
12671
|
+
Private copy of the view's template context. This can be set directly
|
12672
|
+
by Handlebars without triggering the observer that causes the view
|
12673
|
+
to be re-rendered.
|
12674
|
+
*/
|
12675
|
+
_templateContext: Ember.computed(function(key, value) {
|
12676
|
+
if (arguments.length === 2) {
|
12677
|
+
return value;
|
12678
|
+
} else {
|
12679
|
+
return this;
|
12680
|
+
}
|
12681
|
+
}).cacheable(),
|
12682
|
+
|
12683
|
+
/**
|
12684
|
+
If a value that affects template rendering changes, the view should be
|
12685
|
+
re-rendered to reflect the new value.
|
12686
|
+
|
12687
|
+
@private
|
12688
|
+
*/
|
12689
|
+
_displayPropertyDidChange: Ember.observer(function() {
|
12690
|
+
this.rerender();
|
12691
|
+
}, 'templateContext', 'controller'),
|
12692
|
+
|
12359
12693
|
/**
|
12360
12694
|
If the view is currently inserted into the DOM of a parent view, this
|
12361
12695
|
property will point to the parent of the view.
|
@@ -12511,8 +12845,23 @@ Ember.View = Ember.Object.extend(Ember.Evented,
|
|
12511
12845
|
var template = get(this, 'layout') || get(this, 'template');
|
12512
12846
|
|
12513
12847
|
if (template) {
|
12514
|
-
var context = get(this, '
|
12515
|
-
|
12848
|
+
var context = get(this, '_templateContext'),
|
12849
|
+
templateData = this.get('templateData'),
|
12850
|
+
controller = this.get('controller');
|
12851
|
+
|
12852
|
+
var data = {
|
12853
|
+
view: this,
|
12854
|
+
buffer: buffer,
|
12855
|
+
isRenderData: true,
|
12856
|
+
keywords: {
|
12857
|
+
view: get(this, 'concreteView')
|
12858
|
+
}
|
12859
|
+
};
|
12860
|
+
|
12861
|
+
// If the view has a controller specified, make it available to the
|
12862
|
+
// template. If not, pass along the parent template's controller,
|
12863
|
+
// if it exists.
|
12864
|
+
data.keywords.controller = controller || (templateData && templateData.keywords.controller);
|
12516
12865
|
|
12517
12866
|
// Invoke the template with the provided template context, which
|
12518
12867
|
// is the view by default. A hash of data is also passed that provides
|
@@ -13479,11 +13828,14 @@ Ember.View = Ember.Object.extend(Ember.Evented,
|
|
13479
13828
|
@test in createChildViews
|
13480
13829
|
*/
|
13481
13830
|
createChildView: function(view, attrs) {
|
13831
|
+
var coreAttrs;
|
13832
|
+
|
13482
13833
|
if (Ember.View.detect(view)) {
|
13834
|
+
coreAttrs = { _parentView: this };
|
13483
13835
|
if (attrs) {
|
13484
|
-
view = view.
|
13836
|
+
view = view.create(coreAttrs, attrs);
|
13485
13837
|
} else {
|
13486
|
-
view = view.
|
13838
|
+
view = view.create(coreAttrs);
|
13487
13839
|
}
|
13488
13840
|
|
13489
13841
|
var viewName = view.viewName;
|
@@ -13495,6 +13847,7 @@ Ember.View = Ember.Object.extend(Ember.Evented,
|
|
13495
13847
|
ember_assert('must pass instance of View', view instanceof Ember.View);
|
13496
13848
|
set(view, '_parentView', this);
|
13497
13849
|
}
|
13850
|
+
|
13498
13851
|
return view;
|
13499
13852
|
},
|
13500
13853
|
|
@@ -13579,7 +13932,9 @@ Ember.View = Ember.Object.extend(Ember.Evented,
|
|
13579
13932
|
also call methods with the given name.
|
13580
13933
|
*/
|
13581
13934
|
fire: function(name) {
|
13582
|
-
this[name]
|
13935
|
+
if (this[name]) {
|
13936
|
+
this[name].apply(this, [].slice.call(arguments, 1));
|
13937
|
+
}
|
13583
13938
|
this._super.apply(this, arguments);
|
13584
13939
|
},
|
13585
13940
|
|
@@ -13691,9 +14046,11 @@ Ember.View.applyAttributeBindings = function(elem, name, value) {
|
|
13691
14046
|
}
|
13692
14047
|
};
|
13693
14048
|
|
13694
|
-
})(
|
14049
|
+
})();
|
14050
|
+
|
14051
|
+
|
13695
14052
|
|
13696
|
-
(function(
|
14053
|
+
(function() {
|
13697
14054
|
// ==========================================================================
|
13698
14055
|
// Project: Ember - JavaScript Application Framework
|
13699
14056
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -13728,9 +14085,11 @@ Ember.View.reopen({
|
|
13728
14085
|
states: Ember.View.states
|
13729
14086
|
});
|
13730
14087
|
|
13731
|
-
})(
|
14088
|
+
})();
|
14089
|
+
|
14090
|
+
|
13732
14091
|
|
13733
|
-
(function(
|
14092
|
+
(function() {
|
13734
14093
|
// ==========================================================================
|
13735
14094
|
// Project: Ember - JavaScript Application Framework
|
13736
14095
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -13783,9 +14142,11 @@ Ember.View.states.preRender = {
|
|
13783
14142
|
}
|
13784
14143
|
};
|
13785
14144
|
|
13786
|
-
})(
|
14145
|
+
})();
|
14146
|
+
|
14147
|
+
|
13787
14148
|
|
13788
|
-
(function(
|
14149
|
+
(function() {
|
13789
14150
|
// ==========================================================================
|
13790
14151
|
// Project: Ember - JavaScript Application Framework
|
13791
14152
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -13869,9 +14230,11 @@ Ember.View.states.inBuffer = {
|
|
13869
14230
|
};
|
13870
14231
|
|
13871
14232
|
|
13872
|
-
})(
|
14233
|
+
})();
|
14234
|
+
|
14235
|
+
|
13873
14236
|
|
13874
|
-
(function(
|
14237
|
+
(function() {
|
13875
14238
|
// ==========================================================================
|
13876
14239
|
// Project: Ember - JavaScript Application Framework
|
13877
14240
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -13928,6 +14291,13 @@ Ember.View.states.hasElement = {
|
|
13928
14291
|
},
|
13929
14292
|
|
13930
14293
|
empty: function(view) {
|
14294
|
+
var _childViews = get(view, '_childViews'), len, idx;
|
14295
|
+
if (_childViews) {
|
14296
|
+
len = get(_childViews, 'length');
|
14297
|
+
for (idx = 0; idx < len; idx++) {
|
14298
|
+
_childViews[idx]._notifyWillDestroyElement();
|
14299
|
+
}
|
14300
|
+
}
|
13931
14301
|
view.domManager.empty(view);
|
13932
14302
|
},
|
13933
14303
|
|
@@ -13950,9 +14320,11 @@ Ember.View.states.inDOM = {
|
|
13950
14320
|
}
|
13951
14321
|
};
|
13952
14322
|
|
13953
|
-
})(
|
14323
|
+
})();
|
14324
|
+
|
14325
|
+
|
13954
14326
|
|
13955
|
-
(function(
|
14327
|
+
(function() {
|
13956
14328
|
// ==========================================================================
|
13957
14329
|
// Project: Ember - JavaScript Application Framework
|
13958
14330
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -13987,9 +14359,11 @@ Ember.View.states.destroyed = {
|
|
13987
14359
|
};
|
13988
14360
|
|
13989
14361
|
|
13990
|
-
})(
|
14362
|
+
})();
|
14363
|
+
|
14364
|
+
|
13991
14365
|
|
13992
|
-
(function(
|
14366
|
+
(function() {
|
13993
14367
|
// ==========================================================================
|
13994
14368
|
// Project: Ember - JavaScript Application Framework
|
13995
14369
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -13997,9 +14371,11 @@ Ember.View.states.destroyed = {
|
|
13997
14371
|
// License: Licensed under MIT license (see license.js)
|
13998
14372
|
// ==========================================================================
|
13999
14373
|
|
14000
|
-
})(
|
14374
|
+
})();
|
14375
|
+
|
14376
|
+
|
14001
14377
|
|
14002
|
-
(function(
|
14378
|
+
(function() {
|
14003
14379
|
// ==========================================================================
|
14004
14380
|
// Project: Ember - JavaScript Application Framework
|
14005
14381
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -14013,6 +14389,177 @@ var childViewsProperty = Ember.computed(function() {
|
|
14013
14389
|
return get(this, '_childViews');
|
14014
14390
|
}).property('_childViews').cacheable();
|
14015
14391
|
|
14392
|
+
/**
|
14393
|
+
@class
|
14394
|
+
@extends Ember.View
|
14395
|
+
|
14396
|
+
A `ContainerView` is an `Ember.View` subclass that allows for manual or programatic
|
14397
|
+
management of a view's `childViews` array that will correctly update the `ContainerView`
|
14398
|
+
instance's rendered DOM representation.
|
14399
|
+
|
14400
|
+
## Setting Initial Child Views
|
14401
|
+
The initial array of child views can be set in one of two ways. You can provide
|
14402
|
+
a `childViews` property at creation time that contains instance of `Ember.View`:
|
14403
|
+
|
14404
|
+
|
14405
|
+
aContainer = Ember.ContainerView.create({
|
14406
|
+
childViews: [Ember.View.create(), Ember.View.create()]
|
14407
|
+
})
|
14408
|
+
|
14409
|
+
You can also provide a list of property names whose values are instances of `Ember.View`:
|
14410
|
+
|
14411
|
+
aContainer = Ember.ContainerView.create({
|
14412
|
+
childViews: ['aView', 'bView', 'cView'],
|
14413
|
+
aView: Ember.View.create(),
|
14414
|
+
bView: Ember.View.create()
|
14415
|
+
cView: Ember.View.create()
|
14416
|
+
})
|
14417
|
+
|
14418
|
+
The two strategies can be combined:
|
14419
|
+
|
14420
|
+
aContainer = Ember.ContainerView.create({
|
14421
|
+
childViews: ['aView', Ember.View.create()],
|
14422
|
+
aView: Ember.View.create()
|
14423
|
+
})
|
14424
|
+
|
14425
|
+
Each child view's rendering will be inserted into the container's rendered HTML in the same
|
14426
|
+
order as its position in the `childViews` property.
|
14427
|
+
|
14428
|
+
## Adding and Removing Child Views
|
14429
|
+
The views in a container's `childViews` array should be added and removed by manipulating
|
14430
|
+
the `childViews` property directly.
|
14431
|
+
|
14432
|
+
To remove a view pass that view into a `removeObject` call on the container's `childViews` property.
|
14433
|
+
|
14434
|
+
Given an empty `<body>` the following code
|
14435
|
+
|
14436
|
+
aContainer = Ember.ContainerView.create({
|
14437
|
+
classNames: ['the-container'],
|
14438
|
+
childViews: ['aView', 'bView'],
|
14439
|
+
aView: Ember.View.create({
|
14440
|
+
template: Ember.Handlebars.compile("A")
|
14441
|
+
}),
|
14442
|
+
bView: Ember.View.create({
|
14443
|
+
template: Ember.Handlebars.compile("B")
|
14444
|
+
})
|
14445
|
+
})
|
14446
|
+
|
14447
|
+
aContainer.appendTo('body')
|
14448
|
+
|
14449
|
+
Results in the HTML
|
14450
|
+
|
14451
|
+
<div class="ember-view the-container">
|
14452
|
+
<div class="ember-view">A</div>
|
14453
|
+
<div class="ember-view">B</div>
|
14454
|
+
</div>
|
14455
|
+
|
14456
|
+
Removing a view
|
14457
|
+
|
14458
|
+
aContainer.get('childViews') // [aContainer.aView, aContainer.bView]
|
14459
|
+
aContainer.get('childViews').removeObject(aContainer.get('bView'))
|
14460
|
+
aContainer.get('childViews') // [aContainer.aView]
|
14461
|
+
|
14462
|
+
Will result in the following HTML
|
14463
|
+
|
14464
|
+
<div class="ember-view the-container">
|
14465
|
+
<div class="ember-view">A</div>
|
14466
|
+
</div>
|
14467
|
+
|
14468
|
+
|
14469
|
+
Similarly, adding a child view is accomplished by adding `Ember.View` instances to the
|
14470
|
+
container's `childViews` property.
|
14471
|
+
|
14472
|
+
Given an empty `<body>` the following code
|
14473
|
+
|
14474
|
+
aContainer = Ember.ContainerView.create({
|
14475
|
+
classNames: ['the-container'],
|
14476
|
+
childViews: ['aView', 'bView'],
|
14477
|
+
aView: Ember.View.create({
|
14478
|
+
template: Ember.Handlebars.compile("A")
|
14479
|
+
}),
|
14480
|
+
bView: Ember.View.create({
|
14481
|
+
template: Ember.Handlebars.compile("B")
|
14482
|
+
})
|
14483
|
+
})
|
14484
|
+
|
14485
|
+
aContainer.appendTo('body')
|
14486
|
+
|
14487
|
+
Results in the HTML
|
14488
|
+
|
14489
|
+
<div class="ember-view the-container">
|
14490
|
+
<div class="ember-view">A</div>
|
14491
|
+
<div class="ember-view">B</div>
|
14492
|
+
</div>
|
14493
|
+
|
14494
|
+
Adding a view
|
14495
|
+
|
14496
|
+
AnotherViewClass = Ember.View.extend({
|
14497
|
+
template: Ember.Handlebars.compile("Another view")
|
14498
|
+
})
|
14499
|
+
|
14500
|
+
aContainer.get('childViews') // [aContainer.aView, aContainer.bView]
|
14501
|
+
aContainer.get('childViews').pushObject(AnotherViewClass.create())
|
14502
|
+
aContainer.get('childViews') // [aContainer.aView, <AnotherViewClass instance>]
|
14503
|
+
|
14504
|
+
Will result in the following HTML
|
14505
|
+
|
14506
|
+
<div class="ember-view the-container">
|
14507
|
+
<div class="ember-view">A</div>
|
14508
|
+
<div class="ember-view">Another view</div>
|
14509
|
+
</div>
|
14510
|
+
|
14511
|
+
|
14512
|
+
Direct manipulation of childViews presence or absence in the DOM via calls to
|
14513
|
+
`remove` or `removeFromParent` or calls to a container's `removeChild` may not behave
|
14514
|
+
correctly.
|
14515
|
+
|
14516
|
+
Calling `remove()` on a child view will remove the view's HTML, but it will remain as part of its
|
14517
|
+
container's `childView`s property.
|
14518
|
+
|
14519
|
+
Calling `removeChild()` on the container will remove the passed view instance from the container's
|
14520
|
+
`childView`s but keep its HTML within the container's rendered view.
|
14521
|
+
|
14522
|
+
Calling `removeFromParent()` behaves as expected but should be avoided in favor of direct
|
14523
|
+
manipulation of a container's `childViews` property.
|
14524
|
+
|
14525
|
+
aContainer = Ember.ContainerView.create({
|
14526
|
+
classNames: ['the-container'],
|
14527
|
+
childViews: ['aView', 'bView'],
|
14528
|
+
aView: Ember.View.create({
|
14529
|
+
template: Ember.Handlebars.compile("A")
|
14530
|
+
}),
|
14531
|
+
bView: Ember.View.create({
|
14532
|
+
template: Ember.Handlebars.compile("B")
|
14533
|
+
})
|
14534
|
+
})
|
14535
|
+
|
14536
|
+
aContainer.appendTo('body')
|
14537
|
+
|
14538
|
+
Results in the HTML
|
14539
|
+
|
14540
|
+
<div class="ember-view the-container">
|
14541
|
+
<div class="ember-view">A</div>
|
14542
|
+
<div class="ember-view">B</div>
|
14543
|
+
</div>
|
14544
|
+
|
14545
|
+
Calling `aContainer.get('aView').removeFromParent()` will result in the following HTML
|
14546
|
+
|
14547
|
+
<div class="ember-view the-container">
|
14548
|
+
<div class="ember-view">A</div>
|
14549
|
+
<div class="ember-view">B</div>
|
14550
|
+
</div>
|
14551
|
+
|
14552
|
+
And the `Ember.View` instance stored in `aContainer.aView` will be removed from `aContainer`'s
|
14553
|
+
`childViews` array.
|
14554
|
+
|
14555
|
+
|
14556
|
+
## Templates and Layout
|
14557
|
+
A `template`, `templateName`, `defaultTempalte`, `layout`, `layoutName` or `defaultLayout`
|
14558
|
+
property on a container view will not result in the template or layout being rendered.
|
14559
|
+
The HTML contents of a `Ember.ContainerView`'s DOM representation will only be the rendered HTML
|
14560
|
+
of its child views.
|
14561
|
+
*/
|
14562
|
+
|
14016
14563
|
Ember.ContainerView = Ember.View.extend({
|
14017
14564
|
|
14018
14565
|
init: function() {
|
@@ -14092,7 +14639,7 @@ Ember.ContainerView = Ember.View.extend({
|
|
14092
14639
|
if (removed === 0) { return; }
|
14093
14640
|
|
14094
14641
|
var changedViews = views.slice(start, start+removed);
|
14095
|
-
this.
|
14642
|
+
this.initializeViews(changedViews, null, null);
|
14096
14643
|
|
14097
14644
|
this.invokeForState('childViewsWillChange', views, start, removed);
|
14098
14645
|
},
|
@@ -14119,15 +14666,16 @@ Ember.ContainerView = Ember.View.extend({
|
|
14119
14666
|
if (added === 0) return;
|
14120
14667
|
|
14121
14668
|
var changedViews = views.slice(start, start+added);
|
14122
|
-
this.
|
14669
|
+
this.initializeViews(changedViews, this, get(this, 'templateData'));
|
14123
14670
|
|
14124
14671
|
// Let the current state handle the changes
|
14125
14672
|
this.invokeForState('childViewsDidChange', views, start, added);
|
14126
14673
|
},
|
14127
14674
|
|
14128
|
-
|
14675
|
+
initializeViews: function(views, parentView, templateData) {
|
14129
14676
|
forEach(views, function(view) {
|
14130
14677
|
set(view, '_parentView', parentView);
|
14678
|
+
set(view, 'templateData', templateData);
|
14131
14679
|
});
|
14132
14680
|
},
|
14133
14681
|
|
@@ -14214,9 +14762,11 @@ Ember.ContainerView.reopen({
|
|
14214
14762
|
states: Ember.ContainerView.states
|
14215
14763
|
});
|
14216
14764
|
|
14217
|
-
})(
|
14765
|
+
})();
|
14766
|
+
|
14767
|
+
|
14218
14768
|
|
14219
|
-
(function(
|
14769
|
+
(function() {
|
14220
14770
|
// ==========================================================================
|
14221
14771
|
// Project: Ember - JavaScript Application Framework
|
14222
14772
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -14228,24 +14778,132 @@ var get = Ember.get, set = Ember.set, fmt = Ember.String.fmt;
|
|
14228
14778
|
/**
|
14229
14779
|
@class
|
14230
14780
|
@since Ember 0.9
|
14231
|
-
@extends Ember.
|
14232
|
-
|
14233
|
-
Ember.CollectionView
|
14234
|
-
|
14781
|
+
@extends Ember.ContainerView
|
14782
|
+
|
14783
|
+
`Ember.CollectionView` is an `Ember.View` descendent responsible for managing a
|
14784
|
+
collection (an array or array-like object) by maintaing a child view object and
|
14785
|
+
associated DOM representation for each item in the array and ensuring that child
|
14786
|
+
views and their associated rendered HTML are updated when items in the array
|
14787
|
+
are added, removed, or replaced.
|
14235
14788
|
|
14236
|
-
|
14237
|
-
|
14789
|
+
## Setting content
|
14790
|
+
The managed collection of objects is referenced as the `Ember.CollectionView` instance's
|
14791
|
+
`content` property.
|
14238
14792
|
|
14239
|
-
|
14240
|
-
|
14241
|
-
|
14242
|
-
content: null,
|
14793
|
+
someItemsView = Ember.CollectionView.create({
|
14794
|
+
content: ['A', 'B','C']
|
14795
|
+
})
|
14243
14796
|
|
14244
|
-
|
14245
|
-
|
14797
|
+
The view for each item in the collection will have its `content` property set
|
14798
|
+
to the item.
|
14246
14799
|
|
14247
|
-
|
14248
|
-
|
14800
|
+
## Specifying itemViewClass
|
14801
|
+
By default the view class for each item in the managed collection will be an instance
|
14802
|
+
of `Ember.View`. You can supply a different class by setting the `CollectionView`'s
|
14803
|
+
`itemViewClass` property.
|
14804
|
+
|
14805
|
+
Given an empty `<body>` and the following code:
|
14806
|
+
|
14807
|
+
|
14808
|
+
someItemsView = Ember.CollectionView.create({
|
14809
|
+
classNames: ['a-collection'],
|
14810
|
+
content: ['A','B','C'],
|
14811
|
+
itemViewClass: Ember.View.extend({
|
14812
|
+
template: Ember.Handlebars.compile("the letter: {{content}}")
|
14813
|
+
})
|
14814
|
+
})
|
14815
|
+
|
14816
|
+
someItemsView.appendTo('body')
|
14817
|
+
|
14818
|
+
Will result in the following HTML structure
|
14819
|
+
|
14820
|
+
<div class="ember-view a-collection">
|
14821
|
+
<div class="ember-view">the letter: A</div>
|
14822
|
+
<div class="ember-view">the letter: B</div>
|
14823
|
+
<div class="ember-view">the letter: C</div>
|
14824
|
+
</div>
|
14825
|
+
|
14826
|
+
|
14827
|
+
## Automatic matching of parent/child tagNames
|
14828
|
+
Setting the `tagName` property of a `CollectionView` to any of
|
14829
|
+
"ul", "ol", "table", "thead", "tbody", "tfoot", "tr", or "select" will result
|
14830
|
+
in the item views receiving an appropriately matched `tagName` property.
|
14831
|
+
|
14832
|
+
|
14833
|
+
Given an empty `<body>` and the following code:
|
14834
|
+
|
14835
|
+
anUndorderedListView = Ember.CollectionView.create({
|
14836
|
+
tagName: 'ul',
|
14837
|
+
content: ['A','B','C'],
|
14838
|
+
itemViewClass: Ember.View.extend({
|
14839
|
+
template: Ember.Handlebars.compile("the letter: {{content}}")
|
14840
|
+
})
|
14841
|
+
})
|
14842
|
+
|
14843
|
+
anUndorderedListView.appendTo('body')
|
14844
|
+
|
14845
|
+
Will result in the following HTML structure
|
14846
|
+
|
14847
|
+
<ul class="ember-view a-collection">
|
14848
|
+
<li class="ember-view">the letter: A</li>
|
14849
|
+
<li class="ember-view">the letter: B</li>
|
14850
|
+
<li class="ember-view">the letter: C</li>
|
14851
|
+
</ul>
|
14852
|
+
|
14853
|
+
Additional tagName pairs can be provided by adding to `Ember.CollectionView.CONTAINER_MAP `
|
14854
|
+
|
14855
|
+
Ember.CollectionView.CONTAINER_MAP['article'] = 'section'
|
14856
|
+
|
14857
|
+
|
14858
|
+
## Empty View
|
14859
|
+
You can provide an `Ember.View` subclass to the `Ember.CollectionView` instance as its
|
14860
|
+
`emptyView` property. If the `content` property of a `CollectionView` is set to `null`
|
14861
|
+
or an empty array, an instance of this view will be the `CollectionView`s only child.
|
14862
|
+
|
14863
|
+
aListWithNothing = Ember.CollectionView.create({
|
14864
|
+
classNames: ['nothing']
|
14865
|
+
content: null,
|
14866
|
+
emptyView: Ember.View.extend({
|
14867
|
+
template: Ember.Handlebars.compile("The collection is empty")
|
14868
|
+
})
|
14869
|
+
})
|
14870
|
+
|
14871
|
+
aListWithNothing.appendTo('body')
|
14872
|
+
|
14873
|
+
Will result in the following HTML structure
|
14874
|
+
|
14875
|
+
<div class="ember-view nothing">
|
14876
|
+
<div class="ember-view">
|
14877
|
+
The collection is empty
|
14878
|
+
</div>
|
14879
|
+
</div>
|
14880
|
+
|
14881
|
+
## Adding and Removing items
|
14882
|
+
The `childViews` property of a `CollectionView` should not be directly manipulated. Instead,
|
14883
|
+
add, remove, replace items from its `content` property. This will trigger
|
14884
|
+
appropriate changes to its rendered HTML.
|
14885
|
+
|
14886
|
+
## Use in templates via the `{{collection}}` Ember.Handlebars helper
|
14887
|
+
Ember.Handlebars provides a helper specifically for adding `CollectionView`s to templates.
|
14888
|
+
See `Ember.Handlebars.collection` for more details
|
14889
|
+
|
14890
|
+
*/
|
14891
|
+
Ember.CollectionView = Ember.ContainerView.extend(
|
14892
|
+
/** @scope Ember.CollectionView.prototype */ {
|
14893
|
+
|
14894
|
+
/**
|
14895
|
+
A list of items to be displayed by the Ember.CollectionView.
|
14896
|
+
|
14897
|
+
@type Ember.Array
|
14898
|
+
@default null
|
14899
|
+
*/
|
14900
|
+
content: null,
|
14901
|
+
|
14902
|
+
/**
|
14903
|
+
An optional view to display if content is set to an empty array.
|
14904
|
+
|
14905
|
+
@type Ember.View
|
14906
|
+
@default null
|
14249
14907
|
*/
|
14250
14908
|
emptyView: null,
|
14251
14909
|
|
@@ -14255,6 +14913,7 @@ Ember.CollectionView = Ember.ContainerView.extend(
|
|
14255
14913
|
*/
|
14256
14914
|
itemViewClass: Ember.View,
|
14257
14915
|
|
14916
|
+
/** @private */
|
14258
14917
|
init: function() {
|
14259
14918
|
var ret = this._super();
|
14260
14919
|
this._contentDidChange();
|
@@ -14409,9 +15068,11 @@ Ember.CollectionView.CONTAINER_MAP = {
|
|
14409
15068
|
select: 'option'
|
14410
15069
|
};
|
14411
15070
|
|
14412
|
-
})(
|
15071
|
+
})();
|
15072
|
+
|
15073
|
+
|
14413
15074
|
|
14414
|
-
(function(
|
15075
|
+
(function() {
|
14415
15076
|
// ==========================================================================
|
14416
15077
|
// Project: Ember - JavaScript Application Framework
|
14417
15078
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -14419,9 +15080,11 @@ Ember.CollectionView.CONTAINER_MAP = {
|
|
14419
15080
|
// License: Licensed under MIT license (see license.js)
|
14420
15081
|
// ==========================================================================
|
14421
15082
|
|
14422
|
-
})(
|
15083
|
+
})();
|
15084
|
+
|
15085
|
+
|
14423
15086
|
|
14424
|
-
(function(
|
15087
|
+
(function() {
|
14425
15088
|
// ==========================================================================
|
14426
15089
|
// Project: Ember - JavaScript Application Framework
|
14427
15090
|
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
@@ -14431,9 +15094,9 @@ Ember.CollectionView.CONTAINER_MAP = {
|
|
14431
15094
|
|
14432
15095
|
/*globals jQuery*/
|
14433
15096
|
|
14434
|
-
})(
|
15097
|
+
})();
|
14435
15098
|
|
14436
|
-
(function(
|
15099
|
+
(function() {
|
14437
15100
|
var get = Ember.get, set = Ember.set, getPath = Ember.getPath;
|
14438
15101
|
|
14439
15102
|
Ember.State = Ember.Object.extend({
|
@@ -14501,13 +15164,598 @@ Ember.State = Ember.Object.extend({
|
|
14501
15164
|
exit: Ember.K
|
14502
15165
|
});
|
14503
15166
|
|
14504
|
-
})(
|
15167
|
+
})();
|
15168
|
+
|
14505
15169
|
|
14506
|
-
|
15170
|
+
|
15171
|
+
(function() {
|
14507
15172
|
var get = Ember.get, set = Ember.set, getPath = Ember.getPath, fmt = Ember.String.fmt;
|
14508
15173
|
/**
|
14509
15174
|
@class
|
14510
|
-
|
15175
|
+
|
15176
|
+
StateManager is part of Ember's implementation of a finite state machine. A StateManager
|
15177
|
+
instance manages a number of properties that are instances of `Ember.State`,
|
15178
|
+
tracks the current active state, and triggers callbacks when states have changed.
|
15179
|
+
|
15180
|
+
## Defining States
|
15181
|
+
|
15182
|
+
The states of StateManager can be declared in one of two ways. First, you can define
|
15183
|
+
a `states` property that contains all the states:
|
15184
|
+
|
15185
|
+
managerA = Ember.StateManager.create({
|
15186
|
+
states: {
|
15187
|
+
stateOne: Ember.State.create(),
|
15188
|
+
stateTwo: Ember.State.create()
|
15189
|
+
}
|
15190
|
+
})
|
15191
|
+
|
15192
|
+
managerA.get('states')
|
15193
|
+
// {
|
15194
|
+
// stateOne: Ember.State.create(),
|
15195
|
+
// stateTwo: Ember.State.create()
|
15196
|
+
// }
|
15197
|
+
|
15198
|
+
You can also add instances of `Ember.State` (or an `Ember.State` subclass) directly as properties
|
15199
|
+
of a StateManager. These states will be collected into the `states` property for you.
|
15200
|
+
|
15201
|
+
managerA = Ember.StateManager.create({
|
15202
|
+
stateOne: Ember.State.create(),
|
15203
|
+
stateTwo: Ember.State.create()
|
15204
|
+
})
|
15205
|
+
|
15206
|
+
managerA.get('states')
|
15207
|
+
// {
|
15208
|
+
// stateOne: Ember.State.create(),
|
15209
|
+
// stateTwo: Ember.State.create()
|
15210
|
+
// }
|
15211
|
+
|
15212
|
+
## The Initial State
|
15213
|
+
When created a StateManager instance will immediately enter into the state
|
15214
|
+
defined as its `start` property or the state referenced by name in its
|
15215
|
+
`initialState` property:
|
15216
|
+
|
15217
|
+
managerA = Ember.StateManager.create({
|
15218
|
+
start: Ember.State.create({})
|
15219
|
+
})
|
15220
|
+
|
15221
|
+
managerA.getPath('currentState.name') // 'start'
|
15222
|
+
|
15223
|
+
managerB = Ember.StateManager.create({
|
15224
|
+
initialState: 'beginHere',
|
15225
|
+
beginHere: Ember.State.create({})
|
15226
|
+
})
|
15227
|
+
|
15228
|
+
managerB.getPath('currentState.name') // 'beginHere'
|
15229
|
+
|
15230
|
+
Because it is a property you may also provided a computed function if you wish to derive
|
15231
|
+
an `initialState` programmatically:
|
15232
|
+
|
15233
|
+
managerC = Ember.StateManager.create({
|
15234
|
+
initialState: function(){
|
15235
|
+
if (someLogic) {
|
15236
|
+
return 'active';
|
15237
|
+
} else {
|
15238
|
+
return 'passive';
|
15239
|
+
}
|
15240
|
+
}.property(),
|
15241
|
+
active: Ember.State.create({})
|
15242
|
+
passive: Ember.State.create({})
|
15243
|
+
})
|
15244
|
+
|
15245
|
+
## Moving Between States
|
15246
|
+
A StateManager can have any number of Ember.State objects as properties
|
15247
|
+
and can have a single one of these states as its current state.
|
15248
|
+
|
15249
|
+
Calling `goToState` transitions between states:
|
15250
|
+
|
15251
|
+
robotManager = Ember.StateManager.create({
|
15252
|
+
initialState: 'poweredDown',
|
15253
|
+
poweredDown: Ember.State.create({}),
|
15254
|
+
poweredUp: Ember.State.create({})
|
15255
|
+
})
|
15256
|
+
|
15257
|
+
robotManager.getPath('currentState.name') // 'poweredDown'
|
15258
|
+
robotManager.goToState('poweredUp')
|
15259
|
+
robotManager.getPath('currentState.name') // 'poweredUp'
|
15260
|
+
|
15261
|
+
Before transitioning into a new state the existing `currentState` will have its
|
15262
|
+
`exit` method called with with the StateManager instance as its first argument and
|
15263
|
+
an object representing the the transition as its second argument.
|
15264
|
+
|
15265
|
+
After transitioning into a new state the new `currentState` will have its
|
15266
|
+
`enter` method called with with the StateManager instance as its first argument and
|
15267
|
+
an object representing the the transition as its second argument.
|
15268
|
+
|
15269
|
+
robotManager = Ember.StateManager.create({
|
15270
|
+
initialState: 'poweredDown',
|
15271
|
+
poweredDown: Ember.State.create({
|
15272
|
+
exit: function(stateManager, transition){
|
15273
|
+
console.log("exiting the poweredDown state")
|
15274
|
+
}
|
15275
|
+
}),
|
15276
|
+
poweredUp: Ember.State.create({
|
15277
|
+
enter: function(stateManager, transition){
|
15278
|
+
console.log("entering the poweredUp state. Destroy all humans.")
|
15279
|
+
}
|
15280
|
+
})
|
15281
|
+
})
|
15282
|
+
|
15283
|
+
robotManager.getPath('currentState.name') // 'poweredDown'
|
15284
|
+
robotManager.goToState('poweredUp')
|
15285
|
+
// will log
|
15286
|
+
// 'exiting the poweredDown state'
|
15287
|
+
// 'entering the poweredUp state. Destroy all humans.'
|
15288
|
+
|
15289
|
+
|
15290
|
+
Once a StateManager is already in a state, subsequent attempts to enter that state will
|
15291
|
+
not trigger enter or exit method calls. Attempts to transition into a state that the
|
15292
|
+
manager does not have will result in no changes in the StateManager's current state:
|
15293
|
+
|
15294
|
+
robotManager = Ember.StateManager.create({
|
15295
|
+
initialState: 'poweredDown',
|
15296
|
+
poweredDown: Ember.State.create({
|
15297
|
+
exit: function(stateManager, transition){
|
15298
|
+
console.log("exiting the poweredDown state")
|
15299
|
+
}
|
15300
|
+
}),
|
15301
|
+
poweredUp: Ember.State.create({
|
15302
|
+
enter: function(stateManager, transition){
|
15303
|
+
console.log("entering the poweredUp state. Destroy all humans.")
|
15304
|
+
}
|
15305
|
+
})
|
15306
|
+
})
|
15307
|
+
|
15308
|
+
robotManager.getPath('currentState.name') // 'poweredDown'
|
15309
|
+
robotManager.goToState('poweredUp')
|
15310
|
+
// will log
|
15311
|
+
// 'exiting the poweredDown state'
|
15312
|
+
// 'entering the poweredUp state. Destroy all humans.'
|
15313
|
+
robotManager.goToState('poweredUp') // no logging, no state change
|
15314
|
+
|
15315
|
+
robotManager.goToState('someUnknownState') // silently fails
|
15316
|
+
robotManager.getPath('currentState.name') // 'poweredUp'
|
15317
|
+
|
15318
|
+
|
15319
|
+
Each state property may itself contain properties that are instances of Ember.State.
|
15320
|
+
The StateManager can transition to specific sub-states in a series of goToState method calls or
|
15321
|
+
via a single goToState with the full path to the specific state. The StateManager will also
|
15322
|
+
keep track of the full path to its currentState
|
15323
|
+
|
15324
|
+
|
15325
|
+
robotManager = Ember.StateManager.create({
|
15326
|
+
initialState: 'poweredDown',
|
15327
|
+
poweredDown: Ember.State.create({
|
15328
|
+
charging: Ember.State.create(),
|
15329
|
+
charged: Ember.State.create()
|
15330
|
+
}),
|
15331
|
+
poweredUp: Ember.State.create({
|
15332
|
+
mobile: Ember.State.create(),
|
15333
|
+
stationary: Ember.State.create()
|
15334
|
+
})
|
15335
|
+
})
|
15336
|
+
|
15337
|
+
robotManager.getPath('currentState.name') // 'poweredDown'
|
15338
|
+
|
15339
|
+
robotManager.goToState('poweredUp')
|
15340
|
+
robotManager.getPath('currentState.name') // 'poweredUp'
|
15341
|
+
|
15342
|
+
robotManager.goToState('mobile')
|
15343
|
+
robotManager.getPath('currentState.name') // 'mobile'
|
15344
|
+
|
15345
|
+
// transition via a state path
|
15346
|
+
robotManager.goToState('poweredDown.charging')
|
15347
|
+
robotManager.getPath('currentState.name') // 'charging'
|
15348
|
+
|
15349
|
+
robotManager.getPath('currentState.get.path') // 'poweredDown.charging'
|
15350
|
+
|
15351
|
+
Enter transition methods will be called for each state and nested child state in their
|
15352
|
+
hierarchical order. Exit methods will be called for each state and its nested states in
|
15353
|
+
reverse hierarchical order.
|
15354
|
+
|
15355
|
+
Exit transitions for a parent state are not called when entering into one of its child states,
|
15356
|
+
only when transitioning to a new section of possible states in the hierarchy.
|
15357
|
+
|
15358
|
+
robotManager = Ember.StateManager.create({
|
15359
|
+
initialState: 'poweredDown',
|
15360
|
+
poweredDown: Ember.State.create({
|
15361
|
+
enter: function(){},
|
15362
|
+
exit: function(){
|
15363
|
+
console.log("exited poweredDown state")
|
15364
|
+
},
|
15365
|
+
charging: Ember.State.create({
|
15366
|
+
enter: function(){},
|
15367
|
+
exit: function(){}
|
15368
|
+
}),
|
15369
|
+
charged: Ember.State.create({
|
15370
|
+
enter: function(){
|
15371
|
+
console.log("entered charged state")
|
15372
|
+
},
|
15373
|
+
exit: function(){
|
15374
|
+
console.log("exited charged state")
|
15375
|
+
}
|
15376
|
+
})
|
15377
|
+
}),
|
15378
|
+
poweredUp: Ember.State.create({
|
15379
|
+
enter: function(){
|
15380
|
+
console.log("entered poweredUp state")
|
15381
|
+
},
|
15382
|
+
exit: function(){},
|
15383
|
+
mobile: Ember.State.create({
|
15384
|
+
enter: function(){
|
15385
|
+
console.log("entered mobile state")
|
15386
|
+
},
|
15387
|
+
exit: function(){}
|
15388
|
+
}),
|
15389
|
+
stationary: Ember.State.create({
|
15390
|
+
enter: function(){},
|
15391
|
+
exit: function(){}
|
15392
|
+
})
|
15393
|
+
})
|
15394
|
+
})
|
15395
|
+
|
15396
|
+
|
15397
|
+
robotManager.get('currentState.get.path') // 'poweredDown'
|
15398
|
+
robotManager.goToState('charged')
|
15399
|
+
// logs 'entered charged state'
|
15400
|
+
// but does *not* log 'exited poweredDown state'
|
15401
|
+
robotManager.getPath('currentState.name') // 'charged
|
15402
|
+
|
15403
|
+
robotManager.goToState('poweredUp.mobile')
|
15404
|
+
// logs
|
15405
|
+
// 'exited charged state'
|
15406
|
+
// 'exited poweredDown state'
|
15407
|
+
// 'entered poweredUp state'
|
15408
|
+
// 'entered mobile state'
|
15409
|
+
|
15410
|
+
During development you can set a StateManager's `enableLogging` property to `true` to
|
15411
|
+
receive console messages of state transitions.
|
15412
|
+
|
15413
|
+
robotManager = Ember.StateManager.create({
|
15414
|
+
enableLogging: true
|
15415
|
+
})
|
15416
|
+
|
15417
|
+
## Managing currentState with Actions
|
15418
|
+
To control which transitions between states are possible for a given state, StateManager
|
15419
|
+
can receive and route action messages to its states via the `send` method. Calling to `send` with
|
15420
|
+
an action name will begin searching for a method with the same name starting at the current state
|
15421
|
+
and moving up through the parent states in a state hierarchy until an appropriate method is found
|
15422
|
+
or the StateManager instance itself is reached.
|
15423
|
+
|
15424
|
+
If an appropriately named method is found it will be called with the state manager as the first
|
15425
|
+
argument and an optional `context` object as the second argument.
|
15426
|
+
|
15427
|
+
managerA = Ember.StateManager.create({
|
15428
|
+
initialState: 'stateOne.substateOne.subsubstateOne',
|
15429
|
+
stateOne: Ember.State.create({
|
15430
|
+
substateOne: Ember.State.create({
|
15431
|
+
anAction: function(manager, context){
|
15432
|
+
console.log("an action was called")
|
15433
|
+
},
|
15434
|
+
subsubstateOne: Ember.State.create({})
|
15435
|
+
})
|
15436
|
+
})
|
15437
|
+
})
|
15438
|
+
|
15439
|
+
managerA.getPath('currentState.name') // 'subsubstateOne'
|
15440
|
+
managerA.send('anAction')
|
15441
|
+
// 'stateOne.substateOne.subsubstateOne' has no anAction method
|
15442
|
+
// so the 'anAction' method of 'stateOne.substateOne' is called
|
15443
|
+
// and logs "an action was called"
|
15444
|
+
// with managerA as the first argument
|
15445
|
+
// and no second argument
|
15446
|
+
|
15447
|
+
someObject = {}
|
15448
|
+
managerA.send('anAction', someObject)
|
15449
|
+
// the 'anAction' method of 'stateOne.substateOne' is called again
|
15450
|
+
// with managerA as the first argument and
|
15451
|
+
// someObject as the second argument.
|
15452
|
+
|
15453
|
+
|
15454
|
+
If the StateManager attempts to send an action but does not find an appropriately named
|
15455
|
+
method in the current state or while moving upwards through the state hierarchy
|
15456
|
+
it will throw a new Ember.Error. Action detection only moves upwards through the state hierarchy
|
15457
|
+
from the current state. It does not search in other portions of the hierarchy.
|
15458
|
+
|
15459
|
+
managerB = Ember.StateManager.create({
|
15460
|
+
initialState: 'stateOne.substateOne.subsubstateOne',
|
15461
|
+
stateOne: Ember.State.create({
|
15462
|
+
substateOne: Ember.State.create({
|
15463
|
+
subsubstateOne: Ember.State.create({})
|
15464
|
+
})
|
15465
|
+
}),
|
15466
|
+
stateTwo: Ember.State.create({
|
15467
|
+
anAction: function(manager, context){
|
15468
|
+
// will not be called below because it is
|
15469
|
+
// not a parent of the current state
|
15470
|
+
}
|
15471
|
+
})
|
15472
|
+
})
|
15473
|
+
|
15474
|
+
managerB.getPath('currentState.name') // 'subsubstateOne'
|
15475
|
+
managerB.send('anAction')
|
15476
|
+
// Error: <Ember.StateManager:ember132> could not
|
15477
|
+
// respond to event anAction in state stateOne.substateOne.subsubstateOne.
|
15478
|
+
|
15479
|
+
Inside of an action method the given state should delegate `goToState` calls on its
|
15480
|
+
StateManager.
|
15481
|
+
|
15482
|
+
robotManager = Ember.StateManager.create({
|
15483
|
+
initialState: 'poweredDown.charging',
|
15484
|
+
poweredDown: Ember.State.create({
|
15485
|
+
charging: Ember.State.create({
|
15486
|
+
chargeComplete: function(manager, context){
|
15487
|
+
manager.goToState('charged')
|
15488
|
+
}
|
15489
|
+
}),
|
15490
|
+
charged: Ember.State.create({
|
15491
|
+
boot: function(manager, context){
|
15492
|
+
manager.goToState('poweredUp')
|
15493
|
+
}
|
15494
|
+
})
|
15495
|
+
}),
|
15496
|
+
poweredUp: Ember.State.create({
|
15497
|
+
beginExtermination: function(manager, context){
|
15498
|
+
manager.goToState('rampaging')
|
15499
|
+
},
|
15500
|
+
rampaging: Ember.State.create()
|
15501
|
+
})
|
15502
|
+
})
|
15503
|
+
|
15504
|
+
robotManager.getPath('currentState.name') // 'charging'
|
15505
|
+
robotManager.send('boot') // throws error, no boot action
|
15506
|
+
// in current hierarchy
|
15507
|
+
robotManager.getPath('currentState.name') // remains 'charging'
|
15508
|
+
|
15509
|
+
robotManager.send('beginExtermination') // throws error, no beginExtermination
|
15510
|
+
// action in current hierarchy
|
15511
|
+
robotManager.getPath('currentState.name') // remains 'charging'
|
15512
|
+
|
15513
|
+
robotManager.send('chargeComplete')
|
15514
|
+
robotManager.getPath('currentState.name') // 'charged'
|
15515
|
+
|
15516
|
+
robotManager.send('boot')
|
15517
|
+
robotManager.getPath('currentState.name') // 'poweredUp'
|
15518
|
+
|
15519
|
+
robotManager.send('beginExtermination', allHumans)
|
15520
|
+
robotManager.getPath('currentState.name') // 'rampaging'
|
15521
|
+
|
15522
|
+
|
15523
|
+
## Interactions with Ember's View System.
|
15524
|
+
When combined with instances of `Ember.ViewState`, StateManager is designed to
|
15525
|
+
interact with Ember's view system to control which views are added to
|
15526
|
+
and removed from the DOM based on the manager's current state.
|
15527
|
+
|
15528
|
+
By default, a StateManager will manage views inside the 'body' element. This can be
|
15529
|
+
customized by setting the `rootElement` property to a CSS selector of an existing
|
15530
|
+
HTML element you would prefer to receive view rendering.
|
15531
|
+
|
15532
|
+
|
15533
|
+
viewStates = Ember.StateManager.create({
|
15534
|
+
rootElement: '#some-other-element'
|
15535
|
+
})
|
15536
|
+
|
15537
|
+
You can also specify a particular instance of `Ember.ContainerView` you would like to receive
|
15538
|
+
view rendering by setting the `rootView` property. You will be responsible for placing
|
15539
|
+
this element into the DOM yourself.
|
15540
|
+
|
15541
|
+
aLayoutView = Ember.ContainerView.create()
|
15542
|
+
|
15543
|
+
// make sure this view instance is added to the browser
|
15544
|
+
aLayoutView.appendTo('body')
|
15545
|
+
|
15546
|
+
App.viewStates = Ember.StateManager.create({
|
15547
|
+
rootView: aLayoutView
|
15548
|
+
})
|
15549
|
+
|
15550
|
+
|
15551
|
+
Once you have an instance of StateManager controlling a view, you can provide states
|
15552
|
+
that are instances of `Ember.ViewState`. When the StateManager enters a state
|
15553
|
+
that is an instance of `Ember.ViewState` that `ViewState`'s `view` property will be
|
15554
|
+
instantiated and inserted into the StateManager's `rootView` or `rootElement`.
|
15555
|
+
When a state is exited, the `ViewState`'s view will be removed from the StateManager's
|
15556
|
+
view.
|
15557
|
+
|
15558
|
+
ContactListView = Ember.View.extend({
|
15559
|
+
classNames: ['my-contacts-css-class'],
|
15560
|
+
defaultTemplate: Ember.Handlebars.compile('<h2>People</h2>')
|
15561
|
+
})
|
15562
|
+
|
15563
|
+
PhotoListView = Ember.View.extend({
|
15564
|
+
classNames: ['my-photos-css-class'],
|
15565
|
+
defaultTemplate: Ember.Handlebars.compile('<h2>Photos</h2>')
|
15566
|
+
})
|
15567
|
+
|
15568
|
+
viewStates = Ember.StateManager.create({
|
15569
|
+
showingPeople: Ember.ViewState.create({
|
15570
|
+
view: ContactListView
|
15571
|
+
}),
|
15572
|
+
showingPhotos: Ember.ViewState.create({
|
15573
|
+
view: PhotoListView
|
15574
|
+
})
|
15575
|
+
})
|
15576
|
+
|
15577
|
+
viewStates.goToState('showingPeople')
|
15578
|
+
|
15579
|
+
The above code will change the rendered HTML from
|
15580
|
+
|
15581
|
+
<body></body>
|
15582
|
+
|
15583
|
+
to
|
15584
|
+
|
15585
|
+
<body>
|
15586
|
+
<div id="ember1" class="ember-view my-contacts-css-class">
|
15587
|
+
<h2>People</h2>
|
15588
|
+
</div>
|
15589
|
+
</body>
|
15590
|
+
|
15591
|
+
Changing the current state via `goToState` from `showingPeople` to
|
15592
|
+
`showingPhotos` will remove the `showingPeople` view and add the `showingPhotos` view:
|
15593
|
+
|
15594
|
+
viewStates.goToState('showingPhotos')
|
15595
|
+
|
15596
|
+
will change the rendered HTML to
|
15597
|
+
|
15598
|
+
<body>
|
15599
|
+
<div id="ember2" class="ember-view my-photos-css-class">
|
15600
|
+
<h2>Photos</h2>
|
15601
|
+
</div>
|
15602
|
+
</body>
|
15603
|
+
|
15604
|
+
|
15605
|
+
When entering nested `ViewState`s, each state's view will be draw into the the StateManager's
|
15606
|
+
`rootView` or `rootElement` as siblings.
|
15607
|
+
|
15608
|
+
|
15609
|
+
ContactListView = Ember.View.extend({
|
15610
|
+
classNames: ['my-contacts-css-class'],
|
15611
|
+
defaultTemplate: Ember.Handlebars.compile('<h2>People</h2>')
|
15612
|
+
})
|
15613
|
+
|
15614
|
+
EditAContactView = Ember.View.extend({
|
15615
|
+
classNames: ['editing-a-contact-css-class'],
|
15616
|
+
defaultTemplate: Ember.Handlebars.compile('Editing...')
|
15617
|
+
})
|
15618
|
+
|
15619
|
+
viewStates = Ember.StateManager.create({
|
15620
|
+
showingPeople: Ember.ViewState.create({
|
15621
|
+
view: ContactListView,
|
15622
|
+
|
15623
|
+
withEditingPanel: Ember.ViewState.create({
|
15624
|
+
view: EditAContactView
|
15625
|
+
})
|
15626
|
+
})
|
15627
|
+
})
|
15628
|
+
|
15629
|
+
|
15630
|
+
viewStates.goToState('showingPeople.withEditingPanel')
|
15631
|
+
|
15632
|
+
|
15633
|
+
Will result in the following rendered HTML:
|
15634
|
+
|
15635
|
+
<body>
|
15636
|
+
<div id="ember2" class="ember-view my-contacts-css-class">
|
15637
|
+
<h2>People</h2>
|
15638
|
+
</div>
|
15639
|
+
|
15640
|
+
<div id="ember2" class="ember-view editing-a-contact-css-class">
|
15641
|
+
Editing...
|
15642
|
+
</div>
|
15643
|
+
</body>
|
15644
|
+
|
15645
|
+
|
15646
|
+
ViewState views are added and removed from their StateManager's view via their
|
15647
|
+
`enter` and `exit` methods. If you need to override these methods, be sure to call
|
15648
|
+
`_super` to maintain the adding and removing behavior:
|
15649
|
+
|
15650
|
+
viewStates = Ember.StateManager.create({
|
15651
|
+
aState: Ember.ViewState.create({
|
15652
|
+
view: Ember.View.extend({}),
|
15653
|
+
enter: function(manager, transition){
|
15654
|
+
// calling _super ensures this view will be
|
15655
|
+
// properly inserted
|
15656
|
+
this._super();
|
15657
|
+
|
15658
|
+
// now you can do other things
|
15659
|
+
}
|
15660
|
+
})
|
15661
|
+
})
|
15662
|
+
|
15663
|
+
## Managing Multiple Sections of A Page With States
|
15664
|
+
Multiple StateManagers can be combined to control multiple areas of an application's rendered views.
|
15665
|
+
Given the following HTML body:
|
15666
|
+
|
15667
|
+
<body>
|
15668
|
+
<div id='sidebar-nav'>
|
15669
|
+
</div>
|
15670
|
+
<div id='content-area'>
|
15671
|
+
</div>
|
15672
|
+
</body>
|
15673
|
+
|
15674
|
+
You could separately manage view state for each section with two StateManagers
|
15675
|
+
|
15676
|
+
navigationStates = Ember.StateManager.create({
|
15677
|
+
rootElement: '#sidebar-nav',
|
15678
|
+
userAuthenticated: Em.ViewState.create({
|
15679
|
+
view: Ember.View.extend({})
|
15680
|
+
}),
|
15681
|
+
userNotAuthenticated: Em.ViewState.create({
|
15682
|
+
view: Ember.View.extend({})
|
15683
|
+
})
|
15684
|
+
})
|
15685
|
+
|
15686
|
+
contentStates = Ember.StateManager.create({
|
15687
|
+
rootElement: '#content-area',
|
15688
|
+
books: Em.ViewState.create({
|
15689
|
+
view: Ember.View.extend({})
|
15690
|
+
}),
|
15691
|
+
music: Em.ViewState.create({
|
15692
|
+
view: Ember.View.extend({})
|
15693
|
+
})
|
15694
|
+
})
|
15695
|
+
|
15696
|
+
|
15697
|
+
If you prefer to start with an empty body and manage state programmatically you
|
15698
|
+
can also take advantage of StateManager's `rootView` property and the ability of
|
15699
|
+
`Ember.ContainerView`s to manually manage their child views.
|
15700
|
+
|
15701
|
+
|
15702
|
+
dashboard = Ember.ContainerView.create({
|
15703
|
+
childViews: ['navigationAreaView', 'contentAreaView'],
|
15704
|
+
navigationAreaView: Ember.ContainerView.create({}),
|
15705
|
+
contentAreaView: Ember.ContainerView.create({})
|
15706
|
+
})
|
15707
|
+
|
15708
|
+
navigationStates = Ember.StateManager.create({
|
15709
|
+
rootView: dashboard.get('navigationAreaView'),
|
15710
|
+
userAuthenticated: Em.ViewState.create({
|
15711
|
+
view: Ember.View.extend({})
|
15712
|
+
}),
|
15713
|
+
userNotAuthenticated: Em.ViewState.create({
|
15714
|
+
view: Ember.View.extend({})
|
15715
|
+
})
|
15716
|
+
})
|
15717
|
+
|
15718
|
+
contentStates = Ember.StateManager.create({
|
15719
|
+
rootView: dashboard.get('contentAreaView'),
|
15720
|
+
books: Em.ViewState.create({
|
15721
|
+
view: Ember.View.extend({})
|
15722
|
+
}),
|
15723
|
+
music: Em.ViewState.create({
|
15724
|
+
view: Ember.View.extend({})
|
15725
|
+
})
|
15726
|
+
})
|
15727
|
+
|
15728
|
+
dashboard.appendTo('body')
|
15729
|
+
|
15730
|
+
## User Manipulation of State via `{{action}}` Helpers
|
15731
|
+
The Handlebars `{{action}}` helper is StateManager-aware and will use StateManager action sending
|
15732
|
+
to connect user interaction to action-based state transitions.
|
15733
|
+
|
15734
|
+
Given the following body and handlebars template
|
15735
|
+
|
15736
|
+
<body>
|
15737
|
+
<script type='text/x-handlebars'>
|
15738
|
+
<a href="#" {{action "anAction" target="App.appStates"}}> Go </a>
|
15739
|
+
</script>
|
15740
|
+
</body>
|
15741
|
+
|
15742
|
+
And application code
|
15743
|
+
|
15744
|
+
App = Ember.Application.create()
|
15745
|
+
App.appStates = Ember.StateManager.create({
|
15746
|
+
initialState: 'aState',
|
15747
|
+
aState: Ember.State.create({
|
15748
|
+
anAction: function(manager, context){}
|
15749
|
+
}),
|
15750
|
+
bState: Ember.State.create({})
|
15751
|
+
})
|
15752
|
+
|
15753
|
+
A user initiated click or touch event on "Go" will trigger the 'anAction' method of
|
15754
|
+
`App.appStates.aState` with `App.appStates` as the first argument and a
|
15755
|
+
`jQuery.Event` object as the second object. The `jQuery.Event` will include a property
|
15756
|
+
`view` that references the `Ember.View` object that was interacted with.
|
15757
|
+
|
15758
|
+
**/
|
14511
15759
|
Ember.StateManager = Ember.State.extend(
|
14512
15760
|
/** @scope Ember.State.prototype */ {
|
14513
15761
|
|
@@ -14730,9 +15978,11 @@ Ember.StateManager = Ember.State.extend(
|
|
14730
15978
|
}
|
14731
15979
|
});
|
14732
15980
|
|
14733
|
-
})(
|
15981
|
+
})();
|
15982
|
+
|
14734
15983
|
|
14735
|
-
|
15984
|
+
|
15985
|
+
(function() {
|
14736
15986
|
var get = Ember.get, set = Ember.set;
|
14737
15987
|
|
14738
15988
|
Ember.ViewState = Ember.State.extend({
|
@@ -14780,18 +16030,20 @@ Ember.ViewState = Ember.State.extend({
|
|
14780
16030
|
}
|
14781
16031
|
});
|
14782
16032
|
|
14783
|
-
})(
|
16033
|
+
})();
|
16034
|
+
|
14784
16035
|
|
14785
|
-
|
16036
|
+
|
16037
|
+
(function() {
|
14786
16038
|
// ==========================================================================
|
14787
16039
|
// Project: Ember Statecharts
|
14788
16040
|
// Copyright: ©2011 Living Social Inc. and contributors.
|
14789
16041
|
// License: Licensed under MIT license (see license.js)
|
14790
16042
|
// ==========================================================================
|
14791
16043
|
|
14792
|
-
})(
|
16044
|
+
})();
|
14793
16045
|
|
14794
|
-
(function(
|
16046
|
+
(function() {
|
14795
16047
|
// ==========================================================================
|
14796
16048
|
// Project: metamorph
|
14797
16049
|
// Copyright: ©2011 My Company Inc. All rights reserved.
|
@@ -15192,9 +16444,9 @@ Ember.ViewState = Ember.State.extend({
|
|
15192
16444
|
})(this);
|
15193
16445
|
|
15194
16446
|
|
15195
|
-
})(
|
16447
|
+
})();
|
15196
16448
|
|
15197
|
-
(function(
|
16449
|
+
(function() {
|
15198
16450
|
// ==========================================================================
|
15199
16451
|
// Project: Ember Handlebar Views
|
15200
16452
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -15323,14 +16575,64 @@ Ember.Handlebars.compile = function(string) {
|
|
15323
16575
|
};
|
15324
16576
|
|
15325
16577
|
/**
|
15326
|
-
|
16578
|
+
If a path starts with a reserved keyword, returns the root
|
16579
|
+
that should be used.
|
16580
|
+
|
16581
|
+
@private
|
16582
|
+
*/
|
16583
|
+
var normalizePath = Ember.Handlebars.normalizePath = function(root, path, data) {
|
16584
|
+
var keywords = (data && data.keywords) || {},
|
16585
|
+
keyword, isKeyword;
|
16586
|
+
|
16587
|
+
// Get the first segment of the path. For example, if the
|
16588
|
+
// path is "foo.bar.baz", returns "foo".
|
16589
|
+
keyword = path.split('.', 1)[0];
|
16590
|
+
|
16591
|
+
// Test to see if the first path is a keyword that has been
|
16592
|
+
// passed along in the view's data hash. If so, we will treat
|
16593
|
+
// that object as the new root.
|
16594
|
+
if (keywords.hasOwnProperty(keyword)) {
|
16595
|
+
// Look up the value in the template's data hash.
|
16596
|
+
root = keywords[keyword];
|
16597
|
+
isKeyword = true;
|
16598
|
+
|
16599
|
+
// Handle cases where the entire path is the reserved
|
16600
|
+
// word. In that case, return the object itself.
|
16601
|
+
if (path === keyword) {
|
16602
|
+
path = '';
|
16603
|
+
} else {
|
16604
|
+
// Strip the keyword from the path and look up
|
16605
|
+
// the remainder from the newly found root.
|
16606
|
+
path = path.substr(keyword.length);
|
16607
|
+
}
|
16608
|
+
}
|
16609
|
+
|
16610
|
+
return { root: root, path: path, isKeyword: isKeyword };
|
16611
|
+
};
|
16612
|
+
/**
|
16613
|
+
Lookup both on root and on window. If the path starts with
|
16614
|
+
a keyword, the corresponding object will be looked up in the
|
16615
|
+
template's data hash and used to resolve the path.
|
15327
16616
|
|
15328
16617
|
@param {Object} root The object to look up the property on
|
15329
16618
|
@param {String} path The path to be lookedup
|
16619
|
+
@param {Object} options The template's option hash
|
15330
16620
|
*/
|
15331
|
-
|
16621
|
+
|
16622
|
+
Ember.Handlebars.getPath = function(root, path, options) {
|
16623
|
+
var data = options.data,
|
16624
|
+
normalizedPath = normalizePath(root, path, data),
|
16625
|
+
value;
|
16626
|
+
|
16627
|
+
// In cases where the path begins with a keyword, change the
|
16628
|
+
// root to the value represented by that keyword, and ensure
|
16629
|
+
// the path is relative to it.
|
16630
|
+
root = normalizedPath.root;
|
16631
|
+
path = normalizedPath.path;
|
16632
|
+
|
15332
16633
|
// TODO: Remove this `false` when the `getPath` globals support is removed
|
15333
|
-
|
16634
|
+
value = Ember.getPath(root, path, false);
|
16635
|
+
|
15334
16636
|
if (value === undefined && root !== window && Ember.isGlobalPath(path)) {
|
15335
16637
|
value = Ember.getPath(window, path);
|
15336
16638
|
}
|
@@ -15360,9 +16662,11 @@ Ember.Handlebars.registerHelper('helperMissing', function(path, options) {
|
|
15360
16662
|
});
|
15361
16663
|
|
15362
16664
|
|
15363
|
-
})(
|
16665
|
+
})();
|
16666
|
+
|
15364
16667
|
|
15365
|
-
|
16668
|
+
|
16669
|
+
(function() {
|
15366
16670
|
/*jshint newcap:false*/
|
15367
16671
|
var set = Ember.set, get = Ember.get, getPath = Ember.getPath;
|
15368
16672
|
|
@@ -15441,9 +16745,11 @@ Ember.Metamorph = Ember.Mixin.create({
|
|
15441
16745
|
});
|
15442
16746
|
|
15443
16747
|
|
15444
|
-
})(
|
16748
|
+
})();
|
16749
|
+
|
16750
|
+
|
15445
16751
|
|
15446
|
-
(function(
|
16752
|
+
(function() {
|
15447
16753
|
// ==========================================================================
|
15448
16754
|
// Project: Ember Handlebar Views
|
15449
16755
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -15526,14 +16832,15 @@ Ember._BindableSpanView = Ember.View.extend(Ember.Metamorph,
|
|
15526
16832
|
var property = get(this, 'property'),
|
15527
16833
|
context = get(this, 'previousContext'),
|
15528
16834
|
valueNormalizer = get(this, 'valueNormalizerFunc'),
|
15529
|
-
result;
|
16835
|
+
result, templateData;
|
15530
16836
|
|
15531
16837
|
// Use the current context as the result if no
|
15532
16838
|
// property is provided.
|
15533
16839
|
if (property === '') {
|
15534
16840
|
result = context;
|
15535
16841
|
} else {
|
15536
|
-
|
16842
|
+
templateData = get(this, 'templateData');
|
16843
|
+
result = getPath(context, property, { data: templateData });
|
15537
16844
|
}
|
15538
16845
|
|
15539
16846
|
return valueNormalizer ? valueNormalizer(result) : result;
|
@@ -15584,12 +16891,12 @@ Ember._BindableSpanView = Ember.View.extend(Ember.Metamorph,
|
|
15584
16891
|
// If we are preserving the context (for example, if this
|
15585
16892
|
// is an #if block, call the template with the same object.
|
15586
16893
|
if (preserveContext) {
|
15587
|
-
set(this, '
|
16894
|
+
set(this, '_templateContext', context);
|
15588
16895
|
} else {
|
15589
16896
|
// Otherwise, determine if this is a block bind or not.
|
15590
16897
|
// If so, pass the specified object to the template
|
15591
16898
|
if (displayTemplate) {
|
15592
|
-
set(this, '
|
16899
|
+
set(this, '_templateContext', result);
|
15593
16900
|
} else {
|
15594
16901
|
// This is not a bind block, just push the result of the
|
15595
16902
|
// expression to the render context and return.
|
@@ -15608,9 +16915,9 @@ Ember._BindableSpanView = Ember.View.extend(Ember.Metamorph,
|
|
15608
16915
|
set(this, 'template', inverseTemplate);
|
15609
16916
|
|
15610
16917
|
if (preserveContext) {
|
15611
|
-
set(this, '
|
16918
|
+
set(this, '_templateContext', context);
|
15612
16919
|
} else {
|
15613
|
-
set(this, '
|
16920
|
+
set(this, '_templateContext', result);
|
15614
16921
|
}
|
15615
16922
|
} else {
|
15616
16923
|
set(this, 'template', function() { return ''; });
|
@@ -15620,9 +16927,11 @@ Ember._BindableSpanView = Ember.View.extend(Ember.Metamorph,
|
|
15620
16927
|
}
|
15621
16928
|
});
|
15622
16929
|
|
15623
|
-
})(
|
16930
|
+
})();
|
15624
16931
|
|
15625
|
-
|
16932
|
+
|
16933
|
+
|
16934
|
+
(function() {
|
15626
16935
|
// ==========================================================================
|
15627
16936
|
// Project: Ember Handlebar Views
|
15628
16937
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -15641,7 +16950,13 @@ var EmberHandlebars = Ember.Handlebars, helpers = EmberHandlebars.helpers;
|
|
15641
16950
|
fn = options.fn,
|
15642
16951
|
inverse = options.inverse,
|
15643
16952
|
view = data.view,
|
15644
|
-
ctx = this
|
16953
|
+
ctx = this,
|
16954
|
+
normalized;
|
16955
|
+
|
16956
|
+
normalized = Ember.Handlebars.normalizePath(ctx, property, data);
|
16957
|
+
|
16958
|
+
ctx = normalized.root;
|
16959
|
+
property = normalized.path;
|
15645
16960
|
|
15646
16961
|
// Set up observers for observable objects
|
15647
16962
|
if ('object' === typeof this) {
|
@@ -15656,7 +16971,8 @@ var EmberHandlebars = Ember.Handlebars, helpers = EmberHandlebars.helpers;
|
|
15656
16971
|
inverseTemplate: inverse,
|
15657
16972
|
property: property,
|
15658
16973
|
previousContext: ctx,
|
15659
|
-
isEscaped: options.hash.escaped
|
16974
|
+
isEscaped: options.hash.escaped,
|
16975
|
+
templateData: options.data
|
15660
16976
|
});
|
15661
16977
|
|
15662
16978
|
view.appendChild(bindView);
|
@@ -15676,7 +16992,7 @@ var EmberHandlebars = Ember.Handlebars, helpers = EmberHandlebars.helpers;
|
|
15676
16992
|
} else {
|
15677
16993
|
// The object is not observable, so just render it out and
|
15678
16994
|
// be done with it.
|
15679
|
-
data.buffer.push(getPath(this, property));
|
16995
|
+
data.buffer.push(getPath(this, property, options));
|
15680
16996
|
}
|
15681
16997
|
};
|
15682
16998
|
|
@@ -15835,7 +17151,7 @@ EmberHandlebars.registerHelper('bindAttr', function(options) {
|
|
15835
17151
|
// Handle classes differently, as we can bind multiple classes
|
15836
17152
|
var classBindings = attrs['class'];
|
15837
17153
|
if (classBindings !== null && classBindings !== undefined) {
|
15838
|
-
var classResults = EmberHandlebars.bindClasses(this, classBindings, view, dataId);
|
17154
|
+
var classResults = EmberHandlebars.bindClasses(this, classBindings, view, dataId, options);
|
15839
17155
|
ret.push('class="' + classResults.join(' ') + '"');
|
15840
17156
|
delete attrs['class'];
|
15841
17157
|
}
|
@@ -15849,7 +17165,7 @@ EmberHandlebars.registerHelper('bindAttr', function(options) {
|
|
15849
17165
|
|
15850
17166
|
ember_assert(fmt("You must provide a String for a bound attribute, not %@", [property]), typeof property === 'string');
|
15851
17167
|
|
15852
|
-
var value = (property === 'this') ? ctx : getPath(ctx, property),
|
17168
|
+
var value = (property === 'this') ? ctx : getPath(ctx, property, options),
|
15853
17169
|
type = Ember.typeOf(value);
|
15854
17170
|
|
15855
17171
|
ember_assert(fmt("Attributes must be numbers, strings or booleans, not %@", [value]), value === null || value === undefined || type === 'number' || type === 'string' || type === 'boolean');
|
@@ -15858,7 +17174,7 @@ EmberHandlebars.registerHelper('bindAttr', function(options) {
|
|
15858
17174
|
|
15859
17175
|
/** @private */
|
15860
17176
|
observer = function observer() {
|
15861
|
-
var result = getPath(ctx, property);
|
17177
|
+
var result = getPath(ctx, property, options);
|
15862
17178
|
|
15863
17179
|
ember_assert(fmt("Attributes must be numbers, strings or booleans, not %@", [result]), result === null || result === undefined || typeof result === 'number' || typeof result === 'string' || typeof result === 'boolean');
|
15864
17180
|
|
@@ -15928,7 +17244,7 @@ EmberHandlebars.registerHelper('bindAttr', function(options) {
|
|
15928
17244
|
|
15929
17245
|
@returns {Array} An array of class names to add
|
15930
17246
|
*/
|
15931
|
-
EmberHandlebars.bindClasses = function(context, classBindings, view, bindAttrId) {
|
17247
|
+
EmberHandlebars.bindClasses = function(context, classBindings, view, bindAttrId, options) {
|
15932
17248
|
var ret = [], newClass, value, elem;
|
15933
17249
|
|
15934
17250
|
// Helper method to retrieve the property from the context and
|
@@ -15940,7 +17256,7 @@ EmberHandlebars.bindClasses = function(context, classBindings, view, bindAttrId)
|
|
15940
17256
|
|
15941
17257
|
property = split[0];
|
15942
17258
|
|
15943
|
-
var val = property !== '' ? getPath(context, property) : true;
|
17259
|
+
var val = property !== '' ? getPath(context, property, options) : true;
|
15944
17260
|
|
15945
17261
|
// If value is a Boolean and true, return the dasherized property
|
15946
17262
|
// name.
|
@@ -16032,9 +17348,11 @@ EmberHandlebars.bindClasses = function(context, classBindings, view, bindAttrId)
|
|
16032
17348
|
};
|
16033
17349
|
|
16034
17350
|
|
16035
|
-
})(
|
17351
|
+
})();
|
17352
|
+
|
16036
17353
|
|
16037
|
-
|
17354
|
+
|
17355
|
+
(function() {
|
16038
17356
|
// ==========================================================================
|
16039
17357
|
// Project: Ember Handlebar Views
|
16040
17358
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -16046,17 +17364,19 @@ EmberHandlebars.bindClasses = function(context, classBindings, view, bindAttrId)
|
|
16046
17364
|
var get = Ember.get, set = Ember.set;
|
16047
17365
|
var indexOf = Ember.ArrayUtils.indexOf;
|
16048
17366
|
var PARENT_VIEW_PATH = /^parentView\./;
|
17367
|
+
var EmberHandlebars = Ember.Handlebars;
|
16049
17368
|
|
16050
17369
|
/** @private */
|
16051
|
-
|
17370
|
+
EmberHandlebars.ViewHelper = Ember.Object.create({
|
16052
17371
|
|
16053
17372
|
viewClassFromHTMLOptions: function(viewClass, options, thisContext) {
|
17373
|
+
var hash = options.hash, data = options.data;
|
16054
17374
|
var extensions = {},
|
16055
|
-
classes =
|
17375
|
+
classes = hash['class'],
|
16056
17376
|
dup = false;
|
16057
17377
|
|
16058
|
-
if (
|
16059
|
-
extensions.elementId =
|
17378
|
+
if (hash.id) {
|
17379
|
+
extensions.elementId = hash.id;
|
16060
17380
|
dup = true;
|
16061
17381
|
}
|
16062
17382
|
|
@@ -16066,45 +17386,49 @@ Ember.Handlebars.ViewHelper = Ember.Object.create({
|
|
16066
17386
|
dup = true;
|
16067
17387
|
}
|
16068
17388
|
|
16069
|
-
if (
|
16070
|
-
extensions.classNameBindings =
|
17389
|
+
if (hash.classBinding) {
|
17390
|
+
extensions.classNameBindings = hash.classBinding.split(' ');
|
16071
17391
|
dup = true;
|
16072
17392
|
}
|
16073
17393
|
|
16074
|
-
if (
|
16075
|
-
extensions.classNameBindings =
|
17394
|
+
if (hash.classNameBindings) {
|
17395
|
+
extensions.classNameBindings = hash.classNameBindings.split(' ');
|
16076
17396
|
dup = true;
|
16077
17397
|
}
|
16078
17398
|
|
16079
|
-
if (
|
17399
|
+
if (hash.attributeBindings) {
|
16080
17400
|
ember_assert("Setting 'attributeBindings' via Handlebars is not allowed. Please subclass Ember.View and set it there instead.");
|
16081
17401
|
extensions.attributeBindings = null;
|
16082
17402
|
dup = true;
|
16083
17403
|
}
|
16084
17404
|
|
16085
17405
|
if (dup) {
|
16086
|
-
|
16087
|
-
delete
|
16088
|
-
delete
|
16089
|
-
delete
|
17406
|
+
hash = Ember.$.extend({}, hash);
|
17407
|
+
delete hash.id;
|
17408
|
+
delete hash['class'];
|
17409
|
+
delete hash.classBinding;
|
16090
17410
|
}
|
16091
17411
|
|
16092
17412
|
// Look for bindings passed to the helper and, if they are
|
16093
17413
|
// local, make them relative to the current context instead of the
|
16094
17414
|
// view.
|
16095
|
-
var path;
|
17415
|
+
var path, normalized;
|
16096
17416
|
|
16097
|
-
for (var prop in
|
16098
|
-
if (!
|
17417
|
+
for (var prop in hash) {
|
17418
|
+
if (!hash.hasOwnProperty(prop)) { continue; }
|
16099
17419
|
|
16100
17420
|
// Test if the property ends in "Binding"
|
16101
17421
|
if (Ember.IS_BINDING.test(prop)) {
|
16102
|
-
path =
|
16103
|
-
|
17422
|
+
path = hash[prop];
|
17423
|
+
|
17424
|
+
normalized = Ember.Handlebars.normalizePath(null, path, data);
|
17425
|
+
if (normalized.isKeyword) {
|
17426
|
+
hash[prop] = 'templateData.keywords.'+path;
|
17427
|
+
} else if (!Ember.isGlobalPath(path)) {
|
16104
17428
|
if (path === 'this') {
|
16105
|
-
|
17429
|
+
hash[prop] = 'bindingContext';
|
16106
17430
|
} else {
|
16107
|
-
|
17431
|
+
hash[prop] = 'bindingContext.'+path;
|
16108
17432
|
}
|
16109
17433
|
}
|
16110
17434
|
}
|
@@ -16114,7 +17438,7 @@ Ember.Handlebars.ViewHelper = Ember.Object.create({
|
|
16114
17438
|
// for the bindings set up above.
|
16115
17439
|
extensions.bindingContext = thisContext;
|
16116
17440
|
|
16117
|
-
return viewClass.extend(
|
17441
|
+
return viewClass.extend(hash, extensions);
|
16118
17442
|
},
|
16119
17443
|
|
16120
17444
|
helper: function(thisContext, path, options) {
|
@@ -16126,7 +17450,7 @@ Ember.Handlebars.ViewHelper = Ember.Object.create({
|
|
16126
17450
|
newView;
|
16127
17451
|
|
16128
17452
|
if ('string' === typeof path) {
|
16129
|
-
newView =
|
17453
|
+
newView = EmberHandlebars.getPath(thisContext, path, options);
|
16130
17454
|
ember_assert("Unable to find view at path '" + path + "'", !!newView);
|
16131
17455
|
} else {
|
16132
17456
|
newView = path;
|
@@ -16134,12 +17458,14 @@ Ember.Handlebars.ViewHelper = Ember.Object.create({
|
|
16134
17458
|
|
16135
17459
|
ember_assert(Ember.String.fmt('You must pass a view class to the #view helper, not %@ (%@)', [path, newView]), Ember.View.detect(newView));
|
16136
17460
|
|
16137
|
-
newView = this.viewClassFromHTMLOptions(newView,
|
17461
|
+
newView = this.viewClassFromHTMLOptions(newView, options, thisContext);
|
16138
17462
|
var currentView = data.view;
|
16139
|
-
var viewOptions = {
|
17463
|
+
var viewOptions = {
|
17464
|
+
templateData: options.data
|
17465
|
+
};
|
16140
17466
|
|
16141
17467
|
if (fn) {
|
16142
|
-
ember_assert("You cannot provide a template block if you also specified a templateName", !
|
17468
|
+
ember_assert("You cannot provide a template block if you also specified a templateName", !get(viewOptions, 'templateName') && !get(newView.proto(), 'templateName'));
|
16143
17469
|
viewOptions.template = fn;
|
16144
17470
|
}
|
16145
17471
|
|
@@ -16153,7 +17479,7 @@ Ember.Handlebars.ViewHelper = Ember.Object.create({
|
|
16153
17479
|
@param {Hash} options
|
16154
17480
|
@returns {String} HTML string
|
16155
17481
|
*/
|
16156
|
-
|
17482
|
+
EmberHandlebars.registerHelper('view', function(path, options) {
|
16157
17483
|
ember_assert("The view helper only takes a single argument", arguments.length <= 2);
|
16158
17484
|
|
16159
17485
|
// If no path is provided, treat path param as options.
|
@@ -16162,13 +17488,15 @@ Ember.Handlebars.registerHelper('view', function(path, options) {
|
|
16162
17488
|
path = "Ember.View";
|
16163
17489
|
}
|
16164
17490
|
|
16165
|
-
return
|
17491
|
+
return EmberHandlebars.ViewHelper.helper(this, path, options);
|
16166
17492
|
});
|
16167
17493
|
|
16168
17494
|
|
16169
|
-
})(
|
17495
|
+
})();
|
17496
|
+
|
17497
|
+
|
16170
17498
|
|
16171
|
-
(function(
|
17499
|
+
(function() {
|
16172
17500
|
// ==========================================================================
|
16173
17501
|
// Project: Ember Handlebar Views
|
16174
17502
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -16184,6 +17512,108 @@ var get = Ember.get, getPath = Ember.Handlebars.getPath, fmt = Ember.String.fmt;
|
|
16184
17512
|
@param {String} path
|
16185
17513
|
@param {Hash} options
|
16186
17514
|
@returns {String} HTML string
|
17515
|
+
|
17516
|
+
`{{collection}}` is a `Ember.Handlebars` helper for adding instances of
|
17517
|
+
`Ember.CollectionView` to a template. See `Ember.CollectionView` for additional
|
17518
|
+
information on how a `CollectionView` functions.
|
17519
|
+
|
17520
|
+
`{{collection}}`'s primary use is as a block helper with a `contentBinding` option
|
17521
|
+
pointing towards an `Ember.Array`-compatible object. An `Ember.View` instance will
|
17522
|
+
be created for each item in its `content` property. Each view will have its own
|
17523
|
+
`content` property set to the appropriate item in the collection.
|
17524
|
+
|
17525
|
+
The provided block will be applied as the template for each item's view.
|
17526
|
+
|
17527
|
+
Given an empty `<body>` the following template:
|
17528
|
+
|
17529
|
+
<script type="text/x-handlebars">
|
17530
|
+
{{#collection contentBinding="App.items"}}
|
17531
|
+
Hi {{content.name}}
|
17532
|
+
{{/collection}}
|
17533
|
+
</script>
|
17534
|
+
|
17535
|
+
And the following application code
|
17536
|
+
|
17537
|
+
App = Ember.Application.create()
|
17538
|
+
App.items = [
|
17539
|
+
Ember.Object.create({name: 'Dave'}),
|
17540
|
+
Ember.Object.create({name: 'Mary'}),
|
17541
|
+
Ember.Object.create({name: 'Sara'})
|
17542
|
+
]
|
17543
|
+
|
17544
|
+
Will result in the HTML structure below
|
17545
|
+
|
17546
|
+
<div class="ember-view">
|
17547
|
+
<div class="ember-view">Hi Dave</div>
|
17548
|
+
<div class="ember-view">Hi Mary</div>
|
17549
|
+
<div class="ember-view">Hi Sara</div>
|
17550
|
+
</div>
|
17551
|
+
|
17552
|
+
### Blockless Use
|
17553
|
+
If you provide an `itemViewClass` option that has its own `template` you can omit
|
17554
|
+
the block.
|
17555
|
+
|
17556
|
+
The following template:
|
17557
|
+
|
17558
|
+
<script type="text/x-handlebars">
|
17559
|
+
{{collection contentBinding="App.items" itemViewClass="App.AnItemView"}}
|
17560
|
+
</script>
|
17561
|
+
|
17562
|
+
And application code
|
17563
|
+
|
17564
|
+
App = Ember.Application.create()
|
17565
|
+
App.items = [
|
17566
|
+
Ember.Object.create({name: 'Dave'}),
|
17567
|
+
Ember.Object.create({name: 'Mary'}),
|
17568
|
+
Ember.Object.create({name: 'Sara'})
|
17569
|
+
]
|
17570
|
+
|
17571
|
+
App.AnItemView = Ember.View.extend({
|
17572
|
+
template: Ember.Handlebars.compile("Greetings {{content.name}}")
|
17573
|
+
})
|
17574
|
+
|
17575
|
+
Will result in the HTML structure below
|
17576
|
+
|
17577
|
+
<div class="ember-view">
|
17578
|
+
<div class="ember-view">Greetings Dave</div>
|
17579
|
+
<div class="ember-view">Greetings Mary</div>
|
17580
|
+
<div class="ember-view">Greetings Sara</div>
|
17581
|
+
</div>
|
17582
|
+
|
17583
|
+
### Specifying a CollectionView subclass
|
17584
|
+
By default the `{{collection}}` helper will create an instance of `Ember.CollectionView`.
|
17585
|
+
You can supply a `Ember.CollectionView` subclass to the helper by passing it
|
17586
|
+
as the first argument:
|
17587
|
+
|
17588
|
+
<script type="text/x-handlebars">
|
17589
|
+
{{#collection App.MyCustomCollectionClass contentBinding="App.items"}}
|
17590
|
+
Hi {{content.name}}
|
17591
|
+
{{/collection}}
|
17592
|
+
</script>
|
17593
|
+
|
17594
|
+
|
17595
|
+
### Forwarded `item.*`-named Options
|
17596
|
+
As with the `{{view}}`, helper options passed to the `{{collection}}` will be set on
|
17597
|
+
the resulting `Ember.CollectionView` as properties. Additionally, options prefixed with
|
17598
|
+
`item` will be applied to the views rendered for each item (note the camelcasing):
|
17599
|
+
|
17600
|
+
<script type="text/x-handlebars">
|
17601
|
+
{{#collection contentBinding="App.items"
|
17602
|
+
itemTagName="p"
|
17603
|
+
itemClassNames="greeting"}}
|
17604
|
+
Howdy {{content.name}}
|
17605
|
+
{{/collection}}
|
17606
|
+
</script>
|
17607
|
+
|
17608
|
+
Will result in the following HTML structure:
|
17609
|
+
|
17610
|
+
<div class="ember-view">
|
17611
|
+
<p class="ember-view greeting">Howdy Dave</p>
|
17612
|
+
<p class="ember-view greeting">Howdy Mary</p>
|
17613
|
+
<p class="ember-view greeting">Howdy Sara</p>
|
17614
|
+
</div>
|
17615
|
+
|
17616
|
+
|
16187
17617
|
*/
|
16188
17618
|
Ember.Handlebars.registerHelper('collection', function(path, options) {
|
16189
17619
|
// If no path is provided, treat path param as options.
|
@@ -16202,7 +17632,7 @@ Ember.Handlebars.registerHelper('collection', function(path, options) {
|
|
16202
17632
|
// If passed a path string, convert that into an object.
|
16203
17633
|
// Otherwise, just default to the standard class.
|
16204
17634
|
var collectionClass;
|
16205
|
-
collectionClass = path ? getPath(this, path) : Ember.CollectionView;
|
17635
|
+
collectionClass = path ? getPath(this, path, options) : Ember.CollectionView;
|
16206
17636
|
ember_assert(fmt("%@ #collection: Could not find %@", data.view, path), !!collectionClass);
|
16207
17637
|
|
16208
17638
|
var hash = options.hash, itemHash = {}, match;
|
@@ -16211,7 +17641,7 @@ Ember.Handlebars.registerHelper('collection', function(path, options) {
|
|
16211
17641
|
var itemViewClass, itemViewPath = hash.itemViewClass;
|
16212
17642
|
var collectionPrototype = collectionClass.proto();
|
16213
17643
|
delete hash.itemViewClass;
|
16214
|
-
itemViewClass = itemViewPath ? getPath(collectionPrototype, itemViewPath) : collectionPrototype.itemViewClass;
|
17644
|
+
itemViewClass = itemViewPath ? getPath(collectionPrototype, itemViewPath, options) : collectionPrototype.itemViewClass;
|
16215
17645
|
ember_assert(fmt("%@ #collection: Could not find %@", data.view, itemViewPath), !!itemViewClass);
|
16216
17646
|
|
16217
17647
|
// Go through options passed to the {{collection}} helper and extract options
|
@@ -16242,7 +17672,7 @@ Ember.Handlebars.registerHelper('collection', function(path, options) {
|
|
16242
17672
|
|
16243
17673
|
if (hash.emptyViewClass) {
|
16244
17674
|
emptyViewClass = Ember.View.detect(hash.emptyViewClass) ?
|
16245
|
-
hash.emptyViewClass : getPath(this, hash.emptyViewClass);
|
17675
|
+
hash.emptyViewClass : getPath(this, hash.emptyViewClass, options);
|
16246
17676
|
}
|
16247
17677
|
|
16248
17678
|
hash.emptyView = emptyViewClass.extend({
|
@@ -16252,13 +17682,13 @@ Ember.Handlebars.registerHelper('collection', function(path, options) {
|
|
16252
17682
|
}
|
16253
17683
|
|
16254
17684
|
if (hash.preserveContext) {
|
16255
|
-
itemHash.
|
17685
|
+
itemHash._templateContext = Ember.computed(function() {
|
16256
17686
|
return get(this, 'content');
|
16257
17687
|
}).property('content');
|
16258
17688
|
delete hash.preserveContext;
|
16259
17689
|
}
|
16260
17690
|
|
16261
|
-
hash.itemViewClass = Ember.Handlebars.ViewHelper.viewClassFromHTMLOptions(itemViewClass, itemHash, this);
|
17691
|
+
hash.itemViewClass = Ember.Handlebars.ViewHelper.viewClassFromHTMLOptions(itemViewClass, { data: data, hash: itemHash }, this);
|
16262
17692
|
|
16263
17693
|
return Ember.Handlebars.helpers.view.call(this, collectionClass, options);
|
16264
17694
|
});
|
@@ -16266,9 +17696,11 @@ Ember.Handlebars.registerHelper('collection', function(path, options) {
|
|
16266
17696
|
|
16267
17697
|
|
16268
17698
|
|
16269
|
-
})(
|
17699
|
+
})();
|
16270
17700
|
|
16271
|
-
|
17701
|
+
|
17702
|
+
|
17703
|
+
(function() {
|
16272
17704
|
// ==========================================================================
|
16273
17705
|
// Project: Ember Handlebar Views
|
16274
17706
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -16289,12 +17721,14 @@ var getPath = Ember.Handlebars.getPath;
|
|
16289
17721
|
*/
|
16290
17722
|
Ember.Handlebars.registerHelper('unbound', function(property, fn) {
|
16291
17723
|
var context = (fn.contexts && fn.contexts[0]) || this;
|
16292
|
-
return getPath(context, property);
|
17724
|
+
return getPath(context, property, fn);
|
16293
17725
|
});
|
16294
17726
|
|
16295
|
-
})(
|
17727
|
+
})();
|
17728
|
+
|
16296
17729
|
|
16297
|
-
|
17730
|
+
|
17731
|
+
(function() {
|
16298
17732
|
// ==========================================================================
|
16299
17733
|
// Project: Ember Handlebar Views
|
16300
17734
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -16331,9 +17765,11 @@ Ember.Handlebars.registerHelper('debugger', function() {
|
|
16331
17765
|
debugger;
|
16332
17766
|
});
|
16333
17767
|
|
16334
|
-
})(
|
17768
|
+
})();
|
17769
|
+
|
17770
|
+
|
16335
17771
|
|
16336
|
-
(function(
|
17772
|
+
(function() {
|
16337
17773
|
Ember.Handlebars.EachView = Ember.CollectionView.extend(Ember.Metamorph, {
|
16338
17774
|
itemViewClass: Ember.View.extend(Ember.Metamorph)
|
16339
17775
|
});
|
@@ -16349,9 +17785,11 @@ Ember.Handlebars.registerHelper('each', function(path, options) {
|
|
16349
17785
|
return Ember.Handlebars.helpers.collection.call(this, 'Ember.Handlebars.EachView', options);
|
16350
17786
|
});
|
16351
17787
|
|
16352
|
-
})(
|
17788
|
+
})();
|
17789
|
+
|
17790
|
+
|
16353
17791
|
|
16354
|
-
(function(
|
17792
|
+
(function() {
|
16355
17793
|
/**
|
16356
17794
|
`template` allows you to render a template from inside another template.
|
16357
17795
|
This allows you to re-use the same template in multiple places. For example:
|
@@ -16388,15 +17826,128 @@ Ember.Handlebars.registerHelper('template', function(name, options) {
|
|
16388
17826
|
Ember.TEMPLATES[name](this, { data: options.data });
|
16389
17827
|
});
|
16390
17828
|
|
16391
|
-
})(
|
17829
|
+
})();
|
17830
|
+
|
16392
17831
|
|
16393
|
-
|
16394
|
-
|
17832
|
+
|
17833
|
+
(function() {
|
17834
|
+
var EmberHandlebars = Ember.Handlebars, getPath = EmberHandlebars.getPath;
|
16395
17835
|
|
16396
17836
|
var ActionHelper = EmberHandlebars.ActionHelper = {
|
16397
17837
|
registeredActions: {}
|
16398
17838
|
};
|
17839
|
+
/**
|
17840
|
+
@name Handlebars.helpers.action
|
17841
|
+
|
17842
|
+
The `{{action}}` helper registers an HTML element within a template for
|
17843
|
+
DOM event handling. User interaction with that element will call the method
|
17844
|
+
on the template's associated `Ember.View` instance that has the same name
|
17845
|
+
as the first provided argument to `{{action}}`:
|
17846
|
+
|
17847
|
+
Given the following Handlebars template on the page
|
17848
|
+
|
17849
|
+
<script type="text/x-handlebars" data-template-name='a-template'>
|
17850
|
+
<div {{action "anActionName"}}>
|
17851
|
+
click me
|
17852
|
+
</div>
|
17853
|
+
</script>
|
17854
|
+
|
17855
|
+
And application code
|
17856
|
+
|
17857
|
+
AView = Ember.View.extend({
|
17858
|
+
templateName; 'a-template',
|
17859
|
+
anActionName: function(event){}
|
17860
|
+
})
|
17861
|
+
|
17862
|
+
aView = AView.create()
|
17863
|
+
aView.appendTo('body')
|
17864
|
+
|
17865
|
+
Will results in the following rendered HTML
|
17866
|
+
|
17867
|
+
<div class="ember-view">
|
17868
|
+
<div data-ember-action="1">
|
17869
|
+
click me
|
17870
|
+
</div>
|
17871
|
+
</div>
|
17872
|
+
|
17873
|
+
Clicking "click me" will trigger the `anActionName` method of the `aView` object with a
|
17874
|
+
`jQuery.Event` object as its argument. The `jQuery.Event` object will be extended to include
|
17875
|
+
a `view` property that is set to the original view interacted with (in this case the `aView` object).
|
17876
|
+
|
17877
|
+
|
17878
|
+
### Specifying an Action Target
|
17879
|
+
A `target` option can be provided to change which object will receive the method call. This option must be
|
17880
|
+
a string representing a path to an object:
|
17881
|
+
|
17882
|
+
<script type="text/x-handlebars" data-template-name='a-template'>
|
17883
|
+
<div {{action "anActionName" target="MyApplication.someObject"}}>
|
17884
|
+
click me
|
17885
|
+
</div>
|
17886
|
+
</script>
|
17887
|
+
|
17888
|
+
Clicking "click me" in the rendered HTML of the above template will trigger the
|
17889
|
+
`anActionName` method of the object at `MyApplication.someObject`. The first argument
|
17890
|
+
to this method will be a `jQuery.Event` extended to include a `view` property that is
|
17891
|
+
set to the original view interacted with.
|
17892
|
+
|
17893
|
+
A path relative to the template's `Ember.View` instance can also be used as a target:
|
17894
|
+
|
17895
|
+
<script type="text/x-handlebars" data-template-name='a-template'>
|
17896
|
+
<div {{action "anActionName" target="parentView"}}>
|
17897
|
+
click me
|
17898
|
+
</div>
|
17899
|
+
</script>
|
17900
|
+
|
17901
|
+
Clicking "click me" in the rendered HTML of the above template will trigger the
|
17902
|
+
`anActionName` method of the view's parent view.
|
17903
|
+
|
17904
|
+
The `{{action}}` helper is `Ember.StateManager` aware. If the target of
|
17905
|
+
the action is an `Ember.StateManager` instance `{{action}}` will use the `send`
|
17906
|
+
functionality of StateManagers. The documentation for `Ember.StateManager` has additional
|
17907
|
+
information about this use.
|
17908
|
+
|
17909
|
+
If an action's target does not implement a method that matches the supplied action name
|
17910
|
+
an error will be thrown.
|
17911
|
+
|
17912
|
+
|
17913
|
+
<script type="text/x-handlebars" data-template-name='a-template'>
|
17914
|
+
<div {{action "aMethodNameThatIsMissing"}}>
|
17915
|
+
click me
|
17916
|
+
</div>
|
17917
|
+
</script>
|
17918
|
+
|
17919
|
+
With the following application code
|
17920
|
+
|
17921
|
+
AView = Ember.View.extend({
|
17922
|
+
templateName; 'a-template',
|
17923
|
+
// note: no method 'aMethodNameThatIsMissing'
|
17924
|
+
anActionName: function(event){}
|
17925
|
+
})
|
16399
17926
|
|
17927
|
+
aView = AView.create()
|
17928
|
+
aView.appendTo('body')
|
17929
|
+
|
17930
|
+
Will throw `Uncaught TypeError: Cannot call method 'call' of undefined` when "click me" is clicked.
|
17931
|
+
|
17932
|
+
|
17933
|
+
### Specifying DOM event type
|
17934
|
+
By default the `{{action}}` helper registers for DOM `click` events. You can supply an
|
17935
|
+
`on` option to the helper to specify a different DOM event name:
|
17936
|
+
|
17937
|
+
<script type="text/x-handlebars" data-template-name='a-template'>
|
17938
|
+
<div {{action "aMethodNameThatIsMissing" on="doubleClick"}}>
|
17939
|
+
click me
|
17940
|
+
</div>
|
17941
|
+
</script>
|
17942
|
+
|
17943
|
+
See `Ember.EventDispatcher` for a list of acceptable DOM event names.
|
17944
|
+
|
17945
|
+
Because `{{action}}` depends on Ember's event dispatch system it will only function if
|
17946
|
+
an `Ember.EventDispatcher` instance is available. An `Ember.EventDispatcher` instance
|
17947
|
+
will be created when a new `Ember.Application` is created. Having an instance of
|
17948
|
+
`Ember.Application` will satisfy this requirement.
|
17949
|
+
|
17950
|
+
*/
|
16400
17951
|
ActionHelper.registerAction = function(actionName, eventName, target, view, context) {
|
16401
17952
|
var actionId = (++Ember.$.uuid).toString();
|
16402
17953
|
|
@@ -16406,7 +17957,8 @@ ActionHelper.registerAction = function(actionName, eventName, target, view, cont
|
|
16406
17957
|
event.view = view;
|
16407
17958
|
event.context = context;
|
16408
17959
|
|
16409
|
-
|
17960
|
+
// Check for StateManager (or compatible object)
|
17961
|
+
if (target.isState && typeof target.send === 'function') {
|
16410
17962
|
return target.send(actionName, event);
|
16411
17963
|
} else {
|
16412
17964
|
return target[actionName].call(target, event);
|
@@ -16423,23 +17975,68 @@ ActionHelper.registerAction = function(actionName, eventName, target, view, cont
|
|
16423
17975
|
|
16424
17976
|
EmberHandlebars.registerHelper('action', function(actionName, options) {
|
16425
17977
|
var hash = options.hash || {},
|
16426
|
-
eventName =
|
17978
|
+
eventName = hash.on || "click",
|
16427
17979
|
view = options.data.view,
|
16428
17980
|
target, context;
|
16429
17981
|
|
16430
17982
|
if (view.isVirtual) { view = view.get('parentView'); }
|
16431
|
-
target =
|
17983
|
+
target = hash.target ? getPath(this, hash.target, options) : view;
|
16432
17984
|
context = options.contexts[0];
|
16433
17985
|
|
16434
17986
|
var actionId = ActionHelper.registerAction(actionName, eventName, target, view, context);
|
16435
17987
|
return new EmberHandlebars.SafeString('data-ember-action="' + actionId + '"');
|
16436
17988
|
});
|
16437
17989
|
|
16438
|
-
})(
|
17990
|
+
})();
|
17991
|
+
|
16439
17992
|
|
16440
|
-
|
17993
|
+
|
17994
|
+
(function() {
|
16441
17995
|
var get = Ember.get, set = Ember.set;
|
16442
17996
|
|
17997
|
+
/**
|
17998
|
+
@name Handlebars.helpers.yield
|
17999
|
+
|
18000
|
+
When used in a Handlebars template that is assigned to an `Ember.View` instance's
|
18001
|
+
`layout` property Ember will render the layout template first, inserting the view's
|
18002
|
+
own rendered output at the `{{ yield }}` location.
|
18003
|
+
|
18004
|
+
An empty `<body>` and the following application code:
|
18005
|
+
|
18006
|
+
AView = Ember.View.extend({
|
18007
|
+
classNames: ['a-view-with-layout'],
|
18008
|
+
layout: Ember.Handlebars.compile('<div class="wrapper">{{ yield }}</div>'),
|
18009
|
+
template: Ember.Handlebars.compile('<span>I am wrapped</span>')
|
18010
|
+
})
|
18011
|
+
|
18012
|
+
aView = AView.create()
|
18013
|
+
aView.appendTo('body')
|
18014
|
+
|
18015
|
+
Will result in the following HTML output:
|
18016
|
+
|
18017
|
+
<body>
|
18018
|
+
<div class='ember-view a-view-with-layout'>
|
18019
|
+
<div class="wrapper">
|
18020
|
+
<span>I am wrapped</span>
|
18021
|
+
</div>
|
18022
|
+
</div>
|
18023
|
+
</body>
|
18024
|
+
|
18025
|
+
|
18026
|
+
The yield helper cannot be used outside of a template assigned to an `Ember.View`'s `layout` property
|
18027
|
+
and will throw an error if attempted.
|
18028
|
+
|
18029
|
+
BView = Ember.View.extend({
|
18030
|
+
classNames: ['a-view-with-layout'],
|
18031
|
+
template: Ember.Handlebars.compile('{{yield}}')
|
18032
|
+
})
|
18033
|
+
|
18034
|
+
bView = BView.create()
|
18035
|
+
bView.appendTo('body')
|
18036
|
+
|
18037
|
+
// throws
|
18038
|
+
// Uncaught Error: assertion failed: You called yield in a template that was not a layout
|
18039
|
+
*/
|
16443
18040
|
Ember.Handlebars.registerHelper('yield', function(options) {
|
16444
18041
|
var view = options.data.view, template;
|
16445
18042
|
|
@@ -16451,31 +18048,36 @@ Ember.Handlebars.registerHelper('yield', function(options) {
|
|
16451
18048
|
|
16452
18049
|
template = get(view, 'template');
|
16453
18050
|
|
16454
|
-
|
16455
|
-
template(this, options);
|
18051
|
+
if (template) { template(this, options); }
|
16456
18052
|
});
|
16457
18053
|
|
16458
|
-
})(
|
18054
|
+
})();
|
18055
|
+
|
16459
18056
|
|
16460
|
-
|
18057
|
+
|
18058
|
+
(function() {
|
16461
18059
|
// ==========================================================================
|
16462
18060
|
// Project: Ember Handlebar Views
|
16463
18061
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
16464
18062
|
// License: Licensed under MIT license (see license.js)
|
16465
18063
|
// ==========================================================================
|
16466
18064
|
|
16467
|
-
})(
|
18065
|
+
})();
|
18066
|
+
|
16468
18067
|
|
16469
|
-
|
18068
|
+
|
18069
|
+
(function() {
|
16470
18070
|
// ==========================================================================
|
16471
18071
|
// Project: Ember Handlebar Views
|
16472
18072
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
16473
18073
|
// License: Licensed under MIT license (see license.js)
|
16474
18074
|
// ==========================================================================
|
16475
18075
|
|
16476
|
-
})(
|
18076
|
+
})();
|
18077
|
+
|
18078
|
+
|
16477
18079
|
|
16478
|
-
(function(
|
18080
|
+
(function() {
|
16479
18081
|
// ==========================================================================
|
16480
18082
|
// Project: Ember Handlebar Views
|
16481
18083
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -16483,35 +18085,100 @@ Ember.Handlebars.registerHelper('yield', function(options) {
|
|
16483
18085
|
// ==========================================================================
|
16484
18086
|
var set = Ember.set, get = Ember.get;
|
16485
18087
|
|
16486
|
-
|
16487
|
-
|
16488
|
-
|
16489
|
-
|
18088
|
+
/**
|
18089
|
+
@class
|
18090
|
+
|
18091
|
+
Creates an HTML input view in one of two formats.
|
18092
|
+
|
18093
|
+
If a `title` property or binding is provided the input will be wrapped in
|
18094
|
+
a `div` and `label` tag. View properties like `classNames` will be applied to
|
18095
|
+
the outermost `div`. This behavior is deprecated and will issue a warning in development.
|
18096
|
+
|
18097
|
+
|
18098
|
+
{{view Ember.Checkbox classNames="applicaton-specific-checkbox" title="Some title"}}
|
18099
|
+
|
18100
|
+
|
18101
|
+
<div id="ember1" class="ember-view ember-checkbox applicaton-specific-checkbox">
|
18102
|
+
<label><input type="checkbox" />Some title</label>
|
18103
|
+
</div>
|
18104
|
+
|
18105
|
+
If `title` isn't provided the view will render as an input element of the 'checkbox' type and HTML
|
18106
|
+
related properties will be applied directly to the input.
|
18107
|
+
|
18108
|
+
{{view Ember.Checkbox classNames="applicaton-specific-checkbox"}}
|
18109
|
+
|
18110
|
+
<input id="ember1" class="ember-view ember-checkbox applicaton-specific-checkbox" type="checkbox">
|
18111
|
+
|
18112
|
+
You can add a `label` tag yourself in the template where the Ember.Checkbox is being used.
|
18113
|
+
|
18114
|
+
<label>
|
18115
|
+
Some Title
|
18116
|
+
{{view Ember.Checkbox classNames="applicaton-specific-checkbox"}}
|
18117
|
+
</label>
|
18118
|
+
|
18119
|
+
|
18120
|
+
The `checked` attribute of an Ember.Checkbox object should always be set
|
18121
|
+
through the Ember object or by interacting with its rendered element representation
|
18122
|
+
via the mouse, keyboard, or touch. Updating the value of the checkbox via jQuery will
|
18123
|
+
result in the checked value of the object and its element losing synchronization.
|
16490
18124
|
|
18125
|
+
*/
|
16491
18126
|
Ember.Checkbox = Ember.View.extend({
|
16492
|
-
|
16493
|
-
|
18127
|
+
classNames: ['ember-checkbox'],
|
18128
|
+
|
18129
|
+
tagName: Ember.computed(function(){
|
18130
|
+
return get(this, 'title') ? undefined : 'input';
|
18131
|
+
}).property(),
|
18132
|
+
|
18133
|
+
attributeBindings: Ember.computed(function(){
|
18134
|
+
return get(this, 'title') ? [] : ['type', 'checked', 'disabled'];
|
18135
|
+
}).property(),
|
18136
|
+
|
18137
|
+
type: "checkbox",
|
18138
|
+
checked: false,
|
16494
18139
|
disabled: false,
|
16495
18140
|
|
16496
|
-
|
18141
|
+
title: Ember.computed(function(propName, value){
|
18142
|
+
ember_deprecate("Automatically surrounding Ember.Checkbox inputs with a label by providing a 'title' property is deprecated", value === undefined);
|
18143
|
+
return value;
|
18144
|
+
}).property().cacheable(),
|
16497
18145
|
|
16498
|
-
defaultTemplate: Ember.
|
18146
|
+
defaultTemplate: Ember.computed(function(){
|
18147
|
+
if (get(this, 'title')) {
|
18148
|
+
return Ember.Handlebars.compile('<label><input type="checkbox" {{bindAttr checked="checked" disabled="disabled"}}>{{title}}</label>');
|
18149
|
+
} else {
|
18150
|
+
return undefined;
|
18151
|
+
}
|
18152
|
+
}).property().cacheable(),
|
18153
|
+
|
18154
|
+
value: Ember.computed(function(propName, value){
|
18155
|
+
ember_deprecate("Ember.Checkbox's 'value' property has been renamed to 'checked' to match the html element attribute name");
|
18156
|
+
if (value !== undefined) {
|
18157
|
+
return set(this, 'checked', value);
|
18158
|
+
} else {
|
18159
|
+
return get(this, 'checked');
|
18160
|
+
}
|
18161
|
+
}).property('checked'),
|
16499
18162
|
|
16500
18163
|
change: function() {
|
16501
18164
|
Ember.run.once(this, this._updateElementValue);
|
16502
18165
|
// returning false will cause IE to not change checkbox state
|
16503
18166
|
},
|
16504
|
-
|
18167
|
+
|
18168
|
+
/**
|
18169
|
+
@private
|
18170
|
+
*/
|
16505
18171
|
_updateElementValue: function() {
|
16506
|
-
var input = this.$('input:checkbox');
|
16507
|
-
set(this, '
|
18172
|
+
var input = get(this, 'title') ? this.$('input:checkbox') : this.$();
|
18173
|
+
set(this, 'checked', input.prop('checked'));
|
16508
18174
|
}
|
16509
18175
|
});
|
16510
18176
|
|
18177
|
+
})();
|
18178
|
+
|
16511
18179
|
|
16512
|
-
})({});
|
16513
18180
|
|
16514
|
-
(function(
|
18181
|
+
(function() {
|
16515
18182
|
// ==========================================================================
|
16516
18183
|
// Project: Ember Handlebar Views
|
16517
18184
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -16567,9 +18234,11 @@ Ember.TextSupport.KEY_EVENTS = {
|
|
16567
18234
|
27: 'cancel'
|
16568
18235
|
};
|
16569
18236
|
|
16570
|
-
})(
|
18237
|
+
})();
|
18238
|
+
|
16571
18239
|
|
16572
|
-
|
18240
|
+
|
18241
|
+
(function() {
|
16573
18242
|
// ==========================================================================
|
16574
18243
|
// Project: Ember Handlebar Views
|
16575
18244
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -16592,9 +18261,11 @@ Ember.TextField = Ember.View.extend(Ember.TextSupport,
|
|
16592
18261
|
size: null
|
16593
18262
|
});
|
16594
18263
|
|
16595
|
-
})(
|
18264
|
+
})();
|
18265
|
+
|
18266
|
+
|
16596
18267
|
|
16597
|
-
(function(
|
18268
|
+
(function() {
|
16598
18269
|
// ==========================================================================
|
16599
18270
|
// Project: Ember Handlebar Views
|
16600
18271
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -16612,6 +18283,20 @@ Ember.Button = Ember.View.extend(Ember.TargetActionSupport, {
|
|
16612
18283
|
|
16613
18284
|
attributeBindings: ['type', 'disabled', 'href'],
|
16614
18285
|
|
18286
|
+
/** @private
|
18287
|
+
Overrides TargetActionSupport's targetObject computed
|
18288
|
+
property to use Handlebars-specific path resolution.
|
18289
|
+
*/
|
18290
|
+
targetObject: Ember.computed(function() {
|
18291
|
+
var target = get(this, 'target'),
|
18292
|
+
root = get(this, 'templateContext'),
|
18293
|
+
data = get(this, 'templateData');
|
18294
|
+
|
18295
|
+
if (typeof target !== 'string') { return target; }
|
18296
|
+
|
18297
|
+
return Ember.Handlebars.getPath(root, target, { data: data });
|
18298
|
+
}).property('target').cacheable(),
|
18299
|
+
|
16615
18300
|
// Defaults to 'button' if tagName is 'input' or 'button'
|
16616
18301
|
type: Ember.computed(function(key, value) {
|
16617
18302
|
var tagName = this.get('tagName');
|
@@ -16690,9 +18375,11 @@ Ember.Button = Ember.View.extend(Ember.TargetActionSupport, {
|
|
16690
18375
|
}
|
16691
18376
|
});
|
16692
18377
|
|
16693
|
-
})(
|
18378
|
+
})();
|
18379
|
+
|
16694
18380
|
|
16695
|
-
|
18381
|
+
|
18382
|
+
(function() {
|
16696
18383
|
// ==========================================================================
|
16697
18384
|
// Project: Ember Handlebar Views
|
16698
18385
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -16727,14 +18414,18 @@ Ember.TextArea = Ember.View.extend(Ember.TextSupport,
|
|
16727
18414
|
|
16728
18415
|
});
|
16729
18416
|
|
16730
|
-
})(
|
18417
|
+
})();
|
18418
|
+
|
18419
|
+
|
16731
18420
|
|
16732
|
-
(function(
|
18421
|
+
(function() {
|
16733
18422
|
Ember.TabContainerView = Ember.View.extend();
|
16734
18423
|
|
16735
|
-
})(
|
18424
|
+
})();
|
16736
18425
|
|
16737
|
-
|
18426
|
+
|
18427
|
+
|
18428
|
+
(function() {
|
16738
18429
|
var get = Ember.get, getPath = Ember.getPath;
|
16739
18430
|
|
16740
18431
|
Ember.TabPaneView = Ember.View.extend({
|
@@ -16747,9 +18438,11 @@ Ember.TabPaneView = Ember.View.extend({
|
|
16747
18438
|
}).property('tabsContainer.currentView')
|
16748
18439
|
});
|
16749
18440
|
|
16750
|
-
})(
|
18441
|
+
})();
|
18442
|
+
|
16751
18443
|
|
16752
|
-
|
18444
|
+
|
18445
|
+
(function() {
|
16753
18446
|
var get = Ember.get, setPath = Ember.setPath;
|
16754
18447
|
|
16755
18448
|
Ember.TabView = Ember.View.extend({
|
@@ -16762,17 +18455,21 @@ Ember.TabView = Ember.View.extend({
|
|
16762
18455
|
}
|
16763
18456
|
});
|
16764
18457
|
|
16765
|
-
})(
|
18458
|
+
})();
|
18459
|
+
|
16766
18460
|
|
16767
|
-
(function(exports) {
|
16768
18461
|
|
16769
|
-
|
18462
|
+
(function() {
|
16770
18463
|
|
16771
|
-
(
|
18464
|
+
})();
|
18465
|
+
|
18466
|
+
|
18467
|
+
|
18468
|
+
(function() {
|
16772
18469
|
/*jshint eqeqeq:false */
|
16773
18470
|
|
16774
18471
|
var set = Ember.set, get = Ember.get, getPath = Ember.getPath;
|
16775
|
-
var indexOf = Ember.ArrayUtils.indexOf;
|
18472
|
+
var indexOf = Ember.ArrayUtils.indexOf, indexesOf = Ember.ArrayUtils.indexesOf;
|
16776
18473
|
|
16777
18474
|
Ember.Select = Ember.View.extend({
|
16778
18475
|
tagName: 'select',
|
@@ -16780,7 +18477,9 @@ Ember.Select = Ember.View.extend({
|
|
16780
18477
|
'{{#if prompt}}<option>{{prompt}}</option>{{/if}}' +
|
16781
18478
|
'{{#each content}}{{view Ember.SelectOption contentBinding="this"}}{{/each}}'
|
16782
18479
|
),
|
18480
|
+
attributeBindings: ['multiple'],
|
16783
18481
|
|
18482
|
+
multiple: false,
|
16784
18483
|
content: null,
|
16785
18484
|
selection: null,
|
16786
18485
|
prompt: null,
|
@@ -16797,6 +18496,29 @@ Ember.Select = Ember.View.extend({
|
|
16797
18496
|
},
|
16798
18497
|
|
16799
18498
|
change: function() {
|
18499
|
+
if (get(this, 'multiple')) {
|
18500
|
+
this._changeMultiple();
|
18501
|
+
} else {
|
18502
|
+
this._changeSingle();
|
18503
|
+
}
|
18504
|
+
},
|
18505
|
+
|
18506
|
+
selectionDidChange: Ember.observer(function() {
|
18507
|
+
var selection = get(this, 'selection'),
|
18508
|
+
isArray = Ember.isArray(selection);
|
18509
|
+
if (get(this, 'multiple')) {
|
18510
|
+
if (!isArray) {
|
18511
|
+
set(this, 'selection', Ember.A([selection]));
|
18512
|
+
return;
|
18513
|
+
}
|
18514
|
+
this._selectionDidChangeMultiple();
|
18515
|
+
} else {
|
18516
|
+
this._selectionDidChangeSingle();
|
18517
|
+
}
|
18518
|
+
}, 'selection'),
|
18519
|
+
|
18520
|
+
|
18521
|
+
_changeSingle: function() {
|
16800
18522
|
var selectedIndex = this.$()[0].selectedIndex,
|
16801
18523
|
content = get(this, 'content'),
|
16802
18524
|
prompt = get(this, 'prompt');
|
@@ -16808,7 +18530,22 @@ Ember.Select = Ember.View.extend({
|
|
16808
18530
|
set(this, 'selection', content.objectAt(selectedIndex));
|
16809
18531
|
},
|
16810
18532
|
|
16811
|
-
|
18533
|
+
_changeMultiple: function() {
|
18534
|
+
var options = this.$('option:selected'),
|
18535
|
+
prompt = get(this, 'prompt'),
|
18536
|
+
offset = prompt ? 1 : 0,
|
18537
|
+
content = get(this, 'content');
|
18538
|
+
|
18539
|
+
if (!content){ return; }
|
18540
|
+
if (options) {
|
18541
|
+
var selectedIndexes = options.map(function(){
|
18542
|
+
return this.index - offset;
|
18543
|
+
}).toArray();
|
18544
|
+
set(this, 'selection', content.objectsAt(selectedIndexes));
|
18545
|
+
}
|
18546
|
+
},
|
18547
|
+
|
18548
|
+
_selectionDidChangeSingle: function() {
|
16812
18549
|
var el = this.$()[0],
|
16813
18550
|
content = get(this, 'content'),
|
16814
18551
|
selection = get(this, 'selection'),
|
@@ -16817,7 +18554,23 @@ Ember.Select = Ember.View.extend({
|
|
16817
18554
|
|
16818
18555
|
if (prompt) { selectionIndex += 1; }
|
16819
18556
|
if (el) { el.selectedIndex = selectionIndex; }
|
16820
|
-
},
|
18557
|
+
},
|
18558
|
+
|
18559
|
+
_selectionDidChangeMultiple: function() {
|
18560
|
+
var content = get(this, 'content'),
|
18561
|
+
selection = get(this, 'selection'),
|
18562
|
+
selectedIndexes = indexesOf(content, selection),
|
18563
|
+
prompt = get(this, 'prompt'),
|
18564
|
+
offset = prompt ? 1 : 0,
|
18565
|
+
options = this.$('option');
|
18566
|
+
|
18567
|
+
if (options) {
|
18568
|
+
options.each(function() {
|
18569
|
+
this.selected = indexOf(selectedIndexes, this.index + offset) > -1;
|
18570
|
+
});
|
18571
|
+
}
|
18572
|
+
}
|
18573
|
+
|
16821
18574
|
});
|
16822
18575
|
|
16823
18576
|
Ember.SelectOption = Ember.View.extend({
|
@@ -16833,8 +18586,15 @@ Ember.SelectOption = Ember.View.extend({
|
|
16833
18586
|
},
|
16834
18587
|
|
16835
18588
|
selected: Ember.computed(function() {
|
16836
|
-
|
16837
|
-
|
18589
|
+
var content = get(this, 'content'),
|
18590
|
+
selection = getPath(this, 'parentView.selection');
|
18591
|
+
if (getPath(this, 'parentView.multiple')) {
|
18592
|
+
return selection && indexOf(selection, content) > -1;
|
18593
|
+
} else {
|
18594
|
+
// Primitives get passed through bindings as objects... since
|
18595
|
+
// `new Number(4) !== 4`, we use `==` below
|
18596
|
+
return content == selection;
|
18597
|
+
}
|
16838
18598
|
}).property('content', 'parentView.selection'),
|
16839
18599
|
|
16840
18600
|
labelPathDidChange: Ember.observer(function() {
|
@@ -16859,18 +18619,22 @@ Ember.SelectOption = Ember.View.extend({
|
|
16859
18619
|
});
|
16860
18620
|
|
16861
18621
|
|
16862
|
-
})(
|
18622
|
+
})();
|
18623
|
+
|
18624
|
+
|
16863
18625
|
|
16864
|
-
(function(
|
18626
|
+
(function() {
|
16865
18627
|
// ==========================================================================
|
16866
18628
|
// Project: Ember Handlebar Views
|
16867
18629
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
16868
18630
|
// License: Licensed under MIT license (see license.js)
|
16869
18631
|
// ==========================================================================
|
16870
18632
|
|
16871
|
-
})(
|
18633
|
+
})();
|
18634
|
+
|
16872
18635
|
|
16873
|
-
|
18636
|
+
|
18637
|
+
(function() {
|
16874
18638
|
// ==========================================================================
|
16875
18639
|
// Project: Ember Handlebar Views
|
16876
18640
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
@@ -16903,15 +18667,12 @@ Ember.Handlebars.bootstrap = function(ctx) {
|
|
16903
18667
|
var compile = (script.attr('type') === 'text/x-raw-handlebars') ?
|
16904
18668
|
Ember.$.proxy(Handlebars.compile, Handlebars) :
|
16905
18669
|
Ember.$.proxy(Ember.Handlebars.compile, Ember.Handlebars),
|
16906
|
-
// Get the id of the script, used by Ember.View's elementId property,
|
16907
|
-
// Look for data-element-id attribute.
|
16908
|
-
elementId = script.attr('data-element-id'),
|
16909
18670
|
// Get the name of the script, used by Ember.View's templateName property.
|
16910
18671
|
// First look for data-template-name attribute, then fall back to its
|
16911
18672
|
// id if no name is found.
|
16912
18673
|
templateName = script.attr('data-template-name') || script.attr('id'),
|
16913
18674
|
template = compile(script.html()),
|
16914
|
-
view, viewPath, tagName;
|
18675
|
+
view, viewPath, elementId, tagName, options;
|
16915
18676
|
|
16916
18677
|
if (templateName) {
|
16917
18678
|
// For templates which have a name, we save them and then remove them from the DOM
|
@@ -16936,15 +18697,19 @@ Ember.Handlebars.bootstrap = function(ctx) {
|
|
16936
18697
|
viewPath = script.attr('data-view');
|
16937
18698
|
view = viewPath ? Ember.getPath(viewPath) : Ember.View;
|
16938
18699
|
|
18700
|
+
// Get the id of the script, used by Ember.View's elementId property,
|
18701
|
+
// Look for data-element-id attribute.
|
18702
|
+
elementId = script.attr('data-element-id');
|
18703
|
+
|
16939
18704
|
// Users can optionally specify a custom tag name to use by setting the
|
16940
18705
|
// data-tag-name attribute on the script tag.
|
16941
18706
|
tagName = script.attr('data-tag-name');
|
16942
18707
|
|
16943
|
-
|
16944
|
-
|
16945
|
-
|
16946
|
-
|
16947
|
-
|
18708
|
+
options = { template: template };
|
18709
|
+
if (elementId) { options.elementId = elementId; }
|
18710
|
+
if (tagName) { options.tagName = tagName; }
|
18711
|
+
|
18712
|
+
view = view.create(options);
|
16948
18713
|
|
16949
18714
|
view._insertElementLater(function() {
|
16950
18715
|
script.replaceWith(this.$());
|
@@ -16962,23 +18727,25 @@ Ember.$(document).ready(
|
|
16962
18727
|
}
|
16963
18728
|
);
|
16964
18729
|
|
16965
|
-
})(
|
18730
|
+
})();
|
16966
18731
|
|
16967
|
-
|
18732
|
+
|
18733
|
+
|
18734
|
+
(function() {
|
16968
18735
|
// ==========================================================================
|
16969
18736
|
// Project: Ember Handlebar Views
|
16970
18737
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
16971
18738
|
// License: Licensed under MIT license (see license.js)
|
16972
18739
|
// ==========================================================================
|
16973
18740
|
|
16974
|
-
})(
|
18741
|
+
})();
|
16975
18742
|
|
16976
|
-
(function(
|
18743
|
+
(function() {
|
16977
18744
|
// ==========================================================================
|
16978
18745
|
// Project: Ember
|
16979
18746
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
16980
18747
|
// License: Licensed under MIT license (see license.js)
|
16981
18748
|
// ==========================================================================
|
16982
18749
|
|
16983
|
-
})(
|
18750
|
+
})();
|
16984
18751
|
|