embient 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
|