rasputin 0.13.2 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|