rasputin 0.13.2 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +5 -8
- data/lib/rasputin/handlebars/compiler.rb +1 -1
- data/lib/rasputin/version.rb +1 -1
- data/vendor/assets/javascripts/ember-data.js +275 -75
- data/vendor/assets/javascripts/ember-precompiler.js +5 -12
- data/vendor/assets/javascripts/ember.js +1305 -567
- metadata +10 -12
- data/vendor/assets/javascripts/ember-datetime.js +0 -1187
- data/vendor/assets/javascripts/modernizr.js +0 -1116
@@ -15,17 +15,10 @@ console.log = console.info = console.warn = console.error = function(){};
|
|
15
15
|
var jQuery = function() { return jQuery; };
|
16
16
|
jQuery.ready = function() { return jQuery; };
|
17
17
|
jQuery.inArray = function() { return jQuery; };
|
18
|
+
jQuery.jquery = "1.7.1";
|
18
19
|
var $ = jQuery;
|
19
20
|
|
20
|
-
//
|
21
|
-
|
22
|
-
precompile
|
23
|
-
|
24
|
-
var ast = Handlebars.parse(string);
|
25
|
-
var options = { data: true, stringParams: true };
|
26
|
-
var environment = new Ember.Handlebars.Compiler().compile(ast, options);
|
27
|
-
var templateSpec = new Ember.Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true);
|
28
|
-
|
29
|
-
return templateSpec.toString();
|
30
|
-
}
|
31
|
-
};
|
21
|
+
// Ember
|
22
|
+
function precompileEmberHandlebars(string) {
|
23
|
+
return Ember.Handlebars.precompile(string).toString();
|
24
|
+
}
|
@@ -1608,7 +1608,7 @@ if ('undefined' === typeof Ember) {
|
|
1608
1608
|
/**
|
1609
1609
|
@namespace
|
1610
1610
|
@name Ember
|
1611
|
-
@version 0.9.
|
1611
|
+
@version 0.9.4
|
1612
1612
|
|
1613
1613
|
All Ember methods and functions are defined inside of this namespace.
|
1614
1614
|
You generally should not add new properties to this namespace as it may be
|
@@ -1640,10 +1640,10 @@ if ('undefined' !== typeof window) {
|
|
1640
1640
|
/**
|
1641
1641
|
@static
|
1642
1642
|
@type String
|
1643
|
-
@default '0.9.
|
1643
|
+
@default '0.9.4'
|
1644
1644
|
@constant
|
1645
1645
|
*/
|
1646
|
-
Ember.VERSION = '0.9.
|
1646
|
+
Ember.VERSION = '0.9.4';
|
1647
1647
|
|
1648
1648
|
/**
|
1649
1649
|
@static
|
@@ -1664,6 +1664,12 @@ Ember.ENV = 'undefined' === typeof ENV ? {} : ENV;
|
|
1664
1664
|
*/
|
1665
1665
|
Ember.K = function() { return this; };
|
1666
1666
|
|
1667
|
+
/**
|
1668
|
+
@namespace
|
1669
|
+
@name window
|
1670
|
+
@description The global window object
|
1671
|
+
*/
|
1672
|
+
|
1667
1673
|
/**
|
1668
1674
|
Define an assertion that will throw an exception if the condition is not
|
1669
1675
|
met. Ember build tools will remove any calls to ember_assert() when
|
@@ -1729,11 +1735,15 @@ Ember.Logger = window.console || { log: Ember.K, warn: Ember.K, error: Ember.K }
|
|
1729
1735
|
@class
|
1730
1736
|
|
1731
1737
|
Platform specific methods and feature detectors needed by the framework.
|
1738
|
+
|
1739
|
+
@name Ember.platform
|
1732
1740
|
*/
|
1733
1741
|
var platform = Ember.platform = {} ;
|
1734
1742
|
|
1735
1743
|
/**
|
1736
1744
|
Identical to Object.create(). Implements if not available natively.
|
1745
|
+
@memberOf Ember.platform
|
1746
|
+
@name create
|
1737
1747
|
*/
|
1738
1748
|
platform.create = Object.create;
|
1739
1749
|
|
@@ -1831,6 +1841,8 @@ if (defineProperty) {
|
|
1831
1841
|
Identical to Object.defineProperty(). Implements as much functionality
|
1832
1842
|
as possible if not available natively.
|
1833
1843
|
|
1844
|
+
@memberOf Ember.platform
|
1845
|
+
@name defineProperty
|
1834
1846
|
@param {Object} obj The object to modify
|
1835
1847
|
@param {String} keyName property name to modify
|
1836
1848
|
@param {Object} desc descriptor hash
|
@@ -1840,6 +1852,9 @@ platform.defineProperty = defineProperty;
|
|
1840
1852
|
|
1841
1853
|
/**
|
1842
1854
|
Set to true if the platform supports native getters and setters.
|
1855
|
+
|
1856
|
+
@memberOf Ember.platform
|
1857
|
+
@name hasPropertyAccessors
|
1843
1858
|
*/
|
1844
1859
|
platform.hasPropertyAccessors = true;
|
1845
1860
|
|
@@ -2028,8 +2043,6 @@ if (Object.freeze) Object.freeze(EMPTY_META);
|
|
2028
2043
|
@returns {Hash}
|
2029
2044
|
*/
|
2030
2045
|
Ember.meta = function meta(obj, writable) {
|
2031
|
-
|
2032
|
-
ember_assert("You must pass an object to Ember.meta. This was probably called from Ember internals, so you probably called a Ember method with undefined that was expecting an object", obj != undefined);
|
2033
2046
|
|
2034
2047
|
var ret = obj[META_KEY];
|
2035
2048
|
if (writable===false) return ret || EMPTY_META;
|
@@ -2218,6 +2231,7 @@ var meta = Ember.meta;
|
|
2218
2231
|
|
2219
2232
|
var get, set;
|
2220
2233
|
|
2234
|
+
/** @private */
|
2221
2235
|
get = function get(obj, keyName) {
|
2222
2236
|
if (keyName === undefined && 'string' === typeof obj) {
|
2223
2237
|
keyName = obj;
|
@@ -2232,6 +2246,7 @@ get = function get(obj, keyName) {
|
|
2232
2246
|
return ret;
|
2233
2247
|
};
|
2234
2248
|
|
2249
|
+
/** @private */
|
2235
2250
|
set = function set(obj, keyName, value) {
|
2236
2251
|
if (('object'===typeof obj) && !(keyName in obj)) {
|
2237
2252
|
if ('function' === typeof obj.setUnknownProperty) {
|
@@ -2372,8 +2387,8 @@ function getPath(target, path) {
|
|
2372
2387
|
}
|
2373
2388
|
|
2374
2389
|
var TUPLE_RET = [];
|
2375
|
-
var IS_GLOBAL = /^([A-Z$]|([0-9][A-Z$]))
|
2376
|
-
var
|
2390
|
+
var IS_GLOBAL = /^([A-Z$]|([0-9][A-Z$]))/;
|
2391
|
+
var IS_GLOBAL_PATH = /^([A-Z$]|([0-9][A-Z$])).*[\.\*]/;
|
2377
2392
|
var HAS_THIS = /^this[\.\*]/;
|
2378
2393
|
var FIRST_KEY = /^([^\.\*]+)/;
|
2379
2394
|
|
@@ -2384,7 +2399,7 @@ function firstKey(path) {
|
|
2384
2399
|
// assumes path is already normalized
|
2385
2400
|
function normalizeTuple(target, path) {
|
2386
2401
|
var hasThis = HAS_THIS.test(path),
|
2387
|
-
isGlobal = !hasThis &&
|
2402
|
+
isGlobal = !hasThis && IS_GLOBAL_PATH.test(path),
|
2388
2403
|
key;
|
2389
2404
|
|
2390
2405
|
if (!target || isGlobal) target = window;
|
@@ -2449,9 +2464,14 @@ Ember.normalizeTuple = function(target, path) {
|
|
2449
2464
|
|
2450
2465
|
Ember.normalizeTuple.primitive = normalizeTuple;
|
2451
2466
|
|
2452
|
-
Ember.getPath = function(root, path) {
|
2453
|
-
var hasThis, hasStar, isGlobal;
|
2467
|
+
Ember.getPath = function(root, path, _checkGlobal) {
|
2468
|
+
var hasThis, hasStar, isGlobal, ret;
|
2454
2469
|
|
2470
|
+
// Helpers that operate with 'this' within an #each
|
2471
|
+
if (path === '') {
|
2472
|
+
return root;
|
2473
|
+
}
|
2474
|
+
|
2455
2475
|
if (!path && 'string'===typeof root) {
|
2456
2476
|
path = root;
|
2457
2477
|
root = null;
|
@@ -2467,14 +2487,26 @@ Ember.getPath = function(root, path) {
|
|
2467
2487
|
// detect complicated paths and normalize them
|
2468
2488
|
path = normalizePath(path);
|
2469
2489
|
hasThis = HAS_THIS.test(path);
|
2470
|
-
|
2471
|
-
if (!root || hasThis ||
|
2490
|
+
|
2491
|
+
if (!root || hasThis || hasStar) {
|
2492
|
+
if (root && root !== window && IS_GLOBAL.test(path)) {
|
2493
|
+
console.warn("Fetching globals with Ember.getPath is deprecated", root, path);
|
2494
|
+
}
|
2495
|
+
|
2472
2496
|
var tuple = normalizeTuple(root, path);
|
2473
2497
|
root = tuple[0];
|
2474
2498
|
path = tuple[1];
|
2475
|
-
|
2476
|
-
|
2477
|
-
|
2499
|
+
tuple.length = 0;
|
2500
|
+
}
|
2501
|
+
|
2502
|
+
ret = getPath(root, path);
|
2503
|
+
|
2504
|
+
if (ret === undefined && root !== window && !hasThis && IS_GLOBAL.test(path) && _checkGlobal !== false) {
|
2505
|
+
console.warn("Fetching globals with Ember.getPath is deprecated", root, path);
|
2506
|
+
return Ember.getPath(window, path);
|
2507
|
+
} else {
|
2508
|
+
return ret;
|
2509
|
+
}
|
2478
2510
|
};
|
2479
2511
|
|
2480
2512
|
Ember.setPath = function(root, path, value, tolerant) {
|
@@ -2488,22 +2520,30 @@ Ember.setPath = function(root, path, value, tolerant) {
|
|
2488
2520
|
|
2489
2521
|
path = normalizePath(path);
|
2490
2522
|
if (path.indexOf('*')>0) {
|
2523
|
+
if (root && root !== window && IS_GLOBAL.test(path)) {
|
2524
|
+
console.warn("Setting globals with Ember.setPath is deprecated", path);
|
2525
|
+
};
|
2526
|
+
|
2491
2527
|
var tuple = normalizeTuple(root, path);
|
2492
2528
|
root = tuple[0];
|
2493
2529
|
path = tuple[1];
|
2530
|
+
tuple.length = 0;
|
2494
2531
|
}
|
2495
2532
|
|
2496
2533
|
if (path.indexOf('.') > 0) {
|
2497
2534
|
keyName = path.slice(path.lastIndexOf('.')+1);
|
2498
2535
|
path = path.slice(0, path.length-(keyName.length+1));
|
2499
|
-
if (
|
2500
|
-
|
2501
|
-
|
2502
|
-
root
|
2536
|
+
if (path !== 'this') {
|
2537
|
+
// Remove the `false` when we're done with this deprecation
|
2538
|
+
root = Ember.getPath(root, path, false);
|
2539
|
+
if (!root && IS_GLOBAL.test(path)) {
|
2540
|
+
console.warn("Setting globals with Ember.setPath is deprecated", path);
|
2541
|
+
root = Ember.getPath(window, path);
|
2542
|
+
}
|
2503
2543
|
}
|
2504
2544
|
|
2505
2545
|
} else {
|
2506
|
-
if (
|
2546
|
+
if (IS_GLOBAL.test(path)) throw new Error('Invalid Path');
|
2507
2547
|
keyName = path;
|
2508
2548
|
}
|
2509
2549
|
|
@@ -2735,7 +2775,9 @@ function xformForArgs(args) {
|
|
2735
2775
|
return function (target, method, params) {
|
2736
2776
|
var obj = params[0], keyName = changeKey(params[1]), val;
|
2737
2777
|
var copy_args = args.slice();
|
2738
|
-
if (method.length>2)
|
2778
|
+
if (method.length>2) {
|
2779
|
+
val = Ember.getPath(Ember.isGlobalPath(keyName) ? window : obj, keyName);
|
2780
|
+
}
|
2739
2781
|
copy_args.unshift(obj, keyName, val);
|
2740
2782
|
method.apply(target, copy_args);
|
2741
2783
|
};
|
@@ -3138,9 +3180,10 @@ function hasDesc(descs, keyName) {
|
|
3138
3180
|
}).property('firstName', 'lastName').cacheable());
|
3139
3181
|
*/
|
3140
3182
|
Ember.defineProperty = function(obj, keyName, desc, val) {
|
3141
|
-
var m = meta(obj, false), descs = m.descs, watching = m.watching[keyName]>0;
|
3183
|
+
var m = meta(obj, false), descs = m.descs, watching = m.watching[keyName]>0, override = true;
|
3142
3184
|
|
3143
3185
|
if (val === undefined) {
|
3186
|
+
override = false;
|
3144
3187
|
val = hasDesc(descs, keyName) ? descs[keyName].teardown(obj, keyName) : obj[keyName];
|
3145
3188
|
} else if (hasDesc(descs, keyName)) {
|
3146
3189
|
descs[keyName].teardown(obj, keyName);
|
@@ -3161,7 +3204,11 @@ Ember.defineProperty = function(obj, keyName, desc, val) {
|
|
3161
3204
|
if (descs[keyName]) meta(obj).descs[keyName] = null;
|
3162
3205
|
o_defineProperty(obj, keyName, desc);
|
3163
3206
|
}
|
3164
|
-
|
3207
|
+
|
3208
|
+
// if key is being watched, override chains that
|
3209
|
+
// were initialized with the prototype
|
3210
|
+
if (override && watching) Ember.overrideChains(obj, keyName, m);
|
3211
|
+
|
3165
3212
|
return this;
|
3166
3213
|
};
|
3167
3214
|
|
@@ -3218,19 +3265,6 @@ Ember.createPrototype = function(obj, props) {
|
|
3218
3265
|
if (META_KEY in ret) Ember.rewatch(ret); // setup watch chains if needed.
|
3219
3266
|
return ret;
|
3220
3267
|
};
|
3221
|
-
|
3222
|
-
|
3223
|
-
/**
|
3224
|
-
Tears down the meta on an object so that it can be garbage collected.
|
3225
|
-
Multiple calls will have no effect.
|
3226
|
-
|
3227
|
-
@param {Object} obj the object to destroy
|
3228
|
-
@returns {void}
|
3229
|
-
*/
|
3230
|
-
Ember.destroy = function(obj) {
|
3231
|
-
if (obj[META_KEY]) obj[META_KEY] = null;
|
3232
|
-
};
|
3233
|
-
|
3234
3268
|
|
3235
3269
|
})({});
|
3236
3270
|
|
@@ -3249,6 +3283,7 @@ var normalizeTuple = Ember.normalizeTuple.primitive;
|
|
3249
3283
|
var normalizePath = Ember.normalizePath;
|
3250
3284
|
var SIMPLE_PROPERTY = Ember.SIMPLE_PROPERTY;
|
3251
3285
|
var GUID_KEY = Ember.GUID_KEY;
|
3286
|
+
var META_KEY = Ember.META_KEY;
|
3252
3287
|
var notifyObservers = Ember.notifyObservers;
|
3253
3288
|
|
3254
3289
|
var FIRST_KEY = /^([^\.\*]+)/;
|
@@ -3265,17 +3300,17 @@ function isKeyName(path) {
|
|
3265
3300
|
|
3266
3301
|
// ..........................................................
|
3267
3302
|
// DEPENDENT KEYS
|
3268
|
-
//
|
3303
|
+
//
|
3269
3304
|
|
3270
3305
|
var DEP_SKIP = { __emberproto__: true }; // skip some keys and toString
|
3271
|
-
function iterDeps(
|
3272
|
-
|
3306
|
+
function iterDeps(method, obj, depKey, seen, meta) {
|
3307
|
+
|
3273
3308
|
var guid = guidFor(obj);
|
3274
3309
|
if (!seen[guid]) seen[guid] = {};
|
3275
3310
|
if (seen[guid][depKey]) return ;
|
3276
3311
|
seen[guid][depKey] = true;
|
3277
|
-
|
3278
|
-
var deps = meta
|
3312
|
+
|
3313
|
+
var deps = meta.deps;
|
3279
3314
|
deps = deps && deps[depKey];
|
3280
3315
|
if (deps) {
|
3281
3316
|
for(var key in deps) {
|
@@ -3289,18 +3324,18 @@ function iterDeps(methodName, obj, depKey, seen) {
|
|
3289
3324
|
var WILL_SEEN, DID_SEEN;
|
3290
3325
|
|
3291
3326
|
// called whenever a property is about to change to clear the cache of any dependent keys (and notify those properties of changes, etc...)
|
3292
|
-
function dependentKeysWillChange(obj, depKey) {
|
3327
|
+
function dependentKeysWillChange(obj, depKey, meta) {
|
3293
3328
|
var seen = WILL_SEEN, top = !seen;
|
3294
3329
|
if (top) seen = WILL_SEEN = {};
|
3295
|
-
iterDeps(
|
3330
|
+
iterDeps(propertyWillChange, obj, depKey, seen, meta);
|
3296
3331
|
if (top) WILL_SEEN = null;
|
3297
3332
|
}
|
3298
3333
|
|
3299
3334
|
// called whenever a property has just changed to update dependent keys
|
3300
|
-
function dependentKeysDidChange(obj, depKey) {
|
3335
|
+
function dependentKeysDidChange(obj, depKey, meta) {
|
3301
3336
|
var seen = DID_SEEN, top = !seen;
|
3302
3337
|
if (top) seen = DID_SEEN = {};
|
3303
|
-
iterDeps(
|
3338
|
+
iterDeps(propertyDidChange, obj, depKey, seen, meta);
|
3304
3339
|
if (top) DID_SEEN = null;
|
3305
3340
|
}
|
3306
3341
|
|
@@ -3436,6 +3471,7 @@ Wp.add = function(path) {
|
|
3436
3471
|
// put into a queue and try to connect later.
|
3437
3472
|
} else if (!tuple[0]) {
|
3438
3473
|
pendingQueue.push([this, path]);
|
3474
|
+
tuple.length = 0;
|
3439
3475
|
return;
|
3440
3476
|
|
3441
3477
|
// global path, and object already exists
|
@@ -3446,6 +3482,7 @@ Wp.add = function(path) {
|
|
3446
3482
|
path = tuple[1];
|
3447
3483
|
}
|
3448
3484
|
|
3485
|
+
tuple.length = 0;
|
3449
3486
|
this.chain(key, path, src, separator);
|
3450
3487
|
};
|
3451
3488
|
|
@@ -3470,6 +3507,7 @@ Wp.remove = function(path) {
|
|
3470
3507
|
path = tuple[1];
|
3471
3508
|
}
|
3472
3509
|
|
3510
|
+
tuple.length = 0;
|
3473
3511
|
this.unchain(key, path);
|
3474
3512
|
};
|
3475
3513
|
|
@@ -3545,7 +3583,7 @@ Wp.chainDidChange = function(chain, path, depth) {
|
|
3545
3583
|
}
|
3546
3584
|
};
|
3547
3585
|
|
3548
|
-
Wp.didChange = function() {
|
3586
|
+
Wp.didChange = function(suppressEvent) {
|
3549
3587
|
// invalidate my own value first.
|
3550
3588
|
if (this._watching) {
|
3551
3589
|
var obj = this._parent.value();
|
@@ -3567,10 +3605,12 @@ Wp.didChange = function() {
|
|
3567
3605
|
if (chains) {
|
3568
3606
|
for(var key in chains) {
|
3569
3607
|
if (!chains.hasOwnProperty(key)) continue;
|
3570
|
-
chains[key].didChange();
|
3608
|
+
chains[key].didChange(suppressEvent);
|
3571
3609
|
}
|
3572
3610
|
}
|
3573
3611
|
|
3612
|
+
if (suppressEvent) return;
|
3613
|
+
|
3574
3614
|
// and finally tell parent about my path changing...
|
3575
3615
|
if (this._parent) this._parent.chainDidChange(this, this._key, 1);
|
3576
3616
|
};
|
@@ -3590,26 +3630,30 @@ function chainsFor(obj) {
|
|
3590
3630
|
|
3591
3631
|
|
3592
3632
|
|
3593
|
-
function notifyChains(obj, keyName, methodName) {
|
3594
|
-
var m = meta(obj, false);
|
3633
|
+
function notifyChains(obj, m, keyName, methodName, arg) {
|
3595
3634
|
var nodes = m.chainWatchers;
|
3635
|
+
|
3596
3636
|
if (!nodes || nodes.__emberproto__ !== obj) return; // nothing to do
|
3597
3637
|
|
3598
3638
|
nodes = nodes[keyName];
|
3599
3639
|
if (!nodes) return;
|
3600
|
-
|
3640
|
+
|
3601
3641
|
for(var key in nodes) {
|
3602
3642
|
if (!nodes.hasOwnProperty(key)) continue;
|
3603
|
-
nodes[key][methodName](
|
3643
|
+
nodes[key][methodName](arg);
|
3604
3644
|
}
|
3605
3645
|
}
|
3606
3646
|
|
3607
|
-
function
|
3608
|
-
notifyChains(obj, keyName, '
|
3647
|
+
Ember.overrideChains = function(obj, keyName, m) {
|
3648
|
+
notifyChains(obj, m, keyName, 'didChange', true);
|
3609
3649
|
}
|
3610
3650
|
|
3611
|
-
function
|
3612
|
-
notifyChains(obj, keyName, '
|
3651
|
+
function chainsWillChange(obj, keyName, m) {
|
3652
|
+
notifyChains(obj, m, keyName, 'willChange');
|
3653
|
+
}
|
3654
|
+
|
3655
|
+
function chainsDidChange(obj, keyName, m) {
|
3656
|
+
notifyChains(obj, m, keyName, 'didChange');
|
3613
3657
|
}
|
3614
3658
|
|
3615
3659
|
// ..........................................................
|
@@ -3732,12 +3776,12 @@ Ember.rewatch = function(obj) {
|
|
3732
3776
|
|
3733
3777
|
@returns {void}
|
3734
3778
|
*/
|
3735
|
-
Ember.propertyWillChange = function(obj, keyName) {
|
3779
|
+
var propertyWillChange = Ember.propertyWillChange = function(obj, keyName) {
|
3736
3780
|
var m = meta(obj, false), proto = m.proto, desc = m.descs[keyName];
|
3737
3781
|
if (proto === obj) return ;
|
3738
3782
|
if (desc && desc.willChange) desc.willChange(obj, keyName);
|
3739
|
-
dependentKeysWillChange(obj, keyName);
|
3740
|
-
chainsWillChange(obj, keyName);
|
3783
|
+
dependentKeysWillChange(obj, keyName, m);
|
3784
|
+
chainsWillChange(obj, keyName, m);
|
3741
3785
|
Ember.notifyBeforeObservers(obj, keyName);
|
3742
3786
|
};
|
3743
3787
|
|
@@ -3758,15 +3802,56 @@ Ember.propertyWillChange = function(obj, keyName) {
|
|
3758
3802
|
|
3759
3803
|
@returns {void}
|
3760
3804
|
*/
|
3761
|
-
Ember.propertyDidChange = function(obj, keyName) {
|
3805
|
+
var propertyDidChange = Ember.propertyDidChange = function(obj, keyName) {
|
3762
3806
|
var m = meta(obj, false), proto = m.proto, desc = m.descs[keyName];
|
3763
3807
|
if (proto === obj) return ;
|
3764
3808
|
if (desc && desc.didChange) desc.didChange(obj, keyName);
|
3765
|
-
dependentKeysDidChange(obj, keyName);
|
3766
|
-
chainsDidChange(obj, keyName);
|
3809
|
+
dependentKeysDidChange(obj, keyName, m);
|
3810
|
+
chainsDidChange(obj, keyName, m);
|
3767
3811
|
Ember.notifyObservers(obj, keyName);
|
3768
3812
|
};
|
3769
3813
|
|
3814
|
+
var NODE_STACK = []
|
3815
|
+
|
3816
|
+
/**
|
3817
|
+
Tears down the meta on an object so that it can be garbage collected.
|
3818
|
+
Multiple calls will have no effect.
|
3819
|
+
|
3820
|
+
@param {Object} obj the object to destroy
|
3821
|
+
@returns {void}
|
3822
|
+
*/
|
3823
|
+
Ember.destroy = function (obj) {
|
3824
|
+
var meta = obj[META_KEY], node, nodes, key, nodeObject;
|
3825
|
+
if (meta) {
|
3826
|
+
obj[META_KEY] = null;
|
3827
|
+
// remove chainWatchers to remove circular references that would prevent GC
|
3828
|
+
node = meta.chains;
|
3829
|
+
if (node) {
|
3830
|
+
NODE_STACK.push(node);
|
3831
|
+
// process tree
|
3832
|
+
while (NODE_STACK.length > 0) {
|
3833
|
+
node = NODE_STACK.pop();
|
3834
|
+
// push children
|
3835
|
+
nodes = node._chains;
|
3836
|
+
if (nodes) {
|
3837
|
+
for (key in nodes) {
|
3838
|
+
if (nodes.hasOwnProperty(key)) {
|
3839
|
+
NODE_STACK.push(nodes[key]);
|
3840
|
+
}
|
3841
|
+
}
|
3842
|
+
}
|
3843
|
+
// remove chainWatcher in node object
|
3844
|
+
if (node._watching) {
|
3845
|
+
nodeObject = node._object;
|
3846
|
+
if (nodeObject) {
|
3847
|
+
removeChainWatcher(nodeObject, node._key, node);
|
3848
|
+
}
|
3849
|
+
}
|
3850
|
+
}
|
3851
|
+
}
|
3852
|
+
}
|
3853
|
+
};
|
3854
|
+
|
3770
3855
|
})({});
|
3771
3856
|
|
3772
3857
|
|
@@ -3802,8 +3887,20 @@ function invoke(target, method, args, ignore) {
|
|
3802
3887
|
if (args && ignore>0) {
|
3803
3888
|
args = args.length>ignore ? slice.call(args, ignore) : null;
|
3804
3889
|
}
|
3805
|
-
|
3806
|
-
|
3890
|
+
|
3891
|
+
// Unfortunately in some browsers we lose the backtrace if we rethrow the existing error,
|
3892
|
+
// so in the event that we don't have an `onerror` handler we don't wrap in a try/catch
|
3893
|
+
if ('function' === typeof Ember.onerror) {
|
3894
|
+
try {
|
3895
|
+
// IE8's Function.prototype.apply doesn't accept undefined/null arguments.
|
3896
|
+
return method.apply(target || this, args || []);
|
3897
|
+
} catch (error) {
|
3898
|
+
Ember.onerror(error);
|
3899
|
+
}
|
3900
|
+
} else {
|
3901
|
+
// IE8's Function.prototype.apply doesn't accept undefined/null arguments.
|
3902
|
+
return method.apply(target || this, args || []);
|
3903
|
+
}
|
3807
3904
|
}
|
3808
3905
|
|
3809
3906
|
|
@@ -3948,8 +4045,11 @@ Ember.run = run = function(target, method) {
|
|
3948
4045
|
|
3949
4046
|
var ret, loop;
|
3950
4047
|
run.begin();
|
3951
|
-
|
3952
|
-
|
4048
|
+
try {
|
4049
|
+
if (target || method) ret = invoke(target, method, arguments, 2);
|
4050
|
+
} finally {
|
4051
|
+
run.end();
|
4052
|
+
}
|
3953
4053
|
return ret;
|
3954
4054
|
};
|
3955
4055
|
|
@@ -4257,11 +4357,17 @@ Ember.run.cancel = function(timer) {
|
|
4257
4357
|
delete timers[timer];
|
4258
4358
|
};
|
4259
4359
|
|
4260
|
-
|
4261
4360
|
// ..........................................................
|
4262
4361
|
// DEPRECATED API
|
4263
4362
|
//
|
4264
4363
|
|
4364
|
+
/**
|
4365
|
+
@namespace
|
4366
|
+
@name Ember.RunLoop
|
4367
|
+
@deprecated
|
4368
|
+
@description Compatibility for Ember.run
|
4369
|
+
*/
|
4370
|
+
|
4265
4371
|
/**
|
4266
4372
|
@deprecated
|
4267
4373
|
@method
|
@@ -4394,7 +4500,8 @@ var NOT = {
|
|
4394
4500
|
var get = Ember.get,
|
4395
4501
|
getPath = Ember.getPath,
|
4396
4502
|
setPath = Ember.setPath,
|
4397
|
-
guidFor = Ember.guidFor
|
4503
|
+
guidFor = Ember.guidFor,
|
4504
|
+
isGlobalPath = Ember.isGlobalPath;
|
4398
4505
|
|
4399
4506
|
// Applies a binding's transformations against a value.
|
4400
4507
|
function getTransformedValue(binding, val, obj, dir) {
|
@@ -4422,9 +4529,18 @@ function empty(val) {
|
|
4422
4529
|
return val===undefined || val===null || val==='' || (Ember.isArray(val) && get(val, 'length')===0) ;
|
4423
4530
|
}
|
4424
4531
|
|
4532
|
+
function getPathWithGlobals(obj, path) {
|
4533
|
+
return getPath(isGlobalPath(path) ? window : obj, path);
|
4534
|
+
}
|
4535
|
+
|
4425
4536
|
function getTransformedFromValue(obj, binding) {
|
4426
|
-
var operation = binding._operation
|
4427
|
-
|
4537
|
+
var operation = binding._operation,
|
4538
|
+
fromValue;
|
4539
|
+
if (operation) {
|
4540
|
+
fromValue = operation(obj, binding._from, binding._operand);
|
4541
|
+
} else {
|
4542
|
+
fromValue = getPathWithGlobals(obj, binding._from);
|
4543
|
+
}
|
4428
4544
|
return getTransformedValue(binding, fromValue, obj, 'to');
|
4429
4545
|
}
|
4430
4546
|
|
@@ -4434,177 +4550,17 @@ function getTransformedToValue(obj, binding) {
|
|
4434
4550
|
}
|
4435
4551
|
|
4436
4552
|
var AND_OPERATION = function(obj, left, right) {
|
4437
|
-
return
|
4553
|
+
return getPathWithGlobals(obj, left) && getPathWithGlobals(obj, right);
|
4438
4554
|
};
|
4439
4555
|
|
4440
4556
|
var OR_OPERATION = function(obj, left, right) {
|
4441
|
-
return
|
4557
|
+
return getPathWithGlobals(obj, left) || getPathWithGlobals(obj, right);
|
4442
4558
|
};
|
4443
4559
|
|
4444
4560
|
// ..........................................................
|
4445
4561
|
// BINDING
|
4446
4562
|
//
|
4447
4563
|
|
4448
|
-
/**
|
4449
|
-
@class
|
4450
|
-
|
4451
|
-
A binding simply connects the properties of two objects so that whenever the
|
4452
|
-
value of one property changes, the other property will be changed also. You
|
4453
|
-
do not usually work with Binding objects directly but instead describe
|
4454
|
-
bindings in your class definition using something like:
|
4455
|
-
|
4456
|
-
valueBinding: "MyApp.someController.title"
|
4457
|
-
|
4458
|
-
This will create a binding from `MyApp.someController.title` to the `value`
|
4459
|
-
property of your object instance automatically. Now the two values will be
|
4460
|
-
kept in sync.
|
4461
|
-
|
4462
|
-
## Customizing Your Bindings
|
4463
|
-
|
4464
|
-
In addition to synchronizing values, bindings can also perform some basic
|
4465
|
-
transforms on values. These transforms can help to make sure the data fed
|
4466
|
-
into one object always meets the expectations of that object regardless of
|
4467
|
-
what the other object outputs.
|
4468
|
-
|
4469
|
-
To customize a binding, you can use one of the many helper methods defined
|
4470
|
-
on Ember.Binding like so:
|
4471
|
-
|
4472
|
-
valueBinding: Ember.Binding.single("MyApp.someController.title")
|
4473
|
-
|
4474
|
-
This will create a binding just like the example above, except that now the
|
4475
|
-
binding will convert the value of `MyApp.someController.title` to a single
|
4476
|
-
object (removing any arrays) before applying it to the `value` property of
|
4477
|
-
your object.
|
4478
|
-
|
4479
|
-
You can also chain helper methods to build custom bindings like so:
|
4480
|
-
|
4481
|
-
valueBinding: Ember.Binding.single("MyApp.someController.title").notEmpty("(EMPTY)")
|
4482
|
-
|
4483
|
-
This will force the value of MyApp.someController.title to be a single value
|
4484
|
-
and then check to see if the value is "empty" (null, undefined, empty array,
|
4485
|
-
or an empty string). If it is empty, the value will be set to the string
|
4486
|
-
"(EMPTY)".
|
4487
|
-
|
4488
|
-
## One Way Bindings
|
4489
|
-
|
4490
|
-
One especially useful binding customization you can use is the `oneWay()`
|
4491
|
-
helper. This helper tells Ember that you are only interested in
|
4492
|
-
receiving changes on the object you are binding from. For example, if you
|
4493
|
-
are binding to a preference and you want to be notified if the preference
|
4494
|
-
has changed, but your object will not be changing the preference itself, you
|
4495
|
-
could do:
|
4496
|
-
|
4497
|
-
bigTitlesBinding: Ember.Binding.oneWay("MyApp.preferencesController.bigTitles")
|
4498
|
-
|
4499
|
-
This way if the value of MyApp.preferencesController.bigTitles changes the
|
4500
|
-
"bigTitles" property of your object will change also. However, if you
|
4501
|
-
change the value of your "bigTitles" property, it will not update the
|
4502
|
-
preferencesController.
|
4503
|
-
|
4504
|
-
One way bindings are almost twice as fast to setup and twice as fast to
|
4505
|
-
execute because the binding only has to worry about changes to one side.
|
4506
|
-
|
4507
|
-
You should consider using one way bindings anytime you have an object that
|
4508
|
-
may be created frequently and you do not intend to change a property; only
|
4509
|
-
to monitor it for changes. (such as in the example above).
|
4510
|
-
|
4511
|
-
## Adding Custom Transforms
|
4512
|
-
|
4513
|
-
In addition to using the standard helpers provided by Ember, you can
|
4514
|
-
also defined your own custom transform functions which will be used to
|
4515
|
-
convert the value. To do this, just define your transform function and add
|
4516
|
-
it to the binding with the transform() helper. The following example will
|
4517
|
-
not allow Integers less than ten. Note that it checks the value of the
|
4518
|
-
bindings and allows all other values to pass:
|
4519
|
-
|
4520
|
-
valueBinding: Ember.Binding.transform(function(value, binding) {
|
4521
|
-
return ((Ember.typeOf(value) === 'number') && (value < 10)) ? 10 : value;
|
4522
|
-
}).from("MyApp.someController.value")
|
4523
|
-
|
4524
|
-
If you would like to instead use this transform on a number of bindings,
|
4525
|
-
you can also optionally add your own helper method to Ember.Binding. This
|
4526
|
-
method should simply return the value of `this.transform()`. The example
|
4527
|
-
below adds a new helper called `notLessThan()` which will limit the value to
|
4528
|
-
be not less than the passed minimum:
|
4529
|
-
|
4530
|
-
Ember.Binding.reopen({
|
4531
|
-
notLessThan: function(minValue) {
|
4532
|
-
return this.transform(function(value, binding) {
|
4533
|
-
return ((Ember.typeOf(value) === 'number') && (value < minValue)) ? minValue : value;
|
4534
|
-
});
|
4535
|
-
}
|
4536
|
-
});
|
4537
|
-
|
4538
|
-
You could specify this in your core.js file, for example. Then anywhere in
|
4539
|
-
your application you can use it to define bindings like so:
|
4540
|
-
|
4541
|
-
valueBinding: Ember.Binding.from("MyApp.someController.value").notLessThan(10)
|
4542
|
-
|
4543
|
-
Also, remember that helpers are chained so you can use your helper along
|
4544
|
-
with any other helpers. The example below will create a one way binding that
|
4545
|
-
does not allow empty values or values less than 10:
|
4546
|
-
|
4547
|
-
valueBinding: Ember.Binding.oneWay("MyApp.someController.value").notEmpty().notLessThan(10)
|
4548
|
-
|
4549
|
-
## How to Manually Adding Binding
|
4550
|
-
|
4551
|
-
All of the examples above show you how to configure a custom binding, but
|
4552
|
-
the result of these customizations will be a binding template, not a fully
|
4553
|
-
active binding. The binding will actually become active only when you
|
4554
|
-
instantiate the object the binding belongs to. It is useful however, to
|
4555
|
-
understand what actually happens when the binding is activated.
|
4556
|
-
|
4557
|
-
For a binding to function it must have at least a "from" property and a "to"
|
4558
|
-
property. The from property path points to the object/key that you want to
|
4559
|
-
bind from while the to path points to the object/key you want to bind to.
|
4560
|
-
|
4561
|
-
When you define a custom binding, you are usually describing the property
|
4562
|
-
you want to bind from (such as "MyApp.someController.value" in the examples
|
4563
|
-
above). When your object is created, it will automatically assign the value
|
4564
|
-
you want to bind "to" based on the name of your binding key. In the
|
4565
|
-
examples above, during init, Ember objects will effectively call
|
4566
|
-
something like this on your binding:
|
4567
|
-
|
4568
|
-
binding = Ember.Binding.from(this.valueBinding).to("value");
|
4569
|
-
|
4570
|
-
This creates a new binding instance based on the template you provide, and
|
4571
|
-
sets the to path to the "value" property of the new object. Now that the
|
4572
|
-
binding is fully configured with a "from" and a "to", it simply needs to be
|
4573
|
-
connected to become active. This is done through the connect() method:
|
4574
|
-
|
4575
|
-
binding.connect(this);
|
4576
|
-
|
4577
|
-
Note that when you connect a binding you pass the object you want it to be
|
4578
|
-
connected to. This object will be used as the root for both the from and
|
4579
|
-
to side of the binding when inspecting relative paths. This allows the
|
4580
|
-
binding to be automatically inherited by subclassed objects as well.
|
4581
|
-
|
4582
|
-
Now that the binding is connected, it will observe both the from and to side
|
4583
|
-
and relay changes.
|
4584
|
-
|
4585
|
-
If you ever needed to do so (you almost never will, but it is useful to
|
4586
|
-
understand this anyway), you could manually create an active binding by
|
4587
|
-
using the Ember.bind() helper method. (This is the same method used by
|
4588
|
-
to setup your bindings on objects):
|
4589
|
-
|
4590
|
-
Ember.bind(MyApp.anotherObject, "value", "MyApp.someController.value");
|
4591
|
-
|
4592
|
-
Both of these code fragments have the same effect as doing the most friendly
|
4593
|
-
form of binding creation like so:
|
4594
|
-
|
4595
|
-
MyApp.anotherObject = Ember.Object.create({
|
4596
|
-
valueBinding: "MyApp.someController.value",
|
4597
|
-
|
4598
|
-
// OTHER CODE FOR THIS OBJECT...
|
4599
|
-
|
4600
|
-
});
|
4601
|
-
|
4602
|
-
Ember's built in binding creation method makes it easy to automatically
|
4603
|
-
create bindings for you. You should always use the highest-level APIs
|
4604
|
-
available, even if you understand how to it works underneath.
|
4605
|
-
|
4606
|
-
@since Ember 0.9
|
4607
|
-
*/
|
4608
4564
|
var K = function() {};
|
4609
4565
|
var Binding = function(toPath, fromPath) {
|
4610
4566
|
var self;
|
@@ -4627,7 +4583,7 @@ var Binding = function(toPath, fromPath) {
|
|
4627
4583
|
|
4628
4584
|
K.prototype = Binding.prototype;
|
4629
4585
|
|
4630
|
-
Binding.prototype = {
|
4586
|
+
Binding.prototype = /** @scope Ember.Binding.prototype */ {
|
4631
4587
|
// ..........................................................
|
4632
4588
|
// CONFIG
|
4633
4589
|
//
|
@@ -4951,7 +4907,7 @@ Binding.prototype = {
|
|
4951
4907
|
|
4952
4908
|
// get the direction of the binding for the object we are
|
4953
4909
|
// synchronizing from
|
4954
|
-
var guid = guidFor(obj), direction = this[guid]
|
4910
|
+
var guid = guidFor(obj), direction = this[guid];
|
4955
4911
|
|
4956
4912
|
var fromPath = this._from, toPath = this._to;
|
4957
4913
|
|
@@ -4965,13 +4921,13 @@ Binding.prototype = {
|
|
4965
4921
|
|
4966
4922
|
// if we're synchronizing from the remote object...
|
4967
4923
|
if (direction === 'fwd') {
|
4968
|
-
if (log) { Ember.Logger.log(' ', this.toString(),
|
4969
|
-
Ember.trySetPath(obj, toPath, fromValue);
|
4924
|
+
if (log) { Ember.Logger.log(' ', this.toString(), toValue, '->', fromValue, obj); }
|
4925
|
+
Ember.trySetPath(Ember.isGlobalPath(toPath) ? window : obj, toPath, fromValue);
|
4970
4926
|
|
4971
4927
|
// if we're synchronizing *to* the remote object
|
4972
4928
|
} else if (direction === 'back') {// && !this._oneWay) {
|
4973
|
-
if (log) { Ember.Logger.log(' ', this.toString(),
|
4974
|
-
Ember.trySetPath(obj, fromPath, toValue);
|
4929
|
+
if (log) { Ember.Logger.log(' ', this.toString(), toValue, '<-', fromValue, obj); }
|
4930
|
+
Ember.trySetPath(Ember.isGlobalPath(fromPath) ? window : obj, fromPath, toValue);
|
4975
4931
|
}
|
4976
4932
|
}
|
4977
4933
|
|
@@ -4985,7 +4941,8 @@ function mixinProperties(to, from) {
|
|
4985
4941
|
}
|
4986
4942
|
}
|
4987
4943
|
|
4988
|
-
mixinProperties(Binding,
|
4944
|
+
mixinProperties(Binding,
|
4945
|
+
/** @scope Ember.Binding */ {
|
4989
4946
|
|
4990
4947
|
/**
|
4991
4948
|
@see Ember.Binding.prototype.from
|
@@ -5103,13 +5060,182 @@ mixinProperties(Binding, {
|
|
5103
5060
|
|
5104
5061
|
});
|
5105
5062
|
|
5106
|
-
Ember.Binding = Binding;
|
5107
|
-
|
5108
5063
|
/**
|
5109
|
-
|
5110
|
-
|
5111
|
-
binding
|
5112
|
-
|
5064
|
+
@class
|
5065
|
+
|
5066
|
+
A binding simply connects the properties of two objects so that whenever the
|
5067
|
+
value of one property changes, the other property will be changed also. You
|
5068
|
+
do not usually work with Binding objects directly but instead describe
|
5069
|
+
bindings in your class definition using something like:
|
5070
|
+
|
5071
|
+
valueBinding: "MyApp.someController.title"
|
5072
|
+
|
5073
|
+
This will create a binding from `MyApp.someController.title` to the `value`
|
5074
|
+
property of your object instance automatically. Now the two values will be
|
5075
|
+
kept in sync.
|
5076
|
+
|
5077
|
+
## Customizing Your Bindings
|
5078
|
+
|
5079
|
+
In addition to synchronizing values, bindings can also perform some basic
|
5080
|
+
transforms on values. These transforms can help to make sure the data fed
|
5081
|
+
into one object always meets the expectations of that object regardless of
|
5082
|
+
what the other object outputs.
|
5083
|
+
|
5084
|
+
To customize a binding, you can use one of the many helper methods defined
|
5085
|
+
on Ember.Binding like so:
|
5086
|
+
|
5087
|
+
valueBinding: Ember.Binding.single("MyApp.someController.title")
|
5088
|
+
|
5089
|
+
This will create a binding just like the example above, except that now the
|
5090
|
+
binding will convert the value of `MyApp.someController.title` to a single
|
5091
|
+
object (removing any arrays) before applying it to the `value` property of
|
5092
|
+
your object.
|
5093
|
+
|
5094
|
+
You can also chain helper methods to build custom bindings like so:
|
5095
|
+
|
5096
|
+
valueBinding: Ember.Binding.single("MyApp.someController.title").notEmpty("(EMPTY)")
|
5097
|
+
|
5098
|
+
This will force the value of MyApp.someController.title to be a single value
|
5099
|
+
and then check to see if the value is "empty" (null, undefined, empty array,
|
5100
|
+
or an empty string). If it is empty, the value will be set to the string
|
5101
|
+
"(EMPTY)".
|
5102
|
+
|
5103
|
+
## One Way Bindings
|
5104
|
+
|
5105
|
+
One especially useful binding customization you can use is the `oneWay()`
|
5106
|
+
helper. This helper tells Ember that you are only interested in
|
5107
|
+
receiving changes on the object you are binding from. For example, if you
|
5108
|
+
are binding to a preference and you want to be notified if the preference
|
5109
|
+
has changed, but your object will not be changing the preference itself, you
|
5110
|
+
could do:
|
5111
|
+
|
5112
|
+
bigTitlesBinding: Ember.Binding.oneWay("MyApp.preferencesController.bigTitles")
|
5113
|
+
|
5114
|
+
This way if the value of MyApp.preferencesController.bigTitles changes the
|
5115
|
+
"bigTitles" property of your object will change also. However, if you
|
5116
|
+
change the value of your "bigTitles" property, it will not update the
|
5117
|
+
preferencesController.
|
5118
|
+
|
5119
|
+
One way bindings are almost twice as fast to setup and twice as fast to
|
5120
|
+
execute because the binding only has to worry about changes to one side.
|
5121
|
+
|
5122
|
+
You should consider using one way bindings anytime you have an object that
|
5123
|
+
may be created frequently and you do not intend to change a property; only
|
5124
|
+
to monitor it for changes. (such as in the example above).
|
5125
|
+
|
5126
|
+
## Adding Custom Transforms
|
5127
|
+
|
5128
|
+
In addition to using the standard helpers provided by Ember, you can
|
5129
|
+
also defined your own custom transform functions which will be used to
|
5130
|
+
convert the value. To do this, just define your transform function and add
|
5131
|
+
it to the binding with the transform() helper. The following example will
|
5132
|
+
not allow Integers less than ten. Note that it checks the value of the
|
5133
|
+
bindings and allows all other values to pass:
|
5134
|
+
|
5135
|
+
valueBinding: Ember.Binding.transform(function(value, binding) {
|
5136
|
+
return ((Ember.typeOf(value) === 'number') && (value < 10)) ? 10 : value;
|
5137
|
+
}).from("MyApp.someController.value")
|
5138
|
+
|
5139
|
+
If you would like to instead use this transform on a number of bindings,
|
5140
|
+
you can also optionally add your own helper method to Ember.Binding. This
|
5141
|
+
method should simply return the value of `this.transform()`. The example
|
5142
|
+
below adds a new helper called `notLessThan()` which will limit the value to
|
5143
|
+
be not less than the passed minimum:
|
5144
|
+
|
5145
|
+
Ember.Binding.reopen({
|
5146
|
+
notLessThan: function(minValue) {
|
5147
|
+
return this.transform(function(value, binding) {
|
5148
|
+
return ((Ember.typeOf(value) === 'number') && (value < minValue)) ? minValue : value;
|
5149
|
+
});
|
5150
|
+
}
|
5151
|
+
});
|
5152
|
+
|
5153
|
+
You could specify this in your core.js file, for example. Then anywhere in
|
5154
|
+
your application you can use it to define bindings like so:
|
5155
|
+
|
5156
|
+
valueBinding: Ember.Binding.from("MyApp.someController.value").notLessThan(10)
|
5157
|
+
|
5158
|
+
Also, remember that helpers are chained so you can use your helper along
|
5159
|
+
with any other helpers. The example below will create a one way binding that
|
5160
|
+
does not allow empty values or values less than 10:
|
5161
|
+
|
5162
|
+
valueBinding: Ember.Binding.oneWay("MyApp.someController.value").notEmpty().notLessThan(10)
|
5163
|
+
|
5164
|
+
Finally, it's also possible to specify bi-directional transforms. To do this,
|
5165
|
+
you can pass a hash to `transform` with `to` and `from`. In the following
|
5166
|
+
example, we are expecting a lowercase string that we want to transform to
|
5167
|
+
uppercase.
|
5168
|
+
|
5169
|
+
valueBinding: Ember.Binding.transform({
|
5170
|
+
to: function(value, binding) { return value.toUpperCase(); },
|
5171
|
+
from: function(value, binding) { return value.toLowerCase(); }
|
5172
|
+
|
5173
|
+
## How to Manually Adding Binding
|
5174
|
+
|
5175
|
+
All of the examples above show you how to configure a custom binding, but
|
5176
|
+
the result of these customizations will be a binding template, not a fully
|
5177
|
+
active binding. The binding will actually become active only when you
|
5178
|
+
instantiate the object the binding belongs to. It is useful however, to
|
5179
|
+
understand what actually happens when the binding is activated.
|
5180
|
+
|
5181
|
+
For a binding to function it must have at least a "from" property and a "to"
|
5182
|
+
property. The from property path points to the object/key that you want to
|
5183
|
+
bind from while the to path points to the object/key you want to bind to.
|
5184
|
+
|
5185
|
+
When you define a custom binding, you are usually describing the property
|
5186
|
+
you want to bind from (such as "MyApp.someController.value" in the examples
|
5187
|
+
above). When your object is created, it will automatically assign the value
|
5188
|
+
you want to bind "to" based on the name of your binding key. In the
|
5189
|
+
examples above, during init, Ember objects will effectively call
|
5190
|
+
something like this on your binding:
|
5191
|
+
|
5192
|
+
binding = Ember.Binding.from(this.valueBinding).to("value");
|
5193
|
+
|
5194
|
+
This creates a new binding instance based on the template you provide, and
|
5195
|
+
sets the to path to the "value" property of the new object. Now that the
|
5196
|
+
binding is fully configured with a "from" and a "to", it simply needs to be
|
5197
|
+
connected to become active. This is done through the connect() method:
|
5198
|
+
|
5199
|
+
binding.connect(this);
|
5200
|
+
|
5201
|
+
Note that when you connect a binding you pass the object you want it to be
|
5202
|
+
connected to. This object will be used as the root for both the from and
|
5203
|
+
to side of the binding when inspecting relative paths. This allows the
|
5204
|
+
binding to be automatically inherited by subclassed objects as well.
|
5205
|
+
|
5206
|
+
Now that the binding is connected, it will observe both the from and to side
|
5207
|
+
and relay changes.
|
5208
|
+
|
5209
|
+
If you ever needed to do so (you almost never will, but it is useful to
|
5210
|
+
understand this anyway), you could manually create an active binding by
|
5211
|
+
using the Ember.bind() helper method. (This is the same method used by
|
5212
|
+
to setup your bindings on objects):
|
5213
|
+
|
5214
|
+
Ember.bind(MyApp.anotherObject, "value", "MyApp.someController.value");
|
5215
|
+
|
5216
|
+
Both of these code fragments have the same effect as doing the most friendly
|
5217
|
+
form of binding creation like so:
|
5218
|
+
|
5219
|
+
MyApp.anotherObject = Ember.Object.create({
|
5220
|
+
valueBinding: "MyApp.someController.value",
|
5221
|
+
|
5222
|
+
// OTHER CODE FOR THIS OBJECT...
|
5223
|
+
|
5224
|
+
});
|
5225
|
+
|
5226
|
+
Ember's built in binding creation method makes it easy to automatically
|
5227
|
+
create bindings for you. You should always use the highest-level APIs
|
5228
|
+
available, even if you understand how to it works underneath.
|
5229
|
+
|
5230
|
+
@since Ember 0.9
|
5231
|
+
*/
|
5232
|
+
Ember.Binding = Binding;
|
5233
|
+
|
5234
|
+
/**
|
5235
|
+
Global helper method to create a new binding. Just pass the root object
|
5236
|
+
along with a to and from path to create and connect the binding. The new
|
5237
|
+
binding object will be returned which you can further configure with
|
5238
|
+
transforms and other conditions.
|
5113
5239
|
|
5114
5240
|
@param {Object} obj
|
5115
5241
|
The root object of the transform.
|
@@ -5210,6 +5336,9 @@ function ComputedProperty(func, opts) {
|
|
5210
5336
|
this._dependentKeys = opts && opts.dependentKeys;
|
5211
5337
|
}
|
5212
5338
|
|
5339
|
+
/**
|
5340
|
+
@constructor
|
5341
|
+
*/
|
5213
5342
|
Ember.ComputedProperty = ComputedProperty;
|
5214
5343
|
ComputedProperty.prototype = new Ember.Descriptor();
|
5215
5344
|
|
@@ -5265,6 +5394,10 @@ function mkCpSetter(keyName, desc) {
|
|
5265
5394
|
};
|
5266
5395
|
}
|
5267
5396
|
|
5397
|
+
/**
|
5398
|
+
@extends Ember.ComputedProperty
|
5399
|
+
@private
|
5400
|
+
*/
|
5268
5401
|
var Cp = ComputedProperty.prototype;
|
5269
5402
|
|
5270
5403
|
/**
|
@@ -5434,6 +5567,7 @@ var array_Slice = Array.prototype.slice;
|
|
5434
5567
|
|
5435
5568
|
*/
|
5436
5569
|
|
5570
|
+
/** @private */
|
5437
5571
|
var metaPath = Ember.metaPath;
|
5438
5572
|
|
5439
5573
|
// Gets the set of all actions, keyed on the guid of each action's
|
@@ -5505,6 +5639,8 @@ function invokeEvents(targetSet, params) {
|
|
5505
5639
|
parameters passed to an observer. if you pass an xform function, it will
|
5506
5640
|
be invoked and is able to translate event listener parameters into the form
|
5507
5641
|
that observers are expecting.
|
5642
|
+
|
5643
|
+
@name Ember.addListener
|
5508
5644
|
*/
|
5509
5645
|
function addListener(obj, eventName, target, method, xform) {
|
5510
5646
|
ember_assert("You must pass at least an object and event name to Ember.addListener", !!obj && !!eventName);
|
@@ -5563,7 +5699,6 @@ function watchedEvents(obj) {
|
|
5563
5699
|
}
|
5564
5700
|
|
5565
5701
|
function sendEvent(obj, eventName) {
|
5566
|
-
ember_assert("You must pass an object and event name to Ember.sendEvent", !!obj && !!eventName);
|
5567
5702
|
|
5568
5703
|
// first give object a chance to handle it
|
5569
5704
|
if (obj !== Ember && 'function' === typeof obj.sendEvent) {
|
@@ -5639,6 +5774,7 @@ var Mixin, MixinDelegate, REQUIRED, Alias;
|
|
5639
5774
|
var classToString, superClassString;
|
5640
5775
|
|
5641
5776
|
var a_map = Array.prototype.map;
|
5777
|
+
var a_slice = Array.prototype.slice;
|
5642
5778
|
var EMPTY_META = {}; // dummy for non-writable meta
|
5643
5779
|
var META_SKIP = { __emberproto__: true, __ember_count__: true };
|
5644
5780
|
|
@@ -5886,17 +6022,21 @@ function applyMixin(obj, mixins, partial) {
|
|
5886
6022
|
}
|
5887
6023
|
|
5888
6024
|
Ember.mixin = function(obj) {
|
5889
|
-
var args =
|
6025
|
+
var args = a_slice.call(arguments, 1);
|
5890
6026
|
return applyMixin(obj, args, false);
|
5891
6027
|
};
|
5892
6028
|
|
5893
6029
|
|
6030
|
+
/**
|
6031
|
+
@constructor
|
6032
|
+
@name Ember.Mixin
|
6033
|
+
*/
|
5894
6034
|
Mixin = function() { return initMixin(this, arguments); };
|
5895
6035
|
|
5896
6036
|
Mixin._apply = applyMixin;
|
5897
6037
|
|
5898
6038
|
Mixin.applyPartial = function(obj) {
|
5899
|
-
var args =
|
6039
|
+
var args = a_slice.call(arguments, 1);
|
5900
6040
|
return applyMixin(obj, args, true);
|
5901
6041
|
};
|
5902
6042
|
|
@@ -5935,15 +6075,17 @@ Mixin.prototype.reopen = function() {
|
|
5935
6075
|
|
5936
6076
|
var TMP_ARRAY = [];
|
5937
6077
|
Mixin.prototype.apply = function(obj) {
|
5938
|
-
TMP_ARRAY.length=0;
|
5939
6078
|
TMP_ARRAY[0] = this;
|
5940
|
-
|
6079
|
+
var ret = applyMixin(obj, TMP_ARRAY, false);
|
6080
|
+
TMP_ARRAY.length=0;
|
6081
|
+
return ret;
|
5941
6082
|
};
|
5942
6083
|
|
5943
6084
|
Mixin.prototype.applyPartial = function(obj) {
|
5944
|
-
TMP_ARRAY.length=0;
|
5945
6085
|
TMP_ARRAY[0] = this;
|
5946
|
-
|
6086
|
+
var ret = applyMixin(obj, TMP_ARRAY, true);
|
6087
|
+
TMP_ARRAY.length=0;
|
6088
|
+
return ret;
|
5947
6089
|
};
|
5948
6090
|
|
5949
6091
|
function _detect(curMixin, targetMixin, seen) {
|
@@ -5968,7 +6110,7 @@ Mixin.prototype.detect = function(obj) {
|
|
5968
6110
|
|
5969
6111
|
Mixin.prototype.without = function() {
|
5970
6112
|
var ret = new Mixin(this);
|
5971
|
-
ret._without =
|
6113
|
+
ret._without = a_slice.call(arguments);
|
5972
6114
|
return ret;
|
5973
6115
|
};
|
5974
6116
|
|
@@ -6025,6 +6167,9 @@ function findNamespaces() {
|
|
6025
6167
|
if (Namespace.PROCESSED) { return; }
|
6026
6168
|
|
6027
6169
|
for (var prop in window) {
|
6170
|
+
// get(window.globalStorage, 'isNamespace') would try to read the storage for domain isNamespace and cause exception in Firefox.
|
6171
|
+
// globalStorage is a storage obsoleted by the WhatWG storage specification. See https://developer.mozilla.org/en/DOM/Storage#globalStorage
|
6172
|
+
if (prop === "globalStorage" && window.StorageList && window.globalStorage instanceof window.StorageList) { continue; }
|
6028
6173
|
// Unfortunately, some versions of IE don't support window.hasOwnProperty
|
6029
6174
|
if (window.hasOwnProperty && !window.hasOwnProperty(prop)) { continue; }
|
6030
6175
|
|
@@ -6130,13 +6275,13 @@ Ember.MixinDelegate = MixinDelegate;
|
|
6130
6275
|
//
|
6131
6276
|
|
6132
6277
|
Ember.observer = function(func) {
|
6133
|
-
var paths =
|
6278
|
+
var paths = a_slice.call(arguments, 1);
|
6134
6279
|
func.__ember_observes__ = paths;
|
6135
6280
|
return func;
|
6136
6281
|
};
|
6137
6282
|
|
6138
6283
|
Ember.beforeObserver = function(func) {
|
6139
|
-
var paths =
|
6284
|
+
var paths = a_slice.call(arguments, 1);
|
6140
6285
|
func.__ember_observesBefore__ = paths;
|
6141
6286
|
return func;
|
6142
6287
|
};
|
@@ -6174,6 +6319,7 @@ Ember.beforeObserver = function(func) {
|
|
6174
6319
|
//
|
6175
6320
|
|
6176
6321
|
var get = Ember.get, set = Ember.set;
|
6322
|
+
var a_slice = Array.prototype.slice;
|
6177
6323
|
|
6178
6324
|
var contexts = [];
|
6179
6325
|
function popCtx() {
|
@@ -6186,9 +6332,11 @@ function pushCtx(ctx) {
|
|
6186
6332
|
}
|
6187
6333
|
|
6188
6334
|
function iter(key, value) {
|
6335
|
+
var valueProvided = arguments.length === 2;
|
6336
|
+
|
6189
6337
|
function i(item) {
|
6190
6338
|
var cur = get(item, key);
|
6191
|
-
return
|
6339
|
+
return valueProvided ? value===cur : !!cur;
|
6192
6340
|
}
|
6193
6341
|
return i ;
|
6194
6342
|
}
|
@@ -6283,6 +6431,13 @@ Ember.Enumerable = Ember.Mixin.create( /** @lends Ember.Enumerable */ {
|
|
6283
6431
|
If your enumerable is empty, this method should return undefined.
|
6284
6432
|
|
6285
6433
|
@returns {Object} the object or undefined
|
6434
|
+
|
6435
|
+
@example
|
6436
|
+
var arr = ["a", "b", "c"];
|
6437
|
+
arr.firstObject(); => "a"
|
6438
|
+
|
6439
|
+
var arr = [];
|
6440
|
+
arr.firstObject(); => undefined
|
6286
6441
|
*/
|
6287
6442
|
firstObject: Ember.computed(function() {
|
6288
6443
|
if (get(this, 'length')===0) return undefined ;
|
@@ -6293,12 +6448,21 @@ Ember.Enumerable = Ember.Mixin.create( /** @lends Ember.Enumerable */ {
|
|
6293
6448
|
ret = this.nextObject(0, null, context);
|
6294
6449
|
pushCtx(context);
|
6295
6450
|
return ret ;
|
6296
|
-
}).property(
|
6451
|
+
}).property(),
|
6297
6452
|
|
6298
6453
|
/**
|
6299
|
-
Helper method returns the last object from a collection.
|
6454
|
+
Helper method returns the last object from a collection. If your enumerable
|
6455
|
+
contains only one object, this method should always return that object.
|
6456
|
+
If your enumerable is empty, this method should return undefined.
|
6300
6457
|
|
6301
|
-
@returns {Object} the object or undefined
|
6458
|
+
@returns {Object} the last object or undefined
|
6459
|
+
|
6460
|
+
@example
|
6461
|
+
var arr = ["a", "b", "c"];
|
6462
|
+
arr.lastObject(); => "c"
|
6463
|
+
|
6464
|
+
var arr = [];
|
6465
|
+
arr.lastObject(); => undefined
|
6302
6466
|
*/
|
6303
6467
|
lastObject: Ember.computed(function() {
|
6304
6468
|
var len = get(this, 'length');
|
@@ -6314,8 +6478,7 @@ Ember.Enumerable = Ember.Mixin.create( /** @lends Ember.Enumerable */ {
|
|
6314
6478
|
pushCtx(context);
|
6315
6479
|
return last;
|
6316
6480
|
}
|
6317
|
-
|
6318
|
-
}).property('[]').cacheable(),
|
6481
|
+
}).property(),
|
6319
6482
|
|
6320
6483
|
/**
|
6321
6484
|
Returns true if the passed object can be found in the receiver. The
|
@@ -6370,18 +6533,13 @@ Ember.Enumerable = Ember.Mixin.create( /** @lends Ember.Enumerable */ {
|
|
6370
6533
|
},
|
6371
6534
|
|
6372
6535
|
/**
|
6373
|
-
|
6374
|
-
than using one of the wrapper methods defined here. Objects that
|
6375
|
-
implement Ember.Observable will use the get() method, otherwise the property
|
6376
|
-
will be accessed directly.
|
6536
|
+
Alias for mapProperty
|
6377
6537
|
|
6378
|
-
@
|
6379
|
-
@returns {Array}
|
6538
|
+
@params key {String} name of the property
|
6539
|
+
@returns {Array} The mapped array.
|
6380
6540
|
*/
|
6381
6541
|
getEach: function(key) {
|
6382
|
-
return this.
|
6383
|
-
return get(item, key);
|
6384
|
-
});
|
6542
|
+
return this.mapProperty(key);
|
6385
6543
|
},
|
6386
6544
|
|
6387
6545
|
/**
|
@@ -6486,7 +6644,7 @@ Ember.Enumerable = Ember.Mixin.create( /** @lends Ember.Enumerable */ {
|
|
6486
6644
|
@returns {Array} filtered array
|
6487
6645
|
*/
|
6488
6646
|
filterProperty: function(key, value) {
|
6489
|
-
return this.filter(iter(
|
6647
|
+
return this.filter(iter.apply(this, arguments));
|
6490
6648
|
},
|
6491
6649
|
|
6492
6650
|
/**
|
@@ -6541,7 +6699,7 @@ Ember.Enumerable = Ember.Mixin.create( /** @lends Ember.Enumerable */ {
|
|
6541
6699
|
@returns {Object} found item or null
|
6542
6700
|
*/
|
6543
6701
|
findProperty: function(key, value) {
|
6544
|
-
return this.find(iter(
|
6702
|
+
return this.find(iter.apply(this, arguments));
|
6545
6703
|
},
|
6546
6704
|
|
6547
6705
|
/**
|
@@ -6586,7 +6744,7 @@ Ember.Enumerable = Ember.Mixin.create( /** @lends Ember.Enumerable */ {
|
|
6586
6744
|
@returns {Array} filtered array
|
6587
6745
|
*/
|
6588
6746
|
everyProperty: function(key, value) {
|
6589
|
-
return this.every(iter(
|
6747
|
+
return this.every(iter.apply(this, arguments));
|
6590
6748
|
},
|
6591
6749
|
|
6592
6750
|
|
@@ -6632,7 +6790,7 @@ Ember.Enumerable = Ember.Mixin.create( /** @lends Ember.Enumerable */ {
|
|
6632
6790
|
@returns {Boolean} true
|
6633
6791
|
*/
|
6634
6792
|
someProperty: function(key, value) {
|
6635
|
-
return this.some(iter(
|
6793
|
+
return this.some(iter.apply(this, arguments));
|
6636
6794
|
},
|
6637
6795
|
|
6638
6796
|
/**
|
@@ -6688,7 +6846,7 @@ Ember.Enumerable = Ember.Mixin.create( /** @lends Ember.Enumerable */ {
|
|
6688
6846
|
*/
|
6689
6847
|
invoke: function(methodName) {
|
6690
6848
|
var args, ret = [];
|
6691
|
-
if (arguments.length>1) args =
|
6849
|
+
if (arguments.length>1) args = a_slice.call(arguments, 1);
|
6692
6850
|
|
6693
6851
|
this.forEach(function(x, idx) {
|
6694
6852
|
var method = x && x[methodName];
|
@@ -6702,7 +6860,7 @@ Ember.Enumerable = Ember.Mixin.create( /** @lends Ember.Enumerable */ {
|
|
6702
6860
|
|
6703
6861
|
/**
|
6704
6862
|
Simply converts the enumerable into a genuine array. The order is not
|
6705
|
-
|
6863
|
+
guaranteed. Corresponds to the method implemented by Prototype.
|
6706
6864
|
|
6707
6865
|
@returns {Array} the enumerable as an array.
|
6708
6866
|
*/
|
@@ -6843,7 +7001,6 @@ Ember.Enumerable = Ember.Mixin.create( /** @lends Ember.Enumerable */ {
|
|
6843
7001
|
if (removing === -1) removing = null;
|
6844
7002
|
if (adding === -1) adding = null;
|
6845
7003
|
|
6846
|
-
Ember.propertyWillChange(this, '[]');
|
6847
7004
|
if (hasDelta) Ember.propertyWillChange(this, 'length');
|
6848
7005
|
Ember.sendEvent(this, '@enumerable:before', removing, adding);
|
6849
7006
|
|
@@ -6891,7 +7048,6 @@ Ember.Enumerable = Ember.Mixin.create( /** @lends Ember.Enumerable */ {
|
|
6891
7048
|
|
6892
7049
|
Ember.sendEvent(this, '@enumerable:change', removing, adding);
|
6893
7050
|
if (hasDelta) Ember.propertyDidChange(this, 'length');
|
6894
|
-
Ember.propertyDidChange(this, '[]');
|
6895
7051
|
|
6896
7052
|
return this ;
|
6897
7053
|
}
|
@@ -7031,11 +7187,23 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
|
7031
7187
|
},
|
7032
7188
|
|
7033
7189
|
/**
|
7034
|
-
Returns the index
|
7190
|
+
Returns the index of the given object's first occurrence.
|
7191
|
+
If no startAt argument is given, the starting location to
|
7192
|
+
search is 0. If it's negative, will count backward from
|
7193
|
+
the end of the array. Returns -1 if no match is found.
|
7035
7194
|
|
7036
7195
|
@param {Object} object the item to search for
|
7037
|
-
@param {
|
7038
|
-
@returns {Number} index
|
7196
|
+
@param {Number} startAt optional starting location to search, default 0
|
7197
|
+
@returns {Number} index or -1 if not found
|
7198
|
+
|
7199
|
+
@example
|
7200
|
+
var arr = ["a", "b", "c", "d", "a"];
|
7201
|
+
arr.indexOf("a"); => 0
|
7202
|
+
arr.indexOf("z"); => -1
|
7203
|
+
arr.indexOf("a", 2); => 4
|
7204
|
+
arr.indexOf("a", -1); => 4
|
7205
|
+
arr.indexOf("b", 3); => -1
|
7206
|
+
arr.indexOf("a", 100); => -1
|
7039
7207
|
*/
|
7040
7208
|
indexOf: function(object, startAt) {
|
7041
7209
|
var idx, len = get(this, 'length');
|
@@ -7050,16 +7218,28 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
|
|
7050
7218
|
},
|
7051
7219
|
|
7052
7220
|
/**
|
7053
|
-
Returns the
|
7221
|
+
Returns the index of the given object's last occurrence.
|
7222
|
+
If no startAt argument is given, the search starts from
|
7223
|
+
the last position. If it's negative, will count backward
|
7224
|
+
from the end of the array. Returns -1 if no match is found.
|
7054
7225
|
|
7055
7226
|
@param {Object} object the item to search for
|
7056
|
-
@param {
|
7057
|
-
@returns {Number} index
|
7227
|
+
@param {Number} startAt optional starting location to search, default 0
|
7228
|
+
@returns {Number} index or -1 if not found
|
7229
|
+
|
7230
|
+
@example
|
7231
|
+
var arr = ["a", "b", "c", "d", "a"];
|
7232
|
+
arr.lastIndexOf("a"); => 4
|
7233
|
+
arr.lastIndexOf("z"); => -1
|
7234
|
+
arr.lastIndexOf("a", 2); => 0
|
7235
|
+
arr.lastIndexOf("a", -1); => 4
|
7236
|
+
arr.lastIndexOf("b", 3); => 1
|
7237
|
+
arr.lastIndexOf("a", 100); => 4
|
7058
7238
|
*/
|
7059
7239
|
lastIndexOf: function(object, startAt) {
|
7060
7240
|
var idx, len = get(this, 'length');
|
7061
7241
|
|
7062
|
-
if (startAt === undefined) startAt = len-1;
|
7242
|
+
if (startAt === undefined || startAt >= len) startAt = len-1;
|
7063
7243
|
if (startAt < 0) startAt += len;
|
7064
7244
|
|
7065
7245
|
for(idx=startAt;idx>=0;idx--) {
|
@@ -7704,11 +7884,12 @@ Ember.Observable = Ember.Mixin.create(/** @scope Ember.Observable.prototype */ {
|
|
7704
7884
|
@returns {Ember.Observable}
|
7705
7885
|
*/
|
7706
7886
|
setProperties: function(hash) {
|
7707
|
-
|
7708
|
-
|
7709
|
-
|
7710
|
-
|
7711
|
-
|
7887
|
+
var self = this;
|
7888
|
+
Ember.changeProperties(function(){
|
7889
|
+
for(var prop in hash) {
|
7890
|
+
if (hash.hasOwnProperty(prop)) set(self, prop, hash[prop]);
|
7891
|
+
}
|
7892
|
+
});
|
7712
7893
|
return this;
|
7713
7894
|
},
|
7714
7895
|
|
@@ -7981,7 +8162,8 @@ function makeCtor() {
|
|
7981
8162
|
|
7982
8163
|
var CoreObject = makeCtor();
|
7983
8164
|
|
7984
|
-
CoreObject.PrototypeMixin = Ember.Mixin.create(
|
8165
|
+
CoreObject.PrototypeMixin = Ember.Mixin.create(
|
8166
|
+
/** @scope Ember.CoreObject */ {
|
7985
8167
|
|
7986
8168
|
reopen: function() {
|
7987
8169
|
Ember.Mixin._apply(this, arguments, true);
|
@@ -8019,7 +8201,7 @@ CoreObject.PrototypeMixin = Ember.Mixin.create({
|
|
8019
8201
|
@private
|
8020
8202
|
*/
|
8021
8203
|
_scheduledDestroy: function() {
|
8022
|
-
|
8204
|
+
Ember.destroy(this);
|
8023
8205
|
},
|
8024
8206
|
|
8025
8207
|
bind: function(to, from) {
|
@@ -8111,6 +8293,9 @@ var ClassMixin = Ember.Mixin.create({
|
|
8111
8293
|
CoreObject.ClassMixin = ClassMixin;
|
8112
8294
|
ClassMixin.apply(CoreObject);
|
8113
8295
|
|
8296
|
+
/**
|
8297
|
+
@class
|
8298
|
+
*/
|
8114
8299
|
Ember.CoreObject = CoreObject;
|
8115
8300
|
|
8116
8301
|
|
@@ -8239,14 +8424,13 @@ Ember.none = function(obj) {
|
|
8239
8424
|
};
|
8240
8425
|
|
8241
8426
|
/**
|
8242
|
-
Verifies that a value is
|
8243
|
-
the object is not a string.
|
8427
|
+
Verifies that a value is null or an empty string | array | function.
|
8244
8428
|
|
8245
8429
|
@param {Object} obj Value to test
|
8246
8430
|
@returns {Boolean}
|
8247
8431
|
*/
|
8248
8432
|
Ember.empty = function(obj) {
|
8249
|
-
return obj === null || obj === undefined || obj === '';
|
8433
|
+
return obj === null || obj === undefined || (obj.length === 0 && typeof obj !== 'function');
|
8250
8434
|
};
|
8251
8435
|
|
8252
8436
|
/**
|
@@ -8518,12 +8702,15 @@ Ember.Error.prototype = Ember.create(Error.prototype);
|
|
8518
8702
|
var STRING_DASHERIZE_REGEXP = (/[ _]/g);
|
8519
8703
|
var STRING_DASHERIZE_CACHE = {};
|
8520
8704
|
var STRING_DECAMELIZE_REGEXP = (/([a-z])([A-Z])/g);
|
8521
|
-
|
8705
|
+
var STRING_CAMELIZE_REGEXP = (/(\-|_|\s)+(.)?/g);
|
8706
|
+
var STRING_UNDERSCORE_REGEXP_1 = (/([a-z\d])([A-Z]+)/g);
|
8707
|
+
var STRING_UNDERSCORE_REGEXP_2 = (/\-|\s+/g);
|
8708
|
+
|
8522
8709
|
/**
|
8523
|
-
Defines the hash of localized strings for the current language. Used by
|
8710
|
+
Defines the hash of localized strings for the current language. Used by
|
8524
8711
|
the `Ember.String.loc()` helper. To localize, add string values to this
|
8525
8712
|
hash.
|
8526
|
-
|
8713
|
+
|
8527
8714
|
@property {String}
|
8528
8715
|
*/
|
8529
8716
|
Ember.STRINGS = {};
|
@@ -8532,7 +8719,7 @@ Ember.STRINGS = {};
|
|
8532
8719
|
Defines string helper methods including string formatting and localization.
|
8533
8720
|
Unless Ember.EXTEND_PROTOTYPES = false these methods will also be added to the
|
8534
8721
|
String.prototype as well.
|
8535
|
-
|
8722
|
+
|
8536
8723
|
@namespace
|
8537
8724
|
*/
|
8538
8725
|
Ember.String = {
|
@@ -8567,35 +8754,35 @@ Ember.String = {
|
|
8567
8754
|
|
8568
8755
|
/**
|
8569
8756
|
Formats the passed string, but first looks up the string in the localized
|
8570
|
-
strings hash. This is a convenient way to localize text. See
|
8757
|
+
strings hash. This is a convenient way to localize text. See
|
8571
8758
|
`Ember.String.fmt()` for more information on formatting.
|
8572
|
-
|
8759
|
+
|
8573
8760
|
Note that it is traditional but not required to prefix localized string
|
8574
8761
|
keys with an underscore or other character so you can easily identify
|
8575
8762
|
localized strings.
|
8576
|
-
|
8763
|
+
|
8577
8764
|
# Example Usage
|
8578
|
-
|
8765
|
+
|
8579
8766
|
@javascript@
|
8580
8767
|
Ember.STRINGS = {
|
8581
8768
|
'_Hello World': 'Bonjour le monde',
|
8582
8769
|
'_Hello %@ %@': 'Bonjour %@ %@'
|
8583
8770
|
};
|
8584
|
-
|
8771
|
+
|
8585
8772
|
Ember.String.loc("_Hello World");
|
8586
8773
|
=> 'Bonjour le monde';
|
8587
|
-
|
8774
|
+
|
8588
8775
|
Ember.String.loc("_Hello %@ %@", ["John", "Smith"]);
|
8589
8776
|
=> "Bonjour John Smith";
|
8590
|
-
|
8591
|
-
|
8592
|
-
|
8777
|
+
|
8778
|
+
|
8779
|
+
|
8593
8780
|
@param {String} str
|
8594
8781
|
The string to format
|
8595
|
-
|
8782
|
+
|
8596
8783
|
@param {Array} formats
|
8597
8784
|
Optional array of parameters to interpolate into string.
|
8598
|
-
|
8785
|
+
|
8599
8786
|
@returns {String} formatted string
|
8600
8787
|
*/
|
8601
8788
|
loc: function(str, formats) {
|
@@ -8607,12 +8794,12 @@ Ember.String = {
|
|
8607
8794
|
Splits a string into separate units separated by spaces, eliminating any
|
8608
8795
|
empty strings in the process. This is a convenience method for split that
|
8609
8796
|
is mostly useful when applied to the String.prototype.
|
8610
|
-
|
8797
|
+
|
8611
8798
|
# Example Usage
|
8612
|
-
|
8799
|
+
|
8613
8800
|
@javascript@
|
8614
|
-
Ember.String.w("alpha beta gamma").forEach(function(key) {
|
8615
|
-
console.log(key);
|
8801
|
+
Ember.String.w("alpha beta gamma").forEach(function(key) {
|
8802
|
+
console.log(key);
|
8616
8803
|
});
|
8617
8804
|
> alpha
|
8618
8805
|
> beta
|
@@ -8620,11 +8807,11 @@ Ember.String = {
|
|
8620
8807
|
|
8621
8808
|
@param {String} str
|
8622
8809
|
The string to split
|
8623
|
-
|
8810
|
+
|
8624
8811
|
@returns {String} split string
|
8625
8812
|
*/
|
8626
8813
|
w: function(str) { return str.split(/\s+/); },
|
8627
|
-
|
8814
|
+
|
8628
8815
|
/**
|
8629
8816
|
Converts a camelized string into all lower case separated by underscores.
|
8630
8817
|
|
@@ -8668,13 +8855,52 @@ Ember.String = {
|
|
8668
8855
|
}
|
8669
8856
|
|
8670
8857
|
return ret;
|
8671
|
-
}
|
8672
|
-
};
|
8673
|
-
|
8674
|
-
|
8858
|
+
},
|
8675
8859
|
|
8860
|
+
/**
|
8861
|
+
Converts a dasherized string or a string with spaces or underscores into
|
8862
|
+
camelized string.
|
8676
8863
|
|
8677
|
-
|
8864
|
+
h2. Examples
|
8865
|
+
|
8866
|
+
| *Input String* | *Output String* |
|
8867
|
+
| my favorite items | myFavoriteItems |
|
8868
|
+
| css-class-name | cssClassName |
|
8869
|
+
| action_name | actionName |
|
8870
|
+
| innerHTML | innerHTML |
|
8871
|
+
|
8872
|
+
@returns {String} the camelized string.
|
8873
|
+
*/
|
8874
|
+
camelize: function(str) {
|
8875
|
+
return str.replace(STRING_CAMELIZE_REGEXP, function(match, separator, chr) {
|
8876
|
+
return chr ? chr.toUpperCase() : '';
|
8877
|
+
});
|
8878
|
+
},
|
8879
|
+
|
8880
|
+
/**
|
8881
|
+
More general than decamelize, converts a dasherized or camelcased string or a string with spaces into
|
8882
|
+
all lower case separated by undescores.
|
8883
|
+
|
8884
|
+
h2. Examples
|
8885
|
+
|
8886
|
+
| *Input String* | *Output String* |
|
8887
|
+
| my favorite items | my_favorite_items |
|
8888
|
+
| css-class-name | css_class_name |
|
8889
|
+
| action_name | action_name |
|
8890
|
+
| innerHTML | inner_html |
|
8891
|
+
|
8892
|
+
@returns {String} the camelized string.
|
8893
|
+
*/
|
8894
|
+
underscore: function(str) {
|
8895
|
+
return str.replace(STRING_UNDERSCORE_REGEXP_1, '$1_$2').
|
8896
|
+
replace(STRING_UNDERSCORE_REGEXP_2, '_').toLowerCase();
|
8897
|
+
}
|
8898
|
+
};
|
8899
|
+
|
8900
|
+
|
8901
|
+
|
8902
|
+
|
8903
|
+
})({});
|
8678
8904
|
|
8679
8905
|
|
8680
8906
|
(function(exports) {
|
@@ -8700,7 +8926,8 @@ var get = Ember.get, set = Ember.set;
|
|
8700
8926
|
|
8701
8927
|
@since Ember 0.9
|
8702
8928
|
*/
|
8703
|
-
Ember.Copyable = Ember.Mixin.create(
|
8929
|
+
Ember.Copyable = Ember.Mixin.create(
|
8930
|
+
/** @scope Ember.Copyable.prototype */ {
|
8704
8931
|
|
8705
8932
|
/**
|
8706
8933
|
Override to return a copy of the receiver. Default implementation raises
|
@@ -8809,7 +9036,8 @@ var get = Ember.get, set = Ember.set;
|
|
8809
9036
|
|
8810
9037
|
@since Ember 0.9
|
8811
9038
|
*/
|
8812
|
-
Ember.Freezable = Ember.Mixin.create(
|
9039
|
+
Ember.Freezable = Ember.Mixin.create(
|
9040
|
+
/** @scope Ember.Freezable.prototype */ {
|
8813
9041
|
|
8814
9042
|
/**
|
8815
9043
|
Set to YES when the object is frozen. Use this property to detect whether
|
@@ -9219,6 +9447,12 @@ Ember.Set.create = function(items) {
|
|
9219
9447
|
// License: Licensed under MIT license (see license.js)
|
9220
9448
|
// ==========================================================================
|
9221
9449
|
Ember.CoreObject.subclasses = new Ember.Set();
|
9450
|
+
|
9451
|
+
/**
|
9452
|
+
@class
|
9453
|
+
@extends Ember.CoreObject
|
9454
|
+
@extends Ember.Observable
|
9455
|
+
*/
|
9222
9456
|
Ember.Object = Ember.CoreObject.extend(Ember.Observable);
|
9223
9457
|
|
9224
9458
|
|
@@ -9247,7 +9481,8 @@ var get = Ember.get, set = Ember.set;
|
|
9247
9481
|
@extends Ember.Array
|
9248
9482
|
@extends Ember.MutableArray
|
9249
9483
|
*/
|
9250
|
-
Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,
|
9484
|
+
Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,
|
9485
|
+
/** @scope Ember.ArrayProxy.prototype */ {
|
9251
9486
|
|
9252
9487
|
/**
|
9253
9488
|
The content array. Must be an object that implements Ember.Array and or
|
@@ -9379,7 +9614,7 @@ Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray, {
|
|
9379
9614
|
|
9380
9615
|
Then, create a view that binds to your new controller:
|
9381
9616
|
|
9382
|
-
{{collection contentBinding="MyApp.listController"}}
|
9617
|
+
{{#collection contentBinding="MyApp.listController"}}
|
9383
9618
|
{{content.firstName}} {{content.lastName}}
|
9384
9619
|
{{/collection}}
|
9385
9620
|
|
@@ -9409,8 +9644,10 @@ Ember.ArrayController = Ember.ArrayProxy.extend();
|
|
9409
9644
|
var fmt = Ember.String.fmt,
|
9410
9645
|
w = Ember.String.w,
|
9411
9646
|
loc = Ember.String.loc,
|
9647
|
+
camelize = Ember.String.camelize,
|
9412
9648
|
decamelize = Ember.String.decamelize,
|
9413
|
-
dasherize = Ember.String.dasherize
|
9649
|
+
dasherize = Ember.String.dasherize,
|
9650
|
+
underscore = Ember.String.underscore;
|
9414
9651
|
|
9415
9652
|
if (Ember.EXTEND_PROTOTYPES) {
|
9416
9653
|
|
@@ -9434,23 +9671,36 @@ if (Ember.EXTEND_PROTOTYPES) {
|
|
9434
9671
|
String.prototype.loc = function() {
|
9435
9672
|
return loc(this, arguments);
|
9436
9673
|
};
|
9437
|
-
|
9674
|
+
|
9675
|
+
/**
|
9676
|
+
@see Ember.String.camelize
|
9677
|
+
*/
|
9678
|
+
String.prototype.camelize = function() {
|
9679
|
+
return camelize(this);
|
9680
|
+
};
|
9681
|
+
|
9438
9682
|
/**
|
9439
9683
|
@see Ember.String.decamelize
|
9440
9684
|
*/
|
9441
9685
|
String.prototype.decamelize = function() {
|
9442
9686
|
return decamelize(this);
|
9443
9687
|
};
|
9444
|
-
|
9688
|
+
|
9445
9689
|
/**
|
9446
9690
|
@see Ember.String.dasherize
|
9447
9691
|
*/
|
9448
9692
|
String.prototype.dasherize = function() {
|
9449
9693
|
return dasherize(this);
|
9450
9694
|
};
|
9451
|
-
}
|
9452
9695
|
|
9696
|
+
/**
|
9697
|
+
@see Ember.String.underscore
|
9698
|
+
*/
|
9699
|
+
String.prototype.underscore = function() {
|
9700
|
+
return underscore(this);
|
9701
|
+
};
|
9453
9702
|
|
9703
|
+
}
|
9454
9704
|
|
9455
9705
|
|
9456
9706
|
})({});
|
@@ -9463,6 +9713,8 @@ if (Ember.EXTEND_PROTOTYPES) {
|
|
9463
9713
|
// Portions ©2008-2011 Apple Inc. All rights reserved.
|
9464
9714
|
// License: Licensed under MIT license (see license.js)
|
9465
9715
|
// ==========================================================================
|
9716
|
+
var a_slice = Array.prototype.slice;
|
9717
|
+
|
9466
9718
|
if (Ember.EXTEND_PROTOTYPES) {
|
9467
9719
|
|
9468
9720
|
Function.prototype.property = function() {
|
@@ -9471,12 +9723,12 @@ if (Ember.EXTEND_PROTOTYPES) {
|
|
9471
9723
|
};
|
9472
9724
|
|
9473
9725
|
Function.prototype.observes = function() {
|
9474
|
-
this.__ember_observes__ =
|
9726
|
+
this.__ember_observes__ = a_slice.call(arguments);
|
9475
9727
|
return this;
|
9476
9728
|
};
|
9477
9729
|
|
9478
9730
|
Function.prototype.observesBefore = function() {
|
9479
|
-
this.__ember_observesBefore__ =
|
9731
|
+
this.__ember_observesBefore__ = a_slice.call(arguments);
|
9480
9732
|
return this;
|
9481
9733
|
};
|
9482
9734
|
|
@@ -9617,7 +9869,7 @@ Ember.Comparable = Ember.Mixin.create( /** @scope Ember.Comparable.prototype */{
|
|
9617
9869
|
|
9618
9870
|
|
9619
9871
|
(function(exports) {
|
9620
|
-
var get = Ember.get, set = Ember.set;
|
9872
|
+
var get = Ember.get, set = Ember.set, getPath = Ember.getPath;
|
9621
9873
|
|
9622
9874
|
Ember.TargetActionSupport = Ember.Mixin.create({
|
9623
9875
|
target: null,
|
@@ -9627,7 +9879,10 @@ Ember.TargetActionSupport = Ember.Mixin.create({
|
|
9627
9879
|
var target = get(this, 'target');
|
9628
9880
|
|
9629
9881
|
if (Ember.typeOf(target) === "string") {
|
9630
|
-
|
9882
|
+
// TODO: Remove the false when deprecation is done
|
9883
|
+
var value = getPath(this, target, false);
|
9884
|
+
if (value === undefined) { value = getPath(window, target); }
|
9885
|
+
return value;
|
9631
9886
|
} else {
|
9632
9887
|
return target;
|
9633
9888
|
}
|
@@ -9638,14 +9893,21 @@ Ember.TargetActionSupport = Ember.Mixin.create({
|
|
9638
9893
|
target = get(this, 'targetObject');
|
9639
9894
|
|
9640
9895
|
if (target && action) {
|
9896
|
+
var ret;
|
9897
|
+
|
9641
9898
|
if (typeof target.send === 'function') {
|
9642
|
-
target.send(action, this);
|
9899
|
+
ret = target.send(action, this);
|
9643
9900
|
} else {
|
9644
9901
|
if (typeof action === 'string') {
|
9645
9902
|
action = target[action];
|
9646
9903
|
}
|
9647
|
-
action.call(target, this);
|
9904
|
+
ret = action.call(target, this);
|
9648
9905
|
}
|
9906
|
+
if (ret !== false) ret = true;
|
9907
|
+
|
9908
|
+
return ret;
|
9909
|
+
} else {
|
9910
|
+
return false;
|
9649
9911
|
}
|
9650
9912
|
}
|
9651
9913
|
});
|
@@ -10069,7 +10331,7 @@ Ember.NativeArray = NativeArray;
|
|
10069
10331
|
*/
|
10070
10332
|
Ember.A = function(arr){
|
10071
10333
|
if (arr === undefined) { arr = []; }
|
10072
|
-
return Ember.NativeArray.apply(
|
10334
|
+
return Ember.NativeArray.apply(arr);
|
10073
10335
|
};
|
10074
10336
|
|
10075
10337
|
/**
|
@@ -10080,6 +10342,8 @@ Ember.A = function(arr){
|
|
10080
10342
|
*/
|
10081
10343
|
Ember.NativeArray.activate = function() {
|
10082
10344
|
NativeArray.apply(Array.prototype);
|
10345
|
+
|
10346
|
+
Ember.A = function(arr) { return arr || []; }
|
10083
10347
|
};
|
10084
10348
|
|
10085
10349
|
if (Ember.EXTEND_PROTOTYPES) Ember.NativeArray.activate();
|
@@ -10210,7 +10474,7 @@ Ember._RenderBuffer = Ember.Object.extend(
|
|
10210
10474
|
set(this ,'elementClasses', Ember.A());
|
10211
10475
|
set(this, 'elementAttributes', {});
|
10212
10476
|
set(this, 'elementStyle', {});
|
10213
|
-
set(this, 'childBuffers',
|
10477
|
+
set(this, 'childBuffers', []);
|
10214
10478
|
set(this, 'elements', {});
|
10215
10479
|
},
|
10216
10480
|
|
@@ -10221,7 +10485,7 @@ Ember._RenderBuffer = Ember.Object.extend(
|
|
10221
10485
|
@returns {Ember.RenderBuffer} this
|
10222
10486
|
*/
|
10223
10487
|
push: function(string) {
|
10224
|
-
get(this, 'childBuffers').
|
10488
|
+
get(this, 'childBuffers').push(String(string));
|
10225
10489
|
return this;
|
10226
10490
|
},
|
10227
10491
|
|
@@ -10247,15 +10511,38 @@ Ember._RenderBuffer = Ember.Object.extend(
|
|
10247
10511
|
return this;
|
10248
10512
|
},
|
10249
10513
|
|
10514
|
+
// duck type attribute functionality like jQuery so a render buffer
|
10515
|
+
// can be used like a jQuery object in attribute binding scenarios.
|
10516
|
+
|
10250
10517
|
/**
|
10251
10518
|
Adds an attribute which will be rendered to the element.
|
10252
10519
|
|
10253
10520
|
@param {String} name The name of the attribute
|
10254
10521
|
@param {String} value The value to add to the attribute
|
10255
|
-
@returns {Ember.RenderBuffer} this
|
10522
|
+
@returns {Ember.RenderBuffer|String} this or the current attribute value
|
10256
10523
|
*/
|
10257
10524
|
attr: function(name, value) {
|
10258
|
-
get(this, 'elementAttributes')
|
10525
|
+
var attributes = get(this, 'elementAttributes');
|
10526
|
+
|
10527
|
+
if (arguments.length === 1) {
|
10528
|
+
return attributes[name]
|
10529
|
+
} else {
|
10530
|
+
attributes[name] = value;
|
10531
|
+
}
|
10532
|
+
|
10533
|
+
return this;
|
10534
|
+
},
|
10535
|
+
|
10536
|
+
/**
|
10537
|
+
Remove an attribute from the list of attributes to render.
|
10538
|
+
|
10539
|
+
@param {String} name The name of the attribute
|
10540
|
+
@returns {Ember.RenderBuffer} this
|
10541
|
+
*/
|
10542
|
+
removeAttr: function(name) {
|
10543
|
+
var attributes = get(this, 'elementAttributes');
|
10544
|
+
delete attributes[name];
|
10545
|
+
|
10259
10546
|
return this;
|
10260
10547
|
},
|
10261
10548
|
|
@@ -10333,7 +10620,7 @@ Ember._RenderBuffer = Ember.Object.extend(
|
|
10333
10620
|
*/
|
10334
10621
|
begin: function(tagName) {
|
10335
10622
|
return this.newBuffer(tagName, this, function(buffer) {
|
10336
|
-
get(this, 'childBuffers').
|
10623
|
+
get(this, 'childBuffers').push(buffer);
|
10337
10624
|
});
|
10338
10625
|
},
|
10339
10626
|
|
@@ -10344,7 +10631,7 @@ Ember._RenderBuffer = Ember.Object.extend(
|
|
10344
10631
|
*/
|
10345
10632
|
prepend: function(tagName) {
|
10346
10633
|
return this.newBuffer(tagName, this, function(buffer) {
|
10347
|
-
get(this, 'childBuffers').
|
10634
|
+
get(this, 'childBuffers').splice(0, 0, buffer);
|
10348
10635
|
});
|
10349
10636
|
},
|
10350
10637
|
|
@@ -10372,7 +10659,7 @@ Ember._RenderBuffer = Ember.Object.extend(
|
|
10372
10659
|
return this.newBuffer(tagName, parentBuffer, function(buffer) {
|
10373
10660
|
var siblings = get(parentBuffer, 'childBuffers');
|
10374
10661
|
var index = siblings.indexOf(this);
|
10375
|
-
siblings.
|
10662
|
+
siblings.splice(index + 1, 0, buffer);
|
10376
10663
|
});
|
10377
10664
|
},
|
10378
10665
|
|
@@ -10482,10 +10769,15 @@ Ember.EventDispatcher = Ember.Object.extend(
|
|
10482
10769
|
The root DOM element to which event listeners should be attached. Event
|
10483
10770
|
listeners will be attached to the document unless this is overridden.
|
10484
10771
|
|
10772
|
+
Can be specified as a DOMElement or a selector string.
|
10773
|
+
|
10774
|
+
The default body is a string since this may be evaluated before document.body
|
10775
|
+
exists in the DOM.
|
10776
|
+
|
10485
10777
|
@type DOMElement
|
10486
|
-
@default
|
10778
|
+
@default 'body'
|
10487
10779
|
*/
|
10488
|
-
rootElement:
|
10780
|
+
rootElement: 'body',
|
10489
10781
|
|
10490
10782
|
/**
|
10491
10783
|
@private
|
@@ -10536,6 +10828,8 @@ Ember.EventDispatcher = Ember.Object.extend(
|
|
10536
10828
|
|
10537
10829
|
rootElement.addClass('ember-application');
|
10538
10830
|
|
10831
|
+
ember_assert('Unable to add "ember-application" class to rootElement. Make sure you the body or an element in the body.', rootElement.is('.ember-application'));
|
10832
|
+
|
10539
10833
|
for (event in events) {
|
10540
10834
|
if (events.hasOwnProperty(event)) {
|
10541
10835
|
this.setupHandler(rootElement, event, events[event]);
|
@@ -10616,17 +10910,9 @@ Ember.EventDispatcher = Ember.Object.extend(
|
|
10616
10910
|
|
10617
10911
|
/** @private */
|
10618
10912
|
_bubbleEvent: function(view, evt, eventName) {
|
10619
|
-
|
10620
|
-
|
10621
|
-
|
10622
|
-
Ember.run(function() {
|
10623
|
-
handler = view[eventName];
|
10624
|
-
if (Ember.typeOf(handler) === 'function') {
|
10625
|
-
result = handler.call(view, evt);
|
10626
|
-
}
|
10627
|
-
});
|
10628
|
-
|
10629
|
-
return result;
|
10913
|
+
return Ember.run(function() {
|
10914
|
+
return view.handleEvent(eventName, evt);
|
10915
|
+
});
|
10630
10916
|
},
|
10631
10917
|
|
10632
10918
|
/** @private */
|
@@ -10680,10 +10966,14 @@ Ember.Application = Ember.Namespace.extend(
|
|
10680
10966
|
/** @scope Ember.Application.prototype */{
|
10681
10967
|
|
10682
10968
|
/**
|
10969
|
+
The root DOM element of the Application.
|
10970
|
+
|
10971
|
+
Can be specified as DOMElement or a selector string.
|
10972
|
+
|
10683
10973
|
@type DOMElement
|
10684
|
-
@default
|
10974
|
+
@default 'body'
|
10685
10975
|
*/
|
10686
|
-
rootElement:
|
10976
|
+
rootElement: 'body',
|
10687
10977
|
|
10688
10978
|
/**
|
10689
10979
|
@type Ember.EventDispatcher
|
@@ -10709,21 +10999,35 @@ Ember.Application = Ember.Namespace.extend(
|
|
10709
10999
|
|
10710
11000
|
set(this, 'eventDispatcher', eventDispatcher);
|
10711
11001
|
|
10712
|
-
|
10713
|
-
Ember
|
10714
|
-
|
10715
|
-
}
|
11002
|
+
// jQuery 1.7 doesn't call the ready callback if already ready
|
11003
|
+
if (Ember.$.isReady) {
|
11004
|
+
this.didBecomeReady();
|
11005
|
+
} else {
|
11006
|
+
var self = this;
|
11007
|
+
Ember.$(document).ready(function() {
|
11008
|
+
self.didBecomeReady();
|
11009
|
+
});
|
11010
|
+
}
|
10716
11011
|
|
10717
11012
|
this._super();
|
10718
11013
|
},
|
10719
11014
|
|
10720
|
-
|
11015
|
+
/** @private */
|
11016
|
+
didBecomeReady: function() {
|
10721
11017
|
var eventDispatcher = get(this, 'eventDispatcher'),
|
10722
11018
|
customEvents = get(this, 'customEvents');
|
10723
11019
|
|
10724
11020
|
eventDispatcher.setup(customEvents);
|
11021
|
+
|
11022
|
+
this.ready();
|
10725
11023
|
},
|
10726
11024
|
|
11025
|
+
/**
|
11026
|
+
Called when the Application has become ready.
|
11027
|
+
The call will be delayed until the DOM has become ready.
|
11028
|
+
*/
|
11029
|
+
ready: Ember.K,
|
11030
|
+
|
10727
11031
|
/** @private */
|
10728
11032
|
destroy: function() {
|
10729
11033
|
get(this, 'eventDispatcher').destroy();
|
@@ -10772,6 +11076,7 @@ queues.splice(jQuery.inArray('actions', queues)+1, 0, 'render');
|
|
10772
11076
|
/*globals ember_assert */
|
10773
11077
|
var get = Ember.get, set = Ember.set, addObserver = Ember.addObserver;
|
10774
11078
|
var getPath = Ember.getPath, meta = Ember.meta, fmt = Ember.String.fmt;
|
11079
|
+
var a_slice = Array.prototype.slice;
|
10775
11080
|
|
10776
11081
|
var childViewsProperty = Ember.computed(function() {
|
10777
11082
|
var childViews = get(this, '_childViews');
|
@@ -10910,13 +11215,19 @@ Ember.View = Ember.Object.extend(
|
|
10910
11215
|
}
|
10911
11216
|
}).property('_parentView'),
|
10912
11217
|
|
11218
|
+
// return the current view, not including virtual views
|
11219
|
+
concreteView: Ember.computed(function() {
|
11220
|
+
if (!this.isVirtual) { return this; }
|
11221
|
+
else { return get(this, 'parentView'); }
|
11222
|
+
}).property('_parentView'),
|
11223
|
+
|
10913
11224
|
/**
|
10914
11225
|
If false, the view will appear hidden in DOM.
|
10915
11226
|
|
10916
11227
|
@type Boolean
|
10917
|
-
@default
|
11228
|
+
@default null
|
10918
11229
|
*/
|
10919
|
-
isVisible:
|
11230
|
+
isVisible: null,
|
10920
11231
|
|
10921
11232
|
/**
|
10922
11233
|
Array of child views. You should never edit this array directly.
|
@@ -11063,7 +11374,7 @@ Ember.View = Ember.Object.extend(
|
|
11063
11374
|
var fn = state[name];
|
11064
11375
|
|
11065
11376
|
if (fn) {
|
11066
|
-
var args =
|
11377
|
+
var args = a_slice.call(arguments, 1);
|
11067
11378
|
args.unshift(this);
|
11068
11379
|
|
11069
11380
|
return fn.apply(this, args);
|
@@ -11192,38 +11503,22 @@ Ember.View = Ember.Object.extend(
|
|
11192
11503
|
|
11193
11504
|
if (!attributeBindings) { return; }
|
11194
11505
|
|
11195
|
-
attributeBindings.forEach(function(
|
11506
|
+
attributeBindings.forEach(function(attributeName) {
|
11196
11507
|
// Create an observer to add/remove/change the attribute if the
|
11197
11508
|
// JavaScript property changes.
|
11198
11509
|
var observer = function() {
|
11199
11510
|
elem = this.$();
|
11200
|
-
|
11201
|
-
attributeValue = get(this, attribute);
|
11202
|
-
|
11203
|
-
type = typeof attributeValue;
|
11511
|
+
attributeValue = get(this, attributeName);
|
11204
11512
|
|
11205
|
-
|
11206
|
-
elem.attr(attribute, attributeValue);
|
11207
|
-
} else if (attributeValue && type === 'boolean') {
|
11208
|
-
elem.attr(attribute, attribute);
|
11209
|
-
} else if (!attributeValue) {
|
11210
|
-
elem.removeAttr(attribute);
|
11211
|
-
}
|
11513
|
+
Ember.View.applyAttributeBindings(elem, attributeName, attributeValue)
|
11212
11514
|
};
|
11213
11515
|
|
11214
|
-
addObserver(this,
|
11516
|
+
addObserver(this, attributeName, observer);
|
11215
11517
|
|
11216
11518
|
// Determine the current value and add it to the render buffer
|
11217
11519
|
// if necessary.
|
11218
|
-
attributeValue = get(this,
|
11219
|
-
|
11220
|
-
|
11221
|
-
if (type === 'string' || type === 'number') {
|
11222
|
-
buffer.attr(attribute, attributeValue);
|
11223
|
-
} else if (attributeValue && type === 'boolean') {
|
11224
|
-
// Apply boolean attributes in the form attribute="attribute"
|
11225
|
-
buffer.attr(attribute, attribute);
|
11226
|
-
}
|
11520
|
+
attributeValue = get(this, attributeName);
|
11521
|
+
Ember.View.applyAttributeBindings(buffer, attributeName, attributeValue);
|
11227
11522
|
}, this);
|
11228
11523
|
},
|
11229
11524
|
|
@@ -11347,6 +11642,9 @@ Ember.View = Ember.Object.extend(
|
|
11347
11642
|
// Schedule the DOM element to be created and appended to the given
|
11348
11643
|
// element after bindings have synchronized.
|
11349
11644
|
this._insertElementLater(function() {
|
11645
|
+
if (get(this, 'isVisible') === null) {
|
11646
|
+
set(this, 'isVisible', true);
|
11647
|
+
}
|
11350
11648
|
this.$().appendTo(target);
|
11351
11649
|
});
|
11352
11650
|
|
@@ -11467,7 +11765,7 @@ Ember.View = Ember.Object.extend(
|
|
11467
11765
|
*/
|
11468
11766
|
renderBuffer: function(tagName) {
|
11469
11767
|
tagName = tagName || get(this, 'tagName');
|
11470
|
-
if (tagName == null) { tagName =
|
11768
|
+
if (tagName == null) { tagName = 'div'; }
|
11471
11769
|
|
11472
11770
|
return Ember.RenderBuffer(tagName);
|
11473
11771
|
},
|
@@ -11656,7 +11954,7 @@ Ember.View = Ember.Object.extend(
|
|
11656
11954
|
// insert a new buffer after the "parent buffer").
|
11657
11955
|
if (parentBuffer) {
|
11658
11956
|
var tagName = get(this, 'tagName');
|
11659
|
-
|
11957
|
+
if (tagName == null) { tagName = 'div'; }
|
11660
11958
|
|
11661
11959
|
buffer = parentBuffer[bufferOperation](tagName);
|
11662
11960
|
} else {
|
@@ -11705,7 +12003,7 @@ Ember.View = Ember.Object.extend(
|
|
11705
12003
|
buffer.attr('role', role);
|
11706
12004
|
}
|
11707
12005
|
|
11708
|
-
if (
|
12006
|
+
if (get(this, 'isVisible') === false) {
|
11709
12007
|
buffer.style('display', 'none');
|
11710
12008
|
}
|
11711
12009
|
},
|
@@ -11845,6 +12143,14 @@ Ember.View = Ember.Object.extend(
|
|
11845
12143
|
set(this, 'domManager', this.domManagerClass.create({ view: this }));
|
11846
12144
|
|
11847
12145
|
meta(this)["Ember.View"] = {};
|
12146
|
+
|
12147
|
+
var viewController = get(this, 'viewController');
|
12148
|
+
if (viewController) {
|
12149
|
+
viewController = Ember.getPath(viewController);
|
12150
|
+
if (viewController) {
|
12151
|
+
set(viewController, 'view', this);
|
12152
|
+
}
|
12153
|
+
}
|
11848
12154
|
},
|
11849
12155
|
|
11850
12156
|
appendChild: function(view, options) {
|
@@ -11959,7 +12265,10 @@ Ember.View = Ember.Object.extend(
|
|
11959
12265
|
view = view.create(attrs || {}, { _parentView: this });
|
11960
12266
|
|
11961
12267
|
var viewName = attrs && attrs.viewName || view.viewName;
|
11962
|
-
|
12268
|
+
|
12269
|
+
// don't set the property on a virtual view, as they are invisible to
|
12270
|
+
// consumers of the view API
|
12271
|
+
if (viewName) { set(get(this, 'concreteView'), viewName, view); }
|
11963
12272
|
} else {
|
11964
12273
|
ember_assert('must pass instance of View', view instanceof Ember.View);
|
11965
12274
|
set(view, '_parentView', this);
|
@@ -11967,6 +12276,9 @@ Ember.View = Ember.Object.extend(
|
|
11967
12276
|
return view;
|
11968
12277
|
},
|
11969
12278
|
|
12279
|
+
becameVisible: Ember.K,
|
12280
|
+
becameHidden: Ember.K,
|
12281
|
+
|
11970
12282
|
/**
|
11971
12283
|
@private
|
11972
12284
|
|
@@ -11974,9 +12286,54 @@ Ember.View = Ember.Object.extend(
|
|
11974
12286
|
element of the actual DOM element.
|
11975
12287
|
*/
|
11976
12288
|
_isVisibleDidChange: Ember.observer(function() {
|
11977
|
-
|
12289
|
+
var isVisible = get(this, 'isVisible');
|
12290
|
+
|
12291
|
+
this.$().toggle(isVisible);
|
12292
|
+
|
12293
|
+
if (this._isAncestorHidden()) { return; }
|
12294
|
+
|
12295
|
+
if (isVisible) {
|
12296
|
+
this._notifyBecameVisible();
|
12297
|
+
} else {
|
12298
|
+
this._notifyBecameHidden();
|
12299
|
+
}
|
11978
12300
|
}, 'isVisible'),
|
11979
12301
|
|
12302
|
+
_notifyBecameVisible: function() {
|
12303
|
+
this.becameVisible();
|
12304
|
+
|
12305
|
+
this.forEachChildView(function(view) {
|
12306
|
+
var isVisible = get(view, 'isVisible');
|
12307
|
+
|
12308
|
+
if (isVisible || isVisible === null) {
|
12309
|
+
view._notifyBecameVisible();
|
12310
|
+
}
|
12311
|
+
});
|
12312
|
+
},
|
12313
|
+
|
12314
|
+
_notifyBecameHidden: function() {
|
12315
|
+
this.becameHidden();
|
12316
|
+
this.forEachChildView(function(view) {
|
12317
|
+
var isVisible = get(view, 'isVisible');
|
12318
|
+
|
12319
|
+
if (isVisible || isVisible === null) {
|
12320
|
+
view._notifyBecameHidden();
|
12321
|
+
}
|
12322
|
+
});
|
12323
|
+
},
|
12324
|
+
|
12325
|
+
_isAncestorHidden: function() {
|
12326
|
+
var parent = get(this, 'parentView');
|
12327
|
+
|
12328
|
+
while (parent) {
|
12329
|
+
if (get(parent, 'isVisible') === false) { return true; }
|
12330
|
+
|
12331
|
+
parent = get(parent, 'parentView');
|
12332
|
+
}
|
12333
|
+
|
12334
|
+
return false;
|
12335
|
+
},
|
12336
|
+
|
11980
12337
|
clearBuffer: function() {
|
11981
12338
|
this.invokeRecursively(function(view) {
|
11982
12339
|
meta(view)['Ember.View'].buffer = null;
|
@@ -11991,6 +12348,19 @@ Ember.View = Ember.Object.extend(
|
|
11991
12348
|
view.transitionTo(state);
|
11992
12349
|
});
|
11993
12350
|
}
|
12351
|
+
},
|
12352
|
+
|
12353
|
+
// .......................................................
|
12354
|
+
// EVENT HANDLING
|
12355
|
+
//
|
12356
|
+
|
12357
|
+
/**
|
12358
|
+
@private
|
12359
|
+
|
12360
|
+
Handle events from `Ember.EventDispatcher`
|
12361
|
+
*/
|
12362
|
+
handleEvent: function(eventName, evt) {
|
12363
|
+
return this.invokeForState('handleEvent', eventName, evt);
|
11994
12364
|
}
|
11995
12365
|
|
11996
12366
|
});
|
@@ -12075,6 +12445,20 @@ Ember.View.views = {};
|
|
12075
12445
|
// method.
|
12076
12446
|
Ember.View.childViewsProperty = childViewsProperty;
|
12077
12447
|
|
12448
|
+
Ember.View.applyAttributeBindings = function(elem, name, value) {
|
12449
|
+
var type = typeof value;
|
12450
|
+
var currentValue = elem.attr(name);
|
12451
|
+
|
12452
|
+
// if this changes, also change the logic in ember-handlebars/lib/helpers/binding.js
|
12453
|
+
if ((type === 'string' || (type === 'number' && !isNaN(value))) && value !== currentValue) {
|
12454
|
+
elem.attr(name, value);
|
12455
|
+
} else if (value && type === 'boolean') {
|
12456
|
+
elem.attr(name, name);
|
12457
|
+
} else if (!value) {
|
12458
|
+
elem.removeAttr(name);
|
12459
|
+
}
|
12460
|
+
};
|
12461
|
+
|
12078
12462
|
})({});
|
12079
12463
|
|
12080
12464
|
|
@@ -12100,6 +12484,11 @@ Ember.View.states = {
|
|
12100
12484
|
|
12101
12485
|
getElement: function() {
|
12102
12486
|
return null;
|
12487
|
+
},
|
12488
|
+
|
12489
|
+
// Handle events from `Ember.EventDispatcher`
|
12490
|
+
handleEvent: function() {
|
12491
|
+
return true; // continue event propagation
|
12103
12492
|
}
|
12104
12493
|
}
|
12105
12494
|
};
|
@@ -12296,6 +12685,16 @@ Ember.View.states.hasElement = {
|
|
12296
12685
|
|
12297
12686
|
get(view, 'domManager').remove();
|
12298
12687
|
return view;
|
12688
|
+
},
|
12689
|
+
|
12690
|
+
// Handle events from `Ember.EventDispatcher`
|
12691
|
+
handleEvent: function(view, eventName, evt) {
|
12692
|
+
var handler = view[eventName];
|
12693
|
+
if (Ember.typeOf(handler) === 'function') {
|
12694
|
+
return handler.call(view, evt);
|
12695
|
+
} else {
|
12696
|
+
return true; // continue event propagation
|
12697
|
+
}
|
12299
12698
|
}
|
12300
12699
|
};
|
12301
12700
|
|
@@ -12429,7 +12828,7 @@ Ember.ContainerView = Ember.View.extend({
|
|
12429
12828
|
},
|
12430
12829
|
|
12431
12830
|
/**
|
12432
|
-
When the container view is
|
12831
|
+
When the container view is destroyed, tear down the child views
|
12433
12832
|
array observer.
|
12434
12833
|
|
12435
12834
|
@private
|
@@ -12456,6 +12855,11 @@ Ember.ContainerView = Ember.View.extend({
|
|
12456
12855
|
@param {Number} removed the number of child views removed
|
12457
12856
|
**/
|
12458
12857
|
childViewsWillChange: function(views, start, removed) {
|
12858
|
+
if (removed === 0) { return; }
|
12859
|
+
|
12860
|
+
var changedViews = views.slice(start, removed);
|
12861
|
+
this.setParentView(changedViews, null);
|
12862
|
+
|
12459
12863
|
this.invokeForState('childViewsWillChange', views, start, removed);
|
12460
12864
|
},
|
12461
12865
|
|
@@ -12480,10 +12884,19 @@ Ember.ContainerView = Ember.View.extend({
|
|
12480
12884
|
// No new child views were added; bail out.
|
12481
12885
|
if (added === 0) return;
|
12482
12886
|
|
12887
|
+
var changedViews = views.slice(start, added);
|
12888
|
+
this.setParentView(changedViews, this);
|
12889
|
+
|
12483
12890
|
// Let the current state handle the changes
|
12484
12891
|
this.invokeForState('childViewsDidChange', views, start, added);
|
12485
12892
|
},
|
12486
12893
|
|
12894
|
+
setParentView: function(views, parentView) {
|
12895
|
+
views.forEach(function(view) {
|
12896
|
+
set(view, '_parentView', parentView);
|
12897
|
+
});
|
12898
|
+
},
|
12899
|
+
|
12487
12900
|
/**
|
12488
12901
|
Schedules a child view to be inserted into the DOM after bindings have
|
12489
12902
|
finished syncing for this run loop.
|
@@ -12693,6 +13106,10 @@ Ember.CollectionView = Ember.ContainerView.extend(
|
|
12693
13106
|
childViews = get(this, 'childViews'),
|
12694
13107
|
addedViews = [], view, item, idx, len, itemTagName;
|
12695
13108
|
|
13109
|
+
if ('string' === typeof itemViewClass) {
|
13110
|
+
itemViewClass = Ember.getPath(itemViewClass);
|
13111
|
+
}
|
13112
|
+
|
12696
13113
|
ember_assert(fmt("itemViewClass must be a subclass of Ember.View, not %@", [itemViewClass]), Ember.View.detect(itemViewClass));
|
12697
13114
|
|
12698
13115
|
len = content ? get(content, 'length') : 0;
|
@@ -12772,7 +13189,8 @@ Ember.CollectionView.CONTAINER_MAP = {
|
|
12772
13189
|
// Portions ©2008-2011 Apple Inc. All rights reserved.
|
12773
13190
|
// License: Licensed under MIT license (see license.js)
|
12774
13191
|
// ==========================================================================
|
12775
|
-
Ember
|
13192
|
+
ember_assert("Ember requires jQuery 1.6 or 1.7", window.jQuery && jQuery().jquery.match(/^1\.[67](.\d+)?$/));
|
13193
|
+
Ember.$ = window.jQuery;
|
12776
13194
|
})({});
|
12777
13195
|
|
12778
13196
|
(function(exports) {
|
@@ -12784,14 +13202,50 @@ Ember.State = Ember.Object.extend({
|
|
12784
13202
|
start: null,
|
12785
13203
|
|
12786
13204
|
init: function() {
|
12787
|
-
|
12788
|
-
|
13205
|
+
var states = get(this, 'states'), foundStates;
|
13206
|
+
|
13207
|
+
// As a convenience, loop over the properties
|
13208
|
+
// of this state and look for any that are other
|
13209
|
+
// Ember.State instances or classes, and move them
|
13210
|
+
// to the `states` hash. This avoids having to
|
13211
|
+
// create an explicit separate hash.
|
13212
|
+
|
13213
|
+
if (!states) {
|
13214
|
+
states = {};
|
13215
|
+
for (var name in this) {
|
13216
|
+
if (name === "constructor") { continue; }
|
13217
|
+
value = this.setupChild(name, this[name]);
|
12789
13218
|
|
12790
|
-
|
12791
|
-
|
12792
|
-
|
13219
|
+
if (value) {
|
13220
|
+
foundStates = true;
|
13221
|
+
states[name] = value;
|
13222
|
+
}
|
12793
13223
|
}
|
12794
|
-
|
13224
|
+
|
13225
|
+
if (foundStates) { set(this, 'states', states); }
|
13226
|
+
} else {
|
13227
|
+
for (var name in states) {
|
13228
|
+
this.setupChild(name, states[name]);
|
13229
|
+
}
|
13230
|
+
}
|
13231
|
+
|
13232
|
+
set(this, 'routes', {});
|
13233
|
+
},
|
13234
|
+
|
13235
|
+
setupChild: function(name, value) {
|
13236
|
+
if (!value) { return false; }
|
13237
|
+
|
13238
|
+
if (Ember.State.detect(value)) {
|
13239
|
+
value = value.create();
|
13240
|
+
}
|
13241
|
+
|
13242
|
+
if (value.isState) {
|
13243
|
+
set(value, 'parentState', this);
|
13244
|
+
set(value, 'name', (get(this, 'name') || '') + '.' + name);
|
13245
|
+
return value;
|
13246
|
+
}
|
13247
|
+
|
13248
|
+
return false;
|
12795
13249
|
},
|
12796
13250
|
|
12797
13251
|
enter: Ember.K,
|
@@ -12805,29 +13259,20 @@ Ember.State = Ember.Object.extend({
|
|
12805
13259
|
var get = Ember.get, set = Ember.set, getPath = Ember.getPath, fmt = Ember.String.fmt;
|
12806
13260
|
Ember.LOG_STATE_TRANSITIONS = false;
|
12807
13261
|
|
12808
|
-
|
13262
|
+
/**
|
13263
|
+
@class
|
13264
|
+
*/
|
13265
|
+
Ember.StateManager = Ember.State.extend(
|
13266
|
+
/** @scope Ember.State.prototype */ {
|
13267
|
+
|
12809
13268
|
/**
|
12810
|
-
When creating a new
|
13269
|
+
When creating a new statemanager, look for a default state to transition
|
12811
13270
|
into. This state can either be named `start`, or can be specified using the
|
12812
13271
|
`initialState` property.
|
12813
13272
|
*/
|
12814
13273
|
init: function() {
|
12815
13274
|
this._super();
|
12816
13275
|
|
12817
|
-
var states = get(this, 'states');
|
12818
|
-
if (!states) {
|
12819
|
-
states = {};
|
12820
|
-
Ember.keys(this).forEach(function(name) {
|
12821
|
-
var value = get(this, name);
|
12822
|
-
|
12823
|
-
if (value && value.isState) {
|
12824
|
-
states[name] = value;
|
12825
|
-
}
|
12826
|
-
}, this);
|
12827
|
-
|
12828
|
-
set(this, 'states', states);
|
12829
|
-
}
|
12830
|
-
|
12831
13276
|
var initialState = get(this, 'initialState');
|
12832
13277
|
|
12833
13278
|
if (!initialState && get(this, 'start')) {
|
@@ -12842,11 +13287,13 @@ Ember.StateManager = Ember.State.extend({
|
|
12842
13287
|
currentState: null,
|
12843
13288
|
|
12844
13289
|
/**
|
13290
|
+
@property
|
13291
|
+
|
12845
13292
|
If the current state is a view state or the descendent of a view state,
|
12846
13293
|
this property will be the view associated with it. If there is no
|
12847
13294
|
view state active in this state manager, this value will be null.
|
12848
13295
|
*/
|
12849
|
-
currentView:
|
13296
|
+
currentView: Ember.computed(function() {
|
12850
13297
|
var currentState = get(this, 'currentState'),
|
12851
13298
|
view;
|
12852
13299
|
|
@@ -12872,7 +13319,7 @@ Ember.StateManager = Ember.State.extend({
|
|
12872
13319
|
var action = currentState[event];
|
12873
13320
|
|
12874
13321
|
if (action) {
|
12875
|
-
if (log) { console.log(fmt("
|
13322
|
+
if (log) { console.log(fmt("STATEMANAGER: Sending event '%@' to state %@.", [event, currentState.name])); }
|
12876
13323
|
action.call(currentState, this, context);
|
12877
13324
|
} else {
|
12878
13325
|
var parentState = get(currentState, 'parentState');
|
@@ -12880,28 +13327,72 @@ Ember.StateManager = Ember.State.extend({
|
|
12880
13327
|
}
|
12881
13328
|
},
|
12882
13329
|
|
13330
|
+
findStatesByRoute: function(state, route) {
|
13331
|
+
if (!route || route === "") { return undefined; }
|
13332
|
+
var r = route.split('.'), ret = [];
|
13333
|
+
|
13334
|
+
for (var i=0, len = r.length; i < len; i += 1) {
|
13335
|
+
var states = get(state, 'states') ;
|
13336
|
+
|
13337
|
+
if (!states) { return undefined; }
|
13338
|
+
|
13339
|
+
var s = get(states, r[i]);
|
13340
|
+
if (s) { state = s; ret.push(s); }
|
13341
|
+
else { return undefined; }
|
13342
|
+
}
|
13343
|
+
|
13344
|
+
return ret;
|
13345
|
+
},
|
13346
|
+
|
12883
13347
|
goToState: function(name) {
|
13348
|
+
if (Ember.empty(name)) { return; }
|
13349
|
+
|
12884
13350
|
var currentState = get(this, 'currentState') || this, state, newState;
|
12885
13351
|
|
12886
|
-
var exitStates =
|
13352
|
+
var exitStates = [], enterStates;
|
12887
13353
|
|
12888
|
-
newState = getPath(currentState, name);
|
12889
13354
|
state = currentState;
|
12890
13355
|
|
12891
|
-
if (
|
13356
|
+
if (state.routes[name]) {
|
13357
|
+
// cache hit
|
13358
|
+
exitStates = state.routes[name].exitStates;
|
13359
|
+
enterStates = state.routes[name].enterStates;
|
13360
|
+
state = state.routes[name].futureState;
|
13361
|
+
} else {
|
13362
|
+
// cache miss
|
13363
|
+
|
13364
|
+
newState = this.findStatesByRoute(currentState, name);
|
13365
|
+
|
12892
13366
|
while (state && !newState) {
|
12893
|
-
exitStates
|
12894
|
-
exitStates.push(state);
|
13367
|
+
exitStates.unshift(state);
|
12895
13368
|
|
12896
13369
|
state = get(state, 'parentState');
|
12897
13370
|
if (!state) {
|
12898
|
-
|
13371
|
+
newState = this.findStatesByRoute(this, name);
|
13372
|
+
if (!newState) { return; }
|
13373
|
+
}
|
13374
|
+
newState = this.findStatesByRoute(state, name);
|
13375
|
+
}
|
13376
|
+
|
13377
|
+
enterStates = newState.slice(0), exitStates = exitStates.slice(0);
|
13378
|
+
|
13379
|
+
if (enterStates.length > 0) {
|
13380
|
+
state = enterStates[enterStates.length - 1];
|
13381
|
+
|
13382
|
+
while (enterStates.length > 0 && enterStates[0] === exitStates[0]) {
|
13383
|
+
enterStates.shift();
|
13384
|
+
exitStates.shift();
|
12899
13385
|
}
|
12900
|
-
newState = getPath(state, name);
|
12901
13386
|
}
|
13387
|
+
|
13388
|
+
currentState.routes[name] = {
|
13389
|
+
exitStates: exitStates,
|
13390
|
+
enterStates: enterStates,
|
13391
|
+
futureState: state
|
13392
|
+
};
|
12902
13393
|
}
|
12903
13394
|
|
12904
|
-
this.enterState(
|
13395
|
+
this.enterState(exitStates, enterStates, state);
|
12905
13396
|
},
|
12906
13397
|
|
12907
13398
|
getState: function(name) {
|
@@ -12938,37 +13429,28 @@ Ember.StateManager = Ember.State.extend({
|
|
12938
13429
|
if (!async) { transition.resume(); }
|
12939
13430
|
},
|
12940
13431
|
|
12941
|
-
enterState: function(
|
13432
|
+
enterState: function(exitStates, enterStates, state) {
|
12942
13433
|
var log = Ember.LOG_STATE_TRANSITIONS;
|
12943
13434
|
|
12944
|
-
var parts = name.split("."), state = parent, enterStates = Ember.A();
|
12945
|
-
|
12946
|
-
parts.forEach(function(name) {
|
12947
|
-
state = state[name];
|
12948
|
-
|
12949
|
-
var guid = Ember.guidFor(state);
|
12950
|
-
|
12951
|
-
if (guid in exitStates) {
|
12952
|
-
exitStates.removeObject(state);
|
12953
|
-
delete exitStates[guid];
|
12954
|
-
} else {
|
12955
|
-
enterStates.push(state);
|
12956
|
-
}
|
12957
|
-
});
|
12958
|
-
|
12959
13435
|
var stateManager = this;
|
12960
13436
|
|
12961
13437
|
this.asyncEach(exitStates, function(state, transition) {
|
12962
13438
|
state.exit(stateManager, transition);
|
12963
13439
|
}, function() {
|
12964
13440
|
this.asyncEach(enterStates, function(state, transition) {
|
12965
|
-
if (log) { console.log("
|
13441
|
+
if (log) { console.log("STATEMANAGER: Entering " + state.name); }
|
12966
13442
|
state.enter(stateManager, transition);
|
12967
13443
|
}, function() {
|
12968
|
-
var startState = state, enteredState;
|
13444
|
+
var startState = state, enteredState, initialSubstate;
|
13445
|
+
|
13446
|
+
initialSubstate = get(startState, 'initialSubstate');
|
13447
|
+
|
13448
|
+
if (!initialSubstate) {
|
13449
|
+
initialSubstate = 'start';
|
13450
|
+
}
|
12969
13451
|
|
12970
13452
|
// right now, start states cannot be entered asynchronously
|
12971
|
-
while (startState = get(startState,
|
13453
|
+
while (startState = get(startState, initialSubstate)) {
|
12972
13454
|
enteredState = startState;
|
12973
13455
|
startState.enter(stateManager);
|
12974
13456
|
}
|
@@ -12989,10 +13471,25 @@ Ember.ViewState = Ember.State.extend({
|
|
12989
13471
|
isViewState: true,
|
12990
13472
|
|
12991
13473
|
enter: function(stateManager) {
|
12992
|
-
var view = get(this, 'view');
|
13474
|
+
var view = get(this, 'view'), root, childViews;
|
12993
13475
|
|
12994
13476
|
if (view) {
|
12995
|
-
|
13477
|
+
if (Ember.View.detect(view)) {
|
13478
|
+
view = view.create();
|
13479
|
+
set(this, 'view', view);
|
13480
|
+
}
|
13481
|
+
|
13482
|
+
ember_assert('view must be an Ember.View', view instanceof Ember.View);
|
13483
|
+
|
13484
|
+
root = stateManager.get('rootView');
|
13485
|
+
|
13486
|
+
if (root) {
|
13487
|
+
childViews = get(root, 'childViews');
|
13488
|
+
childViews.pushObject(view);
|
13489
|
+
} else {
|
13490
|
+
root = stateManager.get('rootElement') || 'body';
|
13491
|
+
view.appendTo(root);
|
13492
|
+
}
|
12996
13493
|
}
|
12997
13494
|
},
|
12998
13495
|
|
@@ -13000,18 +13497,27 @@ Ember.ViewState = Ember.State.extend({
|
|
13000
13497
|
var view = get(this, 'view');
|
13001
13498
|
|
13002
13499
|
if (view) {
|
13003
|
-
view
|
13500
|
+
// If the view has a parent view, then it is
|
13501
|
+
// part of a view hierarchy and should be removed
|
13502
|
+
// from its parent.
|
13503
|
+
if (get(view, 'parentView')) {
|
13504
|
+
view.removeFromParent();
|
13505
|
+
} else {
|
13506
|
+
|
13507
|
+
// Otherwise, the view is a "root view" and
|
13508
|
+
// was appended directly to the DOM.
|
13509
|
+
view.remove();
|
13510
|
+
}
|
13004
13511
|
}
|
13005
13512
|
}
|
13006
13513
|
});
|
13007
13514
|
|
13008
|
-
|
13009
13515
|
})({});
|
13010
13516
|
|
13011
13517
|
|
13012
13518
|
(function(exports) {
|
13013
13519
|
// ==========================================================================
|
13014
|
-
// Project: Ember
|
13520
|
+
// Project: Ember Statecharts
|
13015
13521
|
// Copyright: ©2011 Living Social Inc. and contributors.
|
13016
13522
|
// License: Licensed under MIT license (see license.js)
|
13017
13523
|
// ==========================================================================
|
@@ -13437,6 +13943,17 @@ Ember.ViewState = Ember.State.extend({
|
|
13437
13943
|
// License: Licensed under MIT license (see license.js)
|
13438
13944
|
// ==========================================================================
|
13439
13945
|
/*globals Handlebars */
|
13946
|
+
/**
|
13947
|
+
@namespace
|
13948
|
+
@name Handlebars
|
13949
|
+
@private
|
13950
|
+
*/
|
13951
|
+
|
13952
|
+
/**
|
13953
|
+
@namespace
|
13954
|
+
@name Handlebars.helpers
|
13955
|
+
@description Helpers for Handlebars templates
|
13956
|
+
*/
|
13440
13957
|
|
13441
13958
|
/**
|
13442
13959
|
@class
|
@@ -13462,12 +13979,6 @@ Ember.ViewState = Ember.State.extend({
|
|
13462
13979
|
Note that you won't usually need to use Ember.Handlebars yourself. Instead, use
|
13463
13980
|
Ember.View, which takes care of integration into the view layer for you.
|
13464
13981
|
*/
|
13465
|
-
/**
|
13466
|
-
@namespace
|
13467
|
-
|
13468
|
-
Ember Handlebars is an extension to Handlebars that makes the built-in
|
13469
|
-
Handlebars helpers and {{mustaches}} binding-aware.
|
13470
|
-
*/
|
13471
13982
|
Ember.Handlebars = Ember.create(Handlebars);
|
13472
13983
|
|
13473
13984
|
Ember.Handlebars.helpers = Ember.create(Handlebars.helpers);
|
@@ -13511,7 +14022,7 @@ Ember.Handlebars.Compiler.prototype.mustache = function(mustache) {
|
|
13511
14022
|
if (mustache.params.length || mustache.hash) {
|
13512
14023
|
return Handlebars.Compiler.prototype.mustache.call(this, mustache);
|
13513
14024
|
} else {
|
13514
|
-
var id = new Handlebars.AST.IdNode(['
|
14025
|
+
var id = new Handlebars.AST.IdNode(['_triageMustache']);
|
13515
14026
|
|
13516
14027
|
// Update the mustache node to include a hash value indicating whether the original node
|
13517
14028
|
// was escaped. This will allow us to properly escape values when the underlying value
|
@@ -13525,6 +14036,19 @@ Ember.Handlebars.Compiler.prototype.mustache = function(mustache) {
|
|
13525
14036
|
}
|
13526
14037
|
};
|
13527
14038
|
|
14039
|
+
/**
|
14040
|
+
Used for precompilation of Ember Handlebars templates. This will not be used during normal
|
14041
|
+
app execution.
|
14042
|
+
|
14043
|
+
@param {String} string The template to precompile
|
14044
|
+
*/
|
14045
|
+
Ember.Handlebars.precompile = function(string) {
|
14046
|
+
var ast = Handlebars.parse(string);
|
14047
|
+
var options = { data: true, stringParams: true };
|
14048
|
+
var environment = new Ember.Handlebars.Compiler().compile(ast, options);
|
14049
|
+
return new Ember.Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true);
|
14050
|
+
};
|
14051
|
+
|
13528
14052
|
/**
|
13529
14053
|
The entry point for Ember Handlebars. This replaces the default Handlebars.compile and turns on
|
13530
14054
|
template-local data and String parameters.
|
@@ -13540,6 +14064,21 @@ Ember.Handlebars.compile = function(string) {
|
|
13540
14064
|
return Handlebars.template(templateSpec);
|
13541
14065
|
};
|
13542
14066
|
|
14067
|
+
/**
|
14068
|
+
Lookup both on root and on window
|
14069
|
+
|
14070
|
+
@param {Object} root The object to look up the property on
|
14071
|
+
@param {String} path The path to be lookedup
|
14072
|
+
*/
|
14073
|
+
Ember.Handlebars.getPath = function(root, path) {
|
14074
|
+
// TODO: Remove this `false` when the `getPath` globals support is removed
|
14075
|
+
var value = Ember.getPath(root, path, false);
|
14076
|
+
if (value === undefined && root !== window && Ember.isGlobalPath(path)) {
|
14077
|
+
value = Ember.getPath(window, path);
|
14078
|
+
}
|
14079
|
+
return value;
|
14080
|
+
};
|
14081
|
+
|
13543
14082
|
/**
|
13544
14083
|
Registers a helper in Handlebars that will be called if no property with the
|
13545
14084
|
given name can be found on the current context object, and no helper with
|
@@ -13609,11 +14148,11 @@ Ember.Checkbox = Ember.View.extend({
|
|
13609
14148
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
13610
14149
|
// License: Licensed under MIT license (see license.js)
|
13611
14150
|
// ==========================================================================
|
13612
|
-
/** @class */
|
13613
|
-
|
13614
14151
|
var get = Ember.get, set = Ember.set;
|
13615
14152
|
|
13616
|
-
|
14153
|
+
/** @class */
|
14154
|
+
Ember.TextSupport = Ember.Mixin.create(
|
14155
|
+
/** @scope Ember.TextSupport.prototype */ {
|
13617
14156
|
|
13618
14157
|
value: "",
|
13619
14158
|
|
@@ -13626,17 +14165,14 @@ Ember.TextSupport = Ember.Mixin.create({
|
|
13626
14165
|
|
13627
14166
|
focusOut: function(event) {
|
13628
14167
|
this._elementValueDidChange();
|
13629
|
-
return false;
|
13630
14168
|
},
|
13631
14169
|
|
13632
14170
|
change: function(event) {
|
13633
14171
|
this._elementValueDidChange();
|
13634
|
-
return false;
|
13635
14172
|
},
|
13636
14173
|
|
13637
14174
|
keyUp: function(event) {
|
13638
14175
|
this.interpretKeyEvents(event);
|
13639
|
-
return false;
|
13640
14176
|
},
|
13641
14177
|
|
13642
14178
|
/**
|
@@ -13651,7 +14187,7 @@ Ember.TextSupport = Ember.Mixin.create({
|
|
13651
14187
|
},
|
13652
14188
|
|
13653
14189
|
_elementValueDidChange: function() {
|
13654
|
-
set(this, 'value', this.$().val()
|
14190
|
+
set(this, 'value', this.$().val());
|
13655
14191
|
}
|
13656
14192
|
|
13657
14193
|
});
|
@@ -13670,10 +14206,12 @@ Ember.TextSupport.KEY_EVENTS = {
|
|
13670
14206
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
13671
14207
|
// License: Licensed under MIT license (see license.js)
|
13672
14208
|
// ==========================================================================
|
13673
|
-
/** @class */
|
13674
|
-
|
13675
14209
|
var get = Ember.get, set = Ember.set;
|
13676
14210
|
|
14211
|
+
/**
|
14212
|
+
@class
|
14213
|
+
@extends Ember.TextSupport
|
14214
|
+
*/
|
13677
14215
|
Ember.TextField = Ember.View.extend(Ember.TextSupport,
|
13678
14216
|
/** @scope Ember.TextField.prototype */ {
|
13679
14217
|
|
@@ -13681,14 +14219,7 @@ Ember.TextField = Ember.View.extend(Ember.TextSupport,
|
|
13681
14219
|
|
13682
14220
|
tagName: "input",
|
13683
14221
|
attributeBindings: ['type', 'value'],
|
13684
|
-
type: "text"
|
13685
|
-
|
13686
|
-
/**
|
13687
|
-
@private
|
13688
|
-
*/
|
13689
|
-
_updateElementValue: function() {
|
13690
|
-
this.$().val(get(this, 'value'));
|
13691
|
-
}
|
14222
|
+
type: "text"
|
13692
14223
|
|
13693
14224
|
});
|
13694
14225
|
|
@@ -13708,11 +14239,26 @@ Ember.Button = Ember.View.extend(Ember.TargetActionSupport, {
|
|
13708
14239
|
classNameBindings: ['isActive'],
|
13709
14240
|
|
13710
14241
|
tagName: 'button',
|
13711
|
-
|
13712
|
-
type: 'button',
|
13713
|
-
disabled: false,
|
14242
|
+
|
13714
14243
|
propagateEvents: false,
|
13715
14244
|
|
14245
|
+
attributeBindings: ['type', 'disabled', 'href'],
|
14246
|
+
|
14247
|
+
// Defaults to 'button' if tagName is 'input' or 'button'
|
14248
|
+
type: Ember.computed(function(key, value) {
|
14249
|
+
var tagName = this.get('tagName');
|
14250
|
+
if (value !== undefined) { this._type = value; }
|
14251
|
+
if (this._type !== undefined) { return this._type; }
|
14252
|
+
if (tagName === 'input' || tagName === 'button') { return 'button'; }
|
14253
|
+
}).property('tagName').cacheable(),
|
14254
|
+
|
14255
|
+
disabled: false,
|
14256
|
+
|
14257
|
+
// Allow 'a' tags to act like buttons
|
14258
|
+
href: Ember.computed(function() {
|
14259
|
+
return this.get('tagName') === 'a' ? '#' : null;
|
14260
|
+
}).property('tagName').cacheable(),
|
14261
|
+
|
13716
14262
|
mouseDown: function() {
|
13717
14263
|
if (!get(this, 'disabled')) {
|
13718
14264
|
set(this, 'isActive', true);
|
@@ -13738,7 +14284,6 @@ Ember.Button = Ember.View.extend(Ember.TargetActionSupport, {
|
|
13738
14284
|
|
13739
14285
|
mouseUp: function(event) {
|
13740
14286
|
if (get(this, 'isActive')) {
|
13741
|
-
|
13742
14287
|
// Actually invoke the button's target and action.
|
13743
14288
|
// This method comes from the Ember.TargetActionSupport mixin.
|
13744
14289
|
this.triggerAction();
|
@@ -13750,16 +14295,30 @@ Ember.Button = Ember.View.extend(Ember.TargetActionSupport, {
|
|
13750
14295
|
return get(this, 'propagateEvents');
|
13751
14296
|
},
|
13752
14297
|
|
14298
|
+
keyDown: function(event) {
|
14299
|
+
// Handle space or enter
|
14300
|
+
if (event.keyCode === 13 || event.keyCode === 32) {
|
14301
|
+
this.mouseDown();
|
14302
|
+
}
|
14303
|
+
},
|
14304
|
+
|
14305
|
+
keyUp: function(event) {
|
14306
|
+
// Handle space or enter
|
14307
|
+
if (event.keyCode === 13 || event.keyCode === 32) {
|
14308
|
+
this.mouseUp();
|
14309
|
+
}
|
14310
|
+
},
|
14311
|
+
|
13753
14312
|
// TODO: Handle proper touch behavior. Including should make inactive when
|
13754
14313
|
// finger moves more than 20x outside of the edge of the button (vs mouse
|
13755
14314
|
// which goes inactive as soon as mouse goes out of edges.)
|
13756
14315
|
|
13757
14316
|
touchStart: function(touch) {
|
13758
|
-
this.mouseDown(touch);
|
14317
|
+
return this.mouseDown(touch);
|
13759
14318
|
},
|
13760
14319
|
|
13761
14320
|
touchEnd: function(touch) {
|
13762
|
-
this.mouseUp(touch);
|
14321
|
+
return this.mouseUp(touch);
|
13763
14322
|
}
|
13764
14323
|
});
|
13765
14324
|
|
@@ -13772,11 +14331,14 @@ Ember.Button = Ember.View.extend(Ember.TargetActionSupport, {
|
|
13772
14331
|
// Copyright: ©2011 Strobe Inc. and contributors.
|
13773
14332
|
// License: Licensed under MIT license (see license.js)
|
13774
14333
|
// ==========================================================================
|
13775
|
-
/** @class */
|
13776
|
-
|
13777
14334
|
var get = Ember.get, set = Ember.set;
|
13778
14335
|
|
13779
|
-
|
14336
|
+
/**
|
14337
|
+
@class
|
14338
|
+
@extends Ember.TextSupport
|
14339
|
+
*/
|
14340
|
+
Ember.TextArea = Ember.View.extend(Ember.TextSupport,
|
14341
|
+
/** @scope Ember.TextArea.prototype */ {
|
13780
14342
|
|
13781
14343
|
classNames: ['ember-text-area'],
|
13782
14344
|
|
@@ -13808,11 +14370,11 @@ Ember.TabContainerView = Ember.View.extend();
|
|
13808
14370
|
var get = Ember.get, getPath = Ember.getPath;
|
13809
14371
|
|
13810
14372
|
Ember.TabPaneView = Ember.View.extend({
|
13811
|
-
tabsContainer:
|
14373
|
+
tabsContainer: Ember.computed(function() {
|
13812
14374
|
return this.nearestInstanceOf(Ember.TabContainerView);
|
13813
14375
|
}).property(),
|
13814
14376
|
|
13815
|
-
isVisible:
|
14377
|
+
isVisible: Ember.computed(function() {
|
13816
14378
|
return get(this, 'viewName') === getPath(this, 'tabsContainer.currentView');
|
13817
14379
|
}).property('tabsContainer.currentView')
|
13818
14380
|
});
|
@@ -13824,7 +14386,7 @@ Ember.TabPaneView = Ember.View.extend({
|
|
13824
14386
|
var get = Ember.get, setPath = Ember.setPath;
|
13825
14387
|
|
13826
14388
|
Ember.TabView = Ember.View.extend({
|
13827
|
-
tabsContainer:
|
14389
|
+
tabsContainer: Ember.computed(function() {
|
13828
14390
|
return this.nearestInstanceOf(Ember.TabContainerView);
|
13829
14391
|
}).property(),
|
13830
14392
|
|
@@ -13840,6 +14402,93 @@ Ember.TabView = Ember.View.extend({
|
|
13840
14402
|
})({});
|
13841
14403
|
|
13842
14404
|
|
14405
|
+
(function(exports) {
|
14406
|
+
var set = Ember.set, get = Ember.get, getPath = Ember.getPath;
|
14407
|
+
|
14408
|
+
Ember.Select = Ember.View.extend({
|
14409
|
+
tagName: 'select',
|
14410
|
+
template: Ember.Handlebars.compile(
|
14411
|
+
'{{#if prompt}}<option>{{prompt}}</option>{{/if}}' +
|
14412
|
+
'{{#each content}}{{view Ember.SelectOption contentBinding="this"}}{{/each}}'
|
14413
|
+
),
|
14414
|
+
|
14415
|
+
content: null,
|
14416
|
+
selection: null,
|
14417
|
+
prompt: null,
|
14418
|
+
|
14419
|
+
optionLabelPath: 'content',
|
14420
|
+
optionValuePath: 'content',
|
14421
|
+
|
14422
|
+
|
14423
|
+
didInsertElement: function() {
|
14424
|
+
var selection = get(this, 'selection');
|
14425
|
+
|
14426
|
+
if (selection) { this.selectionDidChange(); }
|
14427
|
+
|
14428
|
+
this.change();
|
14429
|
+
},
|
14430
|
+
|
14431
|
+
change: function() {
|
14432
|
+
var selectedIndex = this.$()[0].selectedIndex,
|
14433
|
+
content = get(this, 'content'),
|
14434
|
+
prompt = get(this, 'prompt');
|
14435
|
+
|
14436
|
+
if (!content) { return; }
|
14437
|
+
if (prompt && selectedIndex === 0) { set(this, 'selection', null); return; }
|
14438
|
+
|
14439
|
+
if (prompt) { selectedIndex -= 1; }
|
14440
|
+
set(this, 'selection', content.objectAt(selectedIndex));
|
14441
|
+
},
|
14442
|
+
|
14443
|
+
selectionDidChange: Ember.observer(function() {
|
14444
|
+
var el = this.$()[0],
|
14445
|
+
content = get(this, 'content'),
|
14446
|
+
selection = get(this, 'selection'),
|
14447
|
+
selectionIndex = content.indexOf(selection),
|
14448
|
+
prompt = get(this, 'prompt');
|
14449
|
+
|
14450
|
+
if (prompt) { selectionIndex += 1; }
|
14451
|
+
if (el) { el.selectedIndex = selectionIndex; }
|
14452
|
+
}, 'selection')
|
14453
|
+
});
|
14454
|
+
|
14455
|
+
Ember.SelectOption = Ember.View.extend({
|
14456
|
+
tagName: 'option',
|
14457
|
+
template: Ember.Handlebars.compile("{{label}}"),
|
14458
|
+
attributeBindings: ['value'],
|
14459
|
+
|
14460
|
+
init: function() {
|
14461
|
+
this.labelPathDidChange();
|
14462
|
+
this.valuePathDidChange();
|
14463
|
+
|
14464
|
+
this._super();
|
14465
|
+
},
|
14466
|
+
|
14467
|
+
labelPathDidChange: Ember.observer(function() {
|
14468
|
+
var labelPath = getPath(this, 'parentView.optionLabelPath');
|
14469
|
+
|
14470
|
+
if (!labelPath) { return; }
|
14471
|
+
|
14472
|
+
Ember.defineProperty(this, 'label', Ember.computed(function() {
|
14473
|
+
return getPath(this, labelPath);
|
14474
|
+
}).property(labelPath).cacheable());
|
14475
|
+
}, 'parentView.optionLabelPath'),
|
14476
|
+
|
14477
|
+
valuePathDidChange: Ember.observer(function() {
|
14478
|
+
var valuePath = getPath(this, 'parentView.optionValuePath');
|
14479
|
+
|
14480
|
+
if (!valuePath) { return; }
|
14481
|
+
|
14482
|
+
Ember.defineProperty(this, 'value', Ember.computed(function() {
|
14483
|
+
return getPath(this, valuePath);
|
14484
|
+
}).property(valuePath).cacheable());
|
14485
|
+
}, 'parentView.optionValuePath')
|
14486
|
+
});
|
14487
|
+
|
14488
|
+
|
14489
|
+
})({});
|
14490
|
+
|
14491
|
+
|
13843
14492
|
(function(exports) {
|
13844
14493
|
// ==========================================================================
|
13845
14494
|
// Project: Ember Handlebar Views
|
@@ -13935,7 +14584,7 @@ Ember.Metamorph = Ember.Mixin.create({
|
|
13935
14584
|
// ==========================================================================
|
13936
14585
|
/*globals Handlebars */
|
13937
14586
|
|
13938
|
-
var get = Ember.get, set = Ember.set, getPath = Ember.getPath;
|
14587
|
+
var get = Ember.get, set = Ember.set, getPath = Ember.Handlebars.getPath;
|
13939
14588
|
/**
|
13940
14589
|
@ignore
|
13941
14590
|
@private
|
@@ -14006,6 +14655,29 @@ Ember._BindableSpanView = Ember.View.extend(Ember.Metamorph,
|
|
14006
14655
|
*/
|
14007
14656
|
property: null,
|
14008
14657
|
|
14658
|
+
normalizedValue: Ember.computed(function() {
|
14659
|
+
var property = get(this, 'property'),
|
14660
|
+
context = get(this, 'previousContext'),
|
14661
|
+
valueNormalizer = get(this, 'valueNormalizerFunc'),
|
14662
|
+
result;
|
14663
|
+
|
14664
|
+
// Use the current context as the result if no
|
14665
|
+
// property is provided.
|
14666
|
+
if (property === '') {
|
14667
|
+
result = context;
|
14668
|
+
} else {
|
14669
|
+
result = getPath(context, property);
|
14670
|
+
}
|
14671
|
+
|
14672
|
+
return valueNormalizer ? valueNormalizer(result) : result;
|
14673
|
+
}).property('property', 'previousContext', 'valueNormalizerFunc'),
|
14674
|
+
|
14675
|
+
rerenderIfNeeded: function() {
|
14676
|
+
if (!get(this, 'isDestroyed') && get(this, 'normalizedValue') !== this._lastNormalizedValue) {
|
14677
|
+
this.rerender();
|
14678
|
+
}
|
14679
|
+
},
|
14680
|
+
|
14009
14681
|
/**
|
14010
14682
|
Determines which template to invoke, sets up the correct state based on
|
14011
14683
|
that logic, then invokes the default Ember.View `render` implementation.
|
@@ -14028,23 +14700,14 @@ Ember._BindableSpanView = Ember.View.extend(Ember.Metamorph,
|
|
14028
14700
|
var escape = get(this, 'isEscaped');
|
14029
14701
|
|
14030
14702
|
var shouldDisplay = get(this, 'shouldDisplayFunc'),
|
14031
|
-
property = get(this, 'property'),
|
14032
14703
|
preserveContext = get(this, 'preserveContext'),
|
14033
14704
|
context = get(this, 'previousContext');
|
14034
14705
|
|
14035
14706
|
var inverseTemplate = get(this, 'inverseTemplate'),
|
14036
14707
|
displayTemplate = get(this, 'displayTemplate');
|
14037
14708
|
|
14038
|
-
var result;
|
14039
|
-
|
14040
|
-
|
14041
|
-
// Use the current context as the result if no
|
14042
|
-
// property is provided.
|
14043
|
-
if (property === '') {
|
14044
|
-
result = context;
|
14045
|
-
} else {
|
14046
|
-
result = getPath(context, property);
|
14047
|
-
}
|
14709
|
+
var result = get(this, 'normalizedValue');
|
14710
|
+
this._lastNormalizedValue = result;
|
14048
14711
|
|
14049
14712
|
// First, test the conditional to see if we should
|
14050
14713
|
// render the template or not.
|
@@ -14095,12 +14758,15 @@ Ember._BindableSpanView = Ember.View.extend(Ember.Metamorph,
|
|
14095
14758
|
// License: Licensed under MIT license (see license.js)
|
14096
14759
|
// ==========================================================================
|
14097
14760
|
/*globals Handlebars */
|
14098
|
-
var get = Ember.get, getPath = Ember.getPath, set = Ember.set, fmt = Ember.String.fmt;
|
14761
|
+
var get = Ember.get, getPath = Ember.Handlebars.getPath, set = Ember.set, fmt = Ember.String.fmt;
|
14762
|
+
|
14763
|
+
var EmberHandlebars = Ember.Handlebars, helpers = EmberHandlebars.helpers;
|
14764
|
+
var helpers = EmberHandlebars.helpers;
|
14099
14765
|
|
14100
14766
|
(function() {
|
14101
14767
|
// Binds a property into the DOM. This will create a hook in DOM that the
|
14102
|
-
// KVO system will look for and
|
14103
|
-
var bind = function(property, options, preserveContext, shouldDisplay) {
|
14768
|
+
// KVO system will look for and update if the property changes.
|
14769
|
+
var bind = function(property, options, preserveContext, shouldDisplay, valueNormalizer) {
|
14104
14770
|
var data = options.data,
|
14105
14771
|
fn = options.fn,
|
14106
14772
|
inverse = options.inverse,
|
@@ -14115,6 +14781,7 @@ var get = Ember.get, getPath = Ember.getPath, set = Ember.set, fmt = Ember.Strin
|
|
14115
14781
|
var bindView = view.createChildView(Ember._BindableSpanView, {
|
14116
14782
|
preserveContext: preserveContext,
|
14117
14783
|
shouldDisplayFunc: shouldDisplay,
|
14784
|
+
valueNormalizerFunc: valueNormalizer,
|
14118
14785
|
displayTemplate: fn,
|
14119
14786
|
inverseTemplate: inverse,
|
14120
14787
|
property: property,
|
@@ -14124,15 +14791,9 @@ var get = Ember.get, getPath = Ember.getPath, set = Ember.set, fmt = Ember.Strin
|
|
14124
14791
|
|
14125
14792
|
view.appendChild(bindView);
|
14126
14793
|
|
14127
|
-
|
14128
|
-
|
14129
|
-
|
14130
|
-
// Double check since sometimes the view gets destroyed after this observer is already queued
|
14131
|
-
if (!get(bindView, 'isDestroyed')) { bindView.rerender(); }
|
14132
|
-
};
|
14133
|
-
|
14134
|
-
invoker = function() {
|
14135
|
-
Ember.run.once(observer);
|
14794
|
+
/** @private */
|
14795
|
+
var observer = function() {
|
14796
|
+
Ember.run.once(bindView, 'rerenderIfNeeded');
|
14136
14797
|
};
|
14137
14798
|
|
14138
14799
|
// Observes the given property on the context and
|
@@ -14140,7 +14801,7 @@ var get = Ember.get, getPath = Ember.getPath, set = Ember.set, fmt = Ember.Strin
|
|
14140
14801
|
// is an empty string, we are printing the current context
|
14141
14802
|
// object ({{this}}) so updating it is not our responsibility.
|
14142
14803
|
if (property !== '') {
|
14143
|
-
Ember.addObserver(ctx, property,
|
14804
|
+
Ember.addObserver(ctx, property, observer);
|
14144
14805
|
}
|
14145
14806
|
} else {
|
14146
14807
|
// The object is not observable, so just render it out and
|
@@ -14149,6 +14810,30 @@ var get = Ember.get, getPath = Ember.getPath, set = Ember.set, fmt = Ember.Strin
|
|
14149
14810
|
}
|
14150
14811
|
};
|
14151
14812
|
|
14813
|
+
/**
|
14814
|
+
'_triageMustache' is used internally select between a binding and helper for
|
14815
|
+
the given context. Until this point, it would be hard to determine if the
|
14816
|
+
mustache is a property reference or a regular helper reference. This triage
|
14817
|
+
helper resolves that.
|
14818
|
+
|
14819
|
+
This would not be typically invoked by directly.
|
14820
|
+
|
14821
|
+
@private
|
14822
|
+
@name Handlebars.helpers._triageMustache
|
14823
|
+
@param {String} property Property/helperID to triage
|
14824
|
+
@param {Function} fn Context to provide for rendering
|
14825
|
+
@returns {String} HTML string
|
14826
|
+
*/
|
14827
|
+
EmberHandlebars.registerHelper('_triageMustache', function(property, fn) {
|
14828
|
+
ember_assert("You cannot pass more than one argument to the _triageMustache helper", arguments.length <= 2);
|
14829
|
+
if (helpers[property]) {
|
14830
|
+
return helpers[property].call(this, fn);
|
14831
|
+
}
|
14832
|
+
else {
|
14833
|
+
return helpers.bind.apply(this, arguments);
|
14834
|
+
}
|
14835
|
+
});
|
14836
|
+
|
14152
14837
|
/**
|
14153
14838
|
`bind` can be used to display a value, then update that value if it
|
14154
14839
|
changes. For example, if you wanted to print the `title` property of
|
@@ -14169,7 +14854,7 @@ var get = Ember.get, getPath = Ember.getPath, set = Ember.set, fmt = Ember.Strin
|
|
14169
14854
|
@param {Function} fn Context to provide for rendering
|
14170
14855
|
@returns {String} HTML string
|
14171
14856
|
*/
|
14172
|
-
|
14857
|
+
EmberHandlebars.registerHelper('bind', function(property, fn) {
|
14173
14858
|
ember_assert("You cannot pass more than one argument to the bind helper", arguments.length <= 2);
|
14174
14859
|
|
14175
14860
|
var context = (fn.contexts && fn.contexts[0]) || this;
|
@@ -14193,16 +14878,17 @@ var get = Ember.get, getPath = Ember.getPath, set = Ember.set, fmt = Ember.Strin
|
|
14193
14878
|
@param {Function} fn Context to provide for rendering
|
14194
14879
|
@returns {String} HTML string
|
14195
14880
|
*/
|
14196
|
-
|
14881
|
+
EmberHandlebars.registerHelper('boundIf', function(property, fn) {
|
14197
14882
|
var context = (fn.contexts && fn.contexts[0]) || this;
|
14198
|
-
|
14199
|
-
return bind.call(context, property, fn, true, function(result) {
|
14883
|
+
var func = function(result) {
|
14200
14884
|
if (Ember.typeOf(result) === 'array') {
|
14201
14885
|
return get(result, 'length') !== 0;
|
14202
14886
|
} else {
|
14203
14887
|
return !!result;
|
14204
14888
|
}
|
14205
|
-
}
|
14889
|
+
};
|
14890
|
+
|
14891
|
+
return bind.call(context, property, fn, true, func, func);
|
14206
14892
|
});
|
14207
14893
|
})();
|
14208
14894
|
|
@@ -14212,11 +14898,11 @@ var get = Ember.get, getPath = Ember.getPath, set = Ember.set, fmt = Ember.Strin
|
|
14212
14898
|
@param {Hash} options
|
14213
14899
|
@returns {String} HTML string
|
14214
14900
|
*/
|
14215
|
-
|
14901
|
+
EmberHandlebars.registerHelper('with', function(context, options) {
|
14216
14902
|
ember_assert("You must pass exactly one argument to the with helper", arguments.length == 2);
|
14217
14903
|
ember_assert("You must pass a block to the with helper", options.fn && options.fn !== Handlebars.VM.noop);
|
14218
14904
|
|
14219
|
-
return
|
14905
|
+
return helpers.bind.call(options.contexts[0], context, options);
|
14220
14906
|
});
|
14221
14907
|
|
14222
14908
|
|
@@ -14226,11 +14912,11 @@ Ember.Handlebars.registerHelper('with', function(context, options) {
|
|
14226
14912
|
@param {Hash} options
|
14227
14913
|
@returns {String} HTML string
|
14228
14914
|
*/
|
14229
|
-
|
14915
|
+
EmberHandlebars.registerHelper('if', function(context, options) {
|
14230
14916
|
ember_assert("You must pass exactly one argument to the if helper", arguments.length == 2);
|
14231
14917
|
ember_assert("You must pass a block to the if helper", options.fn && options.fn !== Handlebars.VM.noop);
|
14232
14918
|
|
14233
|
-
return
|
14919
|
+
return helpers.boundIf.call(options.contexts[0], context, options);
|
14234
14920
|
});
|
14235
14921
|
|
14236
14922
|
/**
|
@@ -14239,7 +14925,7 @@ Ember.Handlebars.registerHelper('if', function(context, options) {
|
|
14239
14925
|
@param {Hash} options
|
14240
14926
|
@returns {String} HTML string
|
14241
14927
|
*/
|
14242
|
-
|
14928
|
+
EmberHandlebars.registerHelper('unless', function(context, options) {
|
14243
14929
|
ember_assert("You must pass exactly one argument to the unless helper", arguments.length == 2);
|
14244
14930
|
ember_assert("You must pass a block to the unless helper", options.fn && options.fn !== Handlebars.VM.noop);
|
14245
14931
|
|
@@ -14248,7 +14934,7 @@ Ember.Handlebars.registerHelper('unless', function(context, options) {
|
|
14248
14934
|
options.fn = inverse;
|
14249
14935
|
options.inverse = fn;
|
14250
14936
|
|
14251
|
-
return
|
14937
|
+
return helpers.boundIf.call(options.contexts[0], context, options);
|
14252
14938
|
});
|
14253
14939
|
|
14254
14940
|
/**
|
@@ -14261,7 +14947,7 @@ Ember.Handlebars.registerHelper('unless', function(context, options) {
|
|
14261
14947
|
@param {Hash} options
|
14262
14948
|
@returns {String} HTML string
|
14263
14949
|
*/
|
14264
|
-
|
14950
|
+
EmberHandlebars.registerHelper('bindAttr', function(options) {
|
14265
14951
|
|
14266
14952
|
var attrs = options.hash;
|
14267
14953
|
|
@@ -14279,7 +14965,7 @@ Ember.Handlebars.registerHelper('bindAttr', function(options) {
|
|
14279
14965
|
// Handle classes differently, as we can bind multiple classes
|
14280
14966
|
var classBindings = attrs['class'];
|
14281
14967
|
if (classBindings !== null && classBindings !== undefined) {
|
14282
|
-
var classResults =
|
14968
|
+
var classResults = EmberHandlebars.bindClasses(this, classBindings, view, dataId);
|
14283
14969
|
ret.push('class="' + classResults.join(' ') + '"');
|
14284
14970
|
delete attrs['class'];
|
14285
14971
|
}
|
@@ -14299,6 +14985,7 @@ Ember.Handlebars.registerHelper('bindAttr', function(options) {
|
|
14299
14985
|
|
14300
14986
|
var observer, invoker;
|
14301
14987
|
|
14988
|
+
/** @private */
|
14302
14989
|
observer = function observer() {
|
14303
14990
|
var result = getPath(ctx, property);
|
14304
14991
|
|
@@ -14315,22 +15002,10 @@ Ember.Handlebars.registerHelper('bindAttr', function(options) {
|
|
14315
15002
|
return;
|
14316
15003
|
}
|
14317
15004
|
|
14318
|
-
|
14319
|
-
|
14320
|
-
// A false result will remove the attribute from the element. This is
|
14321
|
-
// to support attributes such as disabled, whose presence is meaningful.
|
14322
|
-
if (result === false && currentValue) {
|
14323
|
-
elem.removeAttr(attr);
|
14324
|
-
|
14325
|
-
// Likewise, a true result will set the attribute's name as the value.
|
14326
|
-
} else if (result === true && currentValue !== attr) {
|
14327
|
-
elem.attr(attr, attr);
|
14328
|
-
|
14329
|
-
} else if (currentValue !== result) {
|
14330
|
-
elem.attr(attr, result);
|
14331
|
-
}
|
15005
|
+
Ember.View.applyAttributeBindings(elem, attr, result);
|
14332
15006
|
};
|
14333
15007
|
|
15008
|
+
/** @private */
|
14334
15009
|
invoker = function() {
|
14335
15010
|
Ember.run.once(observer);
|
14336
15011
|
};
|
@@ -14340,21 +15015,19 @@ Ember.Handlebars.registerHelper('bindAttr', function(options) {
|
|
14340
15015
|
// unique data id and update the attribute to the new value.
|
14341
15016
|
Ember.addObserver(ctx, property, invoker);
|
14342
15017
|
|
14343
|
-
//
|
14344
|
-
|
14345
|
-
value = attr;
|
14346
|
-
}
|
15018
|
+
// if this changes, also change the logic in ember-views/lib/views/view.js
|
15019
|
+
var type = typeof value;
|
14347
15020
|
|
14348
|
-
|
14349
|
-
if (value !== false) {
|
14350
|
-
// Return the current value, in the form src="foo.jpg"
|
15021
|
+
if ((type === 'string' || (type === 'number' && !isNaN(value)))) {
|
14351
15022
|
ret.push(attr + '="' + value + '"');
|
15023
|
+
} else if (value && type === 'boolean') {
|
15024
|
+
ret.push(attr + '="' + attr + '"');
|
14352
15025
|
}
|
14353
15026
|
}, this);
|
14354
15027
|
|
14355
15028
|
// Add the unique identifier
|
14356
15029
|
ret.push('data-bindAttr-' + dataId + '="' + dataId + '"');
|
14357
|
-
return new
|
15030
|
+
return new EmberHandlebars.SafeString(ret.join(' '));
|
14358
15031
|
});
|
14359
15032
|
|
14360
15033
|
/**
|
@@ -14383,7 +15056,7 @@ Ember.Handlebars.registerHelper('bindAttr', function(options) {
|
|
14383
15056
|
|
14384
15057
|
@returns {Array} An array of class names to add
|
14385
15058
|
*/
|
14386
|
-
|
15059
|
+
EmberHandlebars.bindClasses = function(context, classBindings, view, bindAttrId) {
|
14387
15060
|
var ret = [], newClass, value, elem;
|
14388
15061
|
|
14389
15062
|
// Helper method to retrieve the property from the context and
|
@@ -14391,9 +15064,10 @@ Ember.Handlebars.bindClasses = function(context, classBindings, view, bindAttrId
|
|
14391
15064
|
// a Boolean or not.
|
14392
15065
|
var classStringForProperty = function(property) {
|
14393
15066
|
var split = property.split(':'),
|
14394
|
-
property = split[0],
|
14395
15067
|
className = split[1];
|
14396
15068
|
|
15069
|
+
property = split[0];
|
15070
|
+
|
14397
15071
|
var val = getPath(context, property);
|
14398
15072
|
|
14399
15073
|
// If value is a Boolean and true, return the dasherized property
|
@@ -14432,6 +15106,7 @@ Ember.Handlebars.bindClasses = function(context, classBindings, view, bindAttrId
|
|
14432
15106
|
|
14433
15107
|
// Set up an observer on the context. If the property changes, toggle the
|
14434
15108
|
// class name.
|
15109
|
+
/** @private */
|
14435
15110
|
observer = function() {
|
14436
15111
|
// Get the current value of the property
|
14437
15112
|
newClass = classStringForProperty(binding);
|
@@ -14458,6 +15133,7 @@ Ember.Handlebars.bindClasses = function(context, classBindings, view, bindAttrId
|
|
14458
15133
|
}
|
14459
15134
|
};
|
14460
15135
|
|
15136
|
+
/** @private */
|
14461
15137
|
invoker = function() {
|
14462
15138
|
Ember.run.once(observer);
|
14463
15139
|
};
|
@@ -14540,15 +15216,10 @@ Ember.Handlebars.ViewHelper = Ember.Object.create({
|
|
14540
15216
|
if (Ember.IS_BINDING.test(prop)) {
|
14541
15217
|
path = options[prop];
|
14542
15218
|
if (!Ember.isGlobalPath(path)) {
|
14543
|
-
|
14544
|
-
|
14545
|
-
|
14546
|
-
|
14547
|
-
if (path === 'this') {
|
14548
|
-
options[prop] = 'bindingContext';
|
14549
|
-
} else {
|
14550
|
-
options[prop] = 'bindingContext.'+path;
|
14551
|
-
}
|
15219
|
+
if (path === 'this') {
|
15220
|
+
options[prop] = 'bindingContext';
|
15221
|
+
} else {
|
15222
|
+
options[prop] = 'bindingContext.'+path;
|
14552
15223
|
}
|
14553
15224
|
}
|
14554
15225
|
}
|
@@ -14570,7 +15241,7 @@ Ember.Handlebars.ViewHelper = Ember.Object.create({
|
|
14570
15241
|
newView;
|
14571
15242
|
|
14572
15243
|
if ('string' === typeof path) {
|
14573
|
-
newView = Ember.getPath(thisContext, path);
|
15244
|
+
newView = Ember.Handlebars.getPath(thisContext, path);
|
14574
15245
|
ember_assert("Unable to find view at path '" + path + "'", !!newView);
|
14575
15246
|
} else {
|
14576
15247
|
newView = path;
|
@@ -14622,7 +15293,7 @@ Ember.Handlebars.registerHelper('view', function(path, options) {
|
|
14622
15293
|
/*globals Handlebars ember_assert */
|
14623
15294
|
|
14624
15295
|
// TODO: Don't require all of this module
|
14625
|
-
var get = Ember.get, fmt = Ember.String.fmt;
|
15296
|
+
var get = Ember.get, getPath = Ember.Handlebars.getPath, fmt = Ember.String.fmt;
|
14626
15297
|
|
14627
15298
|
/**
|
14628
15299
|
@name Handlebars.helpers.collection
|
@@ -14647,7 +15318,7 @@ Ember.Handlebars.registerHelper('collection', function(path, options) {
|
|
14647
15318
|
// If passed a path string, convert that into an object.
|
14648
15319
|
// Otherwise, just default to the standard class.
|
14649
15320
|
var collectionClass;
|
14650
|
-
collectionClass = path ?
|
15321
|
+
collectionClass = path ? getPath(this, path) : Ember.CollectionView;
|
14651
15322
|
ember_assert(fmt("%@ #collection: Could not find %@", data.view, path), !!collectionClass);
|
14652
15323
|
|
14653
15324
|
var hash = options.hash, itemHash = {}, match;
|
@@ -14656,7 +15327,7 @@ Ember.Handlebars.registerHelper('collection', function(path, options) {
|
|
14656
15327
|
var itemViewClass, itemViewPath = hash.itemViewClass;
|
14657
15328
|
var collectionPrototype = get(collectionClass, 'proto');
|
14658
15329
|
delete hash.itemViewClass;
|
14659
|
-
itemViewClass = itemViewPath ?
|
15330
|
+
itemViewClass = itemViewPath ? getPath(collectionPrototype, itemViewPath) : collectionPrototype.itemViewClass;
|
14660
15331
|
ember_assert(fmt("%@ #collection: Could not find %@", data.view, itemViewPath), !!itemViewClass);
|
14661
15332
|
|
14662
15333
|
// Go through options passed to the {{collection}} helper and extract options
|
@@ -14714,7 +15385,7 @@ Ember.Handlebars.registerHelper('collection', function(path, options) {
|
|
14714
15385
|
// License: Licensed under MIT license (see license.js)
|
14715
15386
|
// ==========================================================================
|
14716
15387
|
/*globals Handlebars */
|
14717
|
-
var getPath = Ember.getPath;
|
15388
|
+
var getPath = Ember.Handlebars.getPath;
|
14718
15389
|
|
14719
15390
|
/**
|
14720
15391
|
`unbound` allows you to output a property without binding. *Important:* The
|
@@ -14827,6 +15498,64 @@ Ember.Handlebars.registerHelper('template', function(name, options) {
|
|
14827
15498
|
})({});
|
14828
15499
|
|
14829
15500
|
|
15501
|
+
(function(exports) {
|
15502
|
+
var EmberHandlebars = Ember.Handlebars, getPath = Ember.Handlebars.getPath;
|
15503
|
+
|
15504
|
+
var ActionHelper = EmberHandlebars.ActionHelper = {};
|
15505
|
+
|
15506
|
+
ActionHelper.registerAction = function(actionName, eventName, target, view) {
|
15507
|
+
var actionId = (++jQuery.uuid).toString(),
|
15508
|
+
existingHandler = view[eventName],
|
15509
|
+
handler;
|
15510
|
+
|
15511
|
+
if (existingHandler) {
|
15512
|
+
var handler = function(event) {
|
15513
|
+
var ret;
|
15514
|
+
if ($(event.target).closest('[data-ember-action]').attr('data-ember-action') === actionId) {
|
15515
|
+
ret = target[actionName](event);
|
15516
|
+
}
|
15517
|
+
return ret !== false ? existingHandler.call(view, event) : ret;
|
15518
|
+
};
|
15519
|
+
} else {
|
15520
|
+
var handler = function(event) {
|
15521
|
+
if ($(event.target).closest('[data-ember-action]').attr('data-ember-action') === actionId) {
|
15522
|
+
return target[actionName](event);
|
15523
|
+
}
|
15524
|
+
};
|
15525
|
+
}
|
15526
|
+
|
15527
|
+
view[eventName] = handler;
|
15528
|
+
|
15529
|
+
view.reopen({
|
15530
|
+
rerender: function() {
|
15531
|
+
if (existingHandler) {
|
15532
|
+
view[eventName] = existingHandler;
|
15533
|
+
} else {
|
15534
|
+
view[eventName] = null;
|
15535
|
+
}
|
15536
|
+
return this._super();
|
15537
|
+
}
|
15538
|
+
});
|
15539
|
+
|
15540
|
+
return actionId;
|
15541
|
+
};
|
15542
|
+
|
15543
|
+
EmberHandlebars.registerHelper('action', function(actionName, options) {
|
15544
|
+
var hash = options.hash || {},
|
15545
|
+
eventName = options.hash.on || "click",
|
15546
|
+
view = options.data.view,
|
15547
|
+
target;
|
15548
|
+
|
15549
|
+
if (view.isVirtual) { view = view.get('parentView'); }
|
15550
|
+
target = options.hash.target ? getPath(this, options.hash.target) : view;
|
15551
|
+
|
15552
|
+
var actionId = ActionHelper.registerAction(actionName, eventName, target, view);
|
15553
|
+
return new EmberHandlebars.SafeString('data-ember-action="' + actionId + '"');
|
15554
|
+
});
|
15555
|
+
|
15556
|
+
})({});
|
15557
|
+
|
15558
|
+
|
14830
15559
|
(function(exports) {
|
14831
15560
|
// ==========================================================================
|
14832
15561
|
// Project: Ember Handlebar Views
|
@@ -14851,8 +15580,8 @@ Ember.Handlebars.registerHelper('template', function(name, options) {
|
|
14851
15580
|
// with Ember's Handlebars and are suitable for use as a view's template.
|
14852
15581
|
// Those with type="text/x-raw-handlebars" will be compiled with regular
|
14853
15582
|
// Handlebars and are suitable for use in views' computed properties.
|
14854
|
-
Ember.Handlebars.bootstrap = function() {
|
14855
|
-
Ember.$('script[type="text/html"], script[type="text/x-handlebars"], script[type="text/x-raw-handlebars"]')
|
15583
|
+
Ember.Handlebars.bootstrap = function(ctx) {
|
15584
|
+
Ember.$('script[type="text/html"], script[type="text/x-handlebars"], script[type="text/x-raw-handlebars"]', ctx)
|
14856
15585
|
.each(function() {
|
14857
15586
|
// Get a reference to the script tag
|
14858
15587
|
var script = Ember.$(this),
|
@@ -14864,7 +15593,7 @@ Ember.Handlebars.bootstrap = function() {
|
|
14864
15593
|
// id if no name is found.
|
14865
15594
|
templateName = script.attr('data-template-name') || script.attr('id'),
|
14866
15595
|
template = compile(script.html()),
|
14867
|
-
view, viewPath;
|
15596
|
+
view, viewPath, tagName;
|
14868
15597
|
|
14869
15598
|
if (templateName) {
|
14870
15599
|
// For templates which have a name, we save them and then remove them from the DOM
|
@@ -14889,8 +15618,13 @@ Ember.Handlebars.bootstrap = function() {
|
|
14889
15618
|
viewPath = script.attr('data-view');
|
14890
15619
|
view = viewPath ? Ember.getPath(viewPath) : Ember.View;
|
14891
15620
|
|
15621
|
+
// Users can optionally specify a custom tag name to use by setting the
|
15622
|
+
// data-tag-name attribute on the script tag.
|
15623
|
+
tagName = script.attr('data-tag-name');
|
15624
|
+
|
14892
15625
|
view = view.create({
|
14893
|
-
template: template
|
15626
|
+
template: template,
|
15627
|
+
tagName: (tagName) ? tagName : undefined
|
14894
15628
|
});
|
14895
15629
|
|
14896
15630
|
view._insertElementLater(function() {
|
@@ -14903,7 +15637,11 @@ Ember.Handlebars.bootstrap = function() {
|
|
14903
15637
|
});
|
14904
15638
|
};
|
14905
15639
|
|
14906
|
-
Ember.$(document).ready(
|
15640
|
+
Ember.$(document).ready(
|
15641
|
+
function(){
|
15642
|
+
Ember.Handlebars.bootstrap( Ember.$(document) );
|
15643
|
+
}
|
15644
|
+
);
|
14907
15645
|
|
14908
15646
|
})({});
|
14909
15647
|
|