pyro 1.0.0.rc2 → 1.0.0.rc3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/pyro +1 -1
- data/lib/pyro.rb +8 -3
- data/pyro.gemspec +3 -3
- data/templates/app/index.erb +11 -11
- data/templates/app/vendor/ember/ember-data.js +1965 -807
- data/templates/app/vendor/ember/ember-data.min.js +16 -0
- data/templates/app/vendor/ember/ember-data.prod.js +7840 -37
- data/templates/app/vendor/ember/ember.js +1049 -520
- data/templates/app/vendor/ember/ember.min.js +20 -0
- data/templates/app/vendor/ember/ember.prod.js +996 -496
- metadata +13 -11
@@ -61,7 +61,7 @@ var define, requireModule;
|
|
61
61
|
|
62
62
|
@class Ember
|
63
63
|
@static
|
64
|
-
@version 1.
|
64
|
+
@version 1.1.2
|
65
65
|
*/
|
66
66
|
|
67
67
|
if ('undefined' === typeof Ember) {
|
@@ -88,10 +88,10 @@ Ember.toString = function() { return "Ember"; };
|
|
88
88
|
/**
|
89
89
|
@property VERSION
|
90
90
|
@type String
|
91
|
-
@default '1.
|
91
|
+
@default '1.1.2'
|
92
92
|
@final
|
93
93
|
*/
|
94
|
-
Ember.VERSION = '1.
|
94
|
+
Ember.VERSION = '1.1.2';
|
95
95
|
|
96
96
|
/**
|
97
97
|
Standard environmental variables. You can define these in a global `ENV`
|
@@ -116,6 +116,27 @@ Ember.ENV = Ember.ENV || ENV;
|
|
116
116
|
|
117
117
|
Ember.config = Ember.config || {};
|
118
118
|
|
119
|
+
/**
|
120
|
+
Hash of enabled Canary features. Add to before creating your application.
|
121
|
+
|
122
|
+
@property FEATURES
|
123
|
+
@type Hash
|
124
|
+
*/
|
125
|
+
|
126
|
+
Ember.FEATURES = {};
|
127
|
+
|
128
|
+
/**
|
129
|
+
Test that a feature is enabled. Parsed by Ember's build tools to leave
|
130
|
+
experimental features out of beta/stable builds.
|
131
|
+
|
132
|
+
@method isEnabled
|
133
|
+
@param {string} feature
|
134
|
+
*/
|
135
|
+
|
136
|
+
Ember.FEATURES.isEnabled = function(feature) {
|
137
|
+
return Ember.FEATURES[feature];
|
138
|
+
};
|
139
|
+
|
119
140
|
// ..........................................................
|
120
141
|
// BOOTSTRAP
|
121
142
|
//
|
@@ -326,7 +347,7 @@ Ember.Logger = {
|
|
326
347
|
|
327
348
|
@method assert
|
328
349
|
@for Ember.Logger
|
329
|
-
@param
|
350
|
+
@param {Boolean} bool Value to test
|
330
351
|
*/
|
331
352
|
assert: consoleMethod('assert') || assertPolyfill
|
332
353
|
};
|
@@ -2074,6 +2095,7 @@ function suspendListeners(obj, eventNames, target, method, callback) {
|
|
2074
2095
|
}
|
2075
2096
|
|
2076
2097
|
var suspendedActions = [],
|
2098
|
+
actionsList = [],
|
2077
2099
|
eventName, actions, i, l;
|
2078
2100
|
|
2079
2101
|
for (i=0, l=eventNames.length; i<l; i++) {
|
@@ -2084,6 +2106,7 @@ function suspendListeners(obj, eventNames, target, method, callback) {
|
|
2084
2106
|
if (actionIndex !== -1) {
|
2085
2107
|
actions[actionIndex+2] |= SUSPENDED;
|
2086
2108
|
suspendedActions.push(actionIndex);
|
2109
|
+
actionsList.push(actions);
|
2087
2110
|
}
|
2088
2111
|
}
|
2089
2112
|
|
@@ -2092,7 +2115,7 @@ function suspendListeners(obj, eventNames, target, method, callback) {
|
|
2092
2115
|
function finalizer() {
|
2093
2116
|
for (var i = 0, l = suspendedActions.length; i < l; i++) {
|
2094
2117
|
var actionIndex = suspendedActions[i];
|
2095
|
-
|
2118
|
+
actionsList[i][actionIndex+2] &= ~SUSPENDED;
|
2096
2119
|
}
|
2097
2120
|
}
|
2098
2121
|
|
@@ -4429,18 +4452,18 @@ function registerComputedWithProperties(name, macro) {
|
|
4429
4452
|
}
|
4430
4453
|
|
4431
4454
|
/**
|
4432
|
-
A computed property that returns true
|
4455
|
+
A computed property that returns true if the value of the dependent
|
4433
4456
|
property is null, an empty string, empty array, or empty function.
|
4434
4457
|
|
4435
4458
|
Note: When using `Ember.computed.empty` to watch an array make sure to
|
4436
|
-
use the `array.
|
4459
|
+
use the `array.[]` syntax so the computed can subscribe to transitions
|
4437
4460
|
from empty to non-empty states.
|
4438
4461
|
|
4439
4462
|
Example
|
4440
4463
|
|
4441
4464
|
```javascript
|
4442
4465
|
var ToDoList = Ember.Object.extend({
|
4443
|
-
done: Ember.computed.empty('todos.
|
4466
|
+
done: Ember.computed.empty('todos.[]') // detect array changes
|
4444
4467
|
});
|
4445
4468
|
var todoList = ToDoList.create({todos: ['Unit Test', 'Documentation', 'Release']});
|
4446
4469
|
todoList.get('done'); // false
|
@@ -4459,7 +4482,7 @@ registerComputed('empty', function(dependentKey) {
|
|
4459
4482
|
});
|
4460
4483
|
|
4461
4484
|
/**
|
4462
|
-
A computed property that returns true
|
4485
|
+
A computed property that returns true if the value of the dependent
|
4463
4486
|
property is NOT null, an empty string, empty array, or empty function.
|
4464
4487
|
|
4465
4488
|
Example
|
@@ -4485,7 +4508,7 @@ registerComputed('notEmpty', function(dependentKey) {
|
|
4485
4508
|
});
|
4486
4509
|
|
4487
4510
|
/**
|
4488
|
-
A computed property that returns true
|
4511
|
+
A computed property that returns true if the value of the dependent
|
4489
4512
|
property is null or undefined. This avoids errors from JSLint complaining
|
4490
4513
|
about use of ==, which can be technically confusing.
|
4491
4514
|
|
@@ -4524,9 +4547,9 @@ registerComputed('none', function(dependentKey) {
|
|
4524
4547
|
isAnonymous: Ember.computed.not('loggedIn')
|
4525
4548
|
});
|
4526
4549
|
var user = User.create({loggedIn: false});
|
4527
|
-
user.get('isAnonymous'); // false
|
4528
|
-
user.set('loggedIn', true);
|
4529
4550
|
user.get('isAnonymous'); // true
|
4551
|
+
user.set('loggedIn', true);
|
4552
|
+
user.get('isAnonymous'); // false
|
4530
4553
|
```
|
4531
4554
|
|
4532
4555
|
@method computed.not
|
@@ -4560,7 +4583,7 @@ registerComputed('not', function(dependentKey) {
|
|
4560
4583
|
@method computed.bool
|
4561
4584
|
@for Ember
|
4562
4585
|
@param {String} dependentKey
|
4563
|
-
@return {Ember.ComputedProperty} computed property which
|
4586
|
+
@return {Ember.ComputedProperty} computed property which converts
|
4564
4587
|
to boolean the original value for property
|
4565
4588
|
*/
|
4566
4589
|
registerComputed('bool', function(dependentKey) {
|
@@ -4611,7 +4634,7 @@ registerComputed('match', function(dependentKey, regexp) {
|
|
4611
4634
|
var hampster = Hampster.create();
|
4612
4635
|
hampster.get('napTime'); // false
|
4613
4636
|
hampster.set('state', 'sleepy');
|
4614
|
-
hampster.get('napTime'); //
|
4637
|
+
hampster.get('napTime'); // true
|
4615
4638
|
hampster.set('state', 'hungry');
|
4616
4639
|
hampster.get('napTime'); // false
|
4617
4640
|
```
|
@@ -4778,7 +4801,7 @@ registerComputedWithProperties('and', function(properties) {
|
|
4778
4801
|
});
|
4779
4802
|
|
4780
4803
|
/**
|
4781
|
-
A computed property
|
4804
|
+
A computed property which performs a logical `or` on the
|
4782
4805
|
original values for the provided dependent properties.
|
4783
4806
|
|
4784
4807
|
Example
|
@@ -4945,7 +4968,7 @@ Ember.computed.alias = function(dependentKey) {
|
|
4945
4968
|
@method computed.oneWay
|
4946
4969
|
@for Ember
|
4947
4970
|
@param {String} dependentKey
|
4948
|
-
@return {Ember.ComputedProperty} computed property which creates
|
4971
|
+
@return {Ember.ComputedProperty} computed property which creates a
|
4949
4972
|
one way computed property to the original value for property.
|
4950
4973
|
*/
|
4951
4974
|
Ember.computed.oneWay = function(dependentKey) {
|
@@ -4957,7 +4980,7 @@ Ember.computed.oneWay = function(dependentKey) {
|
|
4957
4980
|
|
4958
4981
|
/**
|
4959
4982
|
A computed property that acts like a standard getter and setter,
|
4960
|
-
but
|
4983
|
+
but returns the value at the provided `defaultPath` if the
|
4961
4984
|
property itself has not been set to a value
|
4962
4985
|
|
4963
4986
|
Example
|
@@ -5325,7 +5348,12 @@ define("backburner",
|
|
5325
5348
|
debouncees = [],
|
5326
5349
|
timers = [],
|
5327
5350
|
autorun, laterTimer, laterTimerExpiresAt,
|
5328
|
-
global = this
|
5351
|
+
global = this,
|
5352
|
+
NUMBER = /\d+/;
|
5353
|
+
|
5354
|
+
function isCoercableNumber(number) {
|
5355
|
+
return typeof number === 'number' || NUMBER.test(number);
|
5356
|
+
}
|
5329
5357
|
|
5330
5358
|
function Backburner(queueNames, options) {
|
5331
5359
|
this.queueNames = queueNames;
|
@@ -5440,32 +5468,60 @@ define("backburner",
|
|
5440
5468
|
},
|
5441
5469
|
|
5442
5470
|
setTimeout: function() {
|
5443
|
-
var
|
5444
|
-
|
5445
|
-
|
5446
|
-
|
5447
|
-
|
5471
|
+
var args = slice.call(arguments);
|
5472
|
+
var length = args.length;
|
5473
|
+
var method, wait, target;
|
5474
|
+
var self = this;
|
5475
|
+
var methodOrTarget, methodOrWait, methodOrArgs;
|
5448
5476
|
|
5449
|
-
if (
|
5450
|
-
|
5451
|
-
|
5477
|
+
if (length === 0) {
|
5478
|
+
return;
|
5479
|
+
} else if (length === 1) {
|
5480
|
+
method = args.shift();
|
5481
|
+
wait = 0;
|
5482
|
+
} else if (length === 2) {
|
5483
|
+
methodOrTarget = args[0];
|
5484
|
+
methodOrWait = args[1];
|
5485
|
+
|
5486
|
+
if (typeof methodOrWait === 'function' || typeof methodOrTarget[methodOrWait] === 'function') {
|
5487
|
+
target = args.shift();
|
5488
|
+
method = args.shift();
|
5489
|
+
wait = 0;
|
5490
|
+
} else if (isCoercableNumber(methodOrWait)) {
|
5491
|
+
method = args.shift();
|
5492
|
+
wait = args.shift();
|
5493
|
+
} else {
|
5494
|
+
method = args.shift();
|
5495
|
+
wait = 0;
|
5496
|
+
}
|
5497
|
+
} else {
|
5498
|
+
var last = args[args.length - 1];
|
5499
|
+
|
5500
|
+
if (isCoercableNumber(last)) {
|
5501
|
+
wait = args.pop();
|
5502
|
+
}
|
5503
|
+
|
5504
|
+
methodOrTarget = args[0];
|
5505
|
+
methodOrArgs = args[1];
|
5506
|
+
|
5507
|
+
if (typeof methodOrArgs === 'function' || (typeof methodOrArgs === 'string' &&
|
5508
|
+
methodOrTarget !== null &&
|
5509
|
+
methodOrArgs in methodOrTarget)) {
|
5510
|
+
target = args.shift();
|
5511
|
+
method = args.shift();
|
5512
|
+
} else {
|
5513
|
+
method = args.shift();
|
5514
|
+
}
|
5452
5515
|
}
|
5453
5516
|
|
5517
|
+
var executeAt = (+new Date()) + parseInt(wait, 10);
|
5518
|
+
|
5454
5519
|
if (typeof method === 'string') {
|
5455
5520
|
method = target[method];
|
5456
5521
|
}
|
5457
5522
|
|
5458
|
-
|
5459
|
-
|
5460
|
-
args = slice.call(arguments, 2);
|
5461
|
-
|
5462
|
-
fn = function() {
|
5463
|
-
method.apply(target, args);
|
5464
|
-
};
|
5465
|
-
} else {
|
5466
|
-
fn = function() {
|
5467
|
-
method.call(target);
|
5468
|
-
};
|
5523
|
+
function fn() {
|
5524
|
+
method.apply(target, args);
|
5469
5525
|
}
|
5470
5526
|
|
5471
5527
|
// find position to insert - TODO: binary search
|
@@ -5666,6 +5722,7 @@ define("backburner",
|
|
5666
5722
|
|
5667
5723
|
__exports__.Backburner = Backburner;
|
5668
5724
|
});
|
5725
|
+
|
5669
5726
|
})();
|
5670
5727
|
|
5671
5728
|
|
@@ -6839,15 +6896,14 @@ function addNormalizedProperty(base, key, value, meta, descs, values, concats, m
|
|
6839
6896
|
descs[key] = value;
|
6840
6897
|
values[key] = undefined;
|
6841
6898
|
} else {
|
6842
|
-
|
6843
|
-
if (isMethod(value)) {
|
6844
|
-
value = giveMethodSuper(base, key, value, values, descs);
|
6845
|
-
} else if ((concats && a_indexOf.call(concats, key) >= 0) ||
|
6899
|
+
if ((concats && a_indexOf.call(concats, key) >= 0) ||
|
6846
6900
|
key === 'concatenatedProperties' ||
|
6847
6901
|
key === 'mergedProperties') {
|
6848
6902
|
value = applyConcatenatedProperties(base, key, value, values);
|
6849
6903
|
} else if ((mergings && a_indexOf.call(mergings, key) >= 0)) {
|
6850
6904
|
value = applyMergedProperties(base, key, value, values);
|
6905
|
+
} else if (isMethod(value)) {
|
6906
|
+
value = giveMethodSuper(base, key, value, values, descs);
|
6851
6907
|
}
|
6852
6908
|
|
6853
6909
|
descs[key] = undefined;
|
@@ -7283,11 +7339,10 @@ Alias.prototype = new Ember.Descriptor();
|
|
7283
7339
|
@deprecated Use `Ember.aliasMethod` or `Ember.computed.alias` instead
|
7284
7340
|
*/
|
7285
7341
|
Ember.alias = function(methodName) {
|
7342
|
+
|
7286
7343
|
return new Alias(methodName);
|
7287
7344
|
};
|
7288
7345
|
|
7289
|
-
Ember.alias = Ember.deprecateFunc("Ember.alias is deprecated. Please use Ember.aliasMethod or Ember.computed.alias instead.", Ember.alias);
|
7290
|
-
|
7291
7346
|
/**
|
7292
7347
|
Makes a method available via an additional name.
|
7293
7348
|
|
@@ -7429,6 +7484,55 @@ Ember.beforeObserver = function(func) {
|
|
7429
7484
|
|
7430
7485
|
|
7431
7486
|
|
7487
|
+
(function() {
|
7488
|
+
// Provides a way to register library versions with ember.
|
7489
|
+
var forEach = Ember.EnumerableUtils.forEach,
|
7490
|
+
indexOf = Ember.EnumerableUtils.indexOf;
|
7491
|
+
|
7492
|
+
Ember.libraries = function() {
|
7493
|
+
var libraries = [];
|
7494
|
+
var coreLibIndex = 0;
|
7495
|
+
|
7496
|
+
var getLibrary = function(name) {
|
7497
|
+
for (var i = 0; i < libraries.length; i++) {
|
7498
|
+
if (libraries[i].name === name) {
|
7499
|
+
return libraries[i];
|
7500
|
+
}
|
7501
|
+
}
|
7502
|
+
};
|
7503
|
+
|
7504
|
+
libraries.register = function(name, version) {
|
7505
|
+
if (!getLibrary(name)) {
|
7506
|
+
libraries.push({name: name, version: version});
|
7507
|
+
}
|
7508
|
+
};
|
7509
|
+
|
7510
|
+
libraries.registerCoreLibrary = function(name, version) {
|
7511
|
+
if (!getLibrary(name)) {
|
7512
|
+
libraries.splice(coreLibIndex++, 0, {name: name, version: version});
|
7513
|
+
}
|
7514
|
+
};
|
7515
|
+
|
7516
|
+
libraries.deRegister = function(name) {
|
7517
|
+
var lib = getLibrary(name);
|
7518
|
+
if (lib) libraries.splice(indexOf(libraries, lib), 1);
|
7519
|
+
};
|
7520
|
+
|
7521
|
+
libraries.each = function (callback) {
|
7522
|
+
forEach(libraries, function(lib) {
|
7523
|
+
callback(lib.name, lib.version);
|
7524
|
+
});
|
7525
|
+
};
|
7526
|
+
|
7527
|
+
return libraries;
|
7528
|
+
}();
|
7529
|
+
|
7530
|
+
Ember.libraries.registerCoreLibrary('Ember', Ember.VERSION);
|
7531
|
+
|
7532
|
+
})();
|
7533
|
+
|
7534
|
+
|
7535
|
+
|
7432
7536
|
(function() {
|
7433
7537
|
/**
|
7434
7538
|
Ember Metal
|
@@ -8087,6 +8191,13 @@ define("rsvp",
|
|
8087
8191
|
|
8088
8192
|
(function() {
|
8089
8193
|
/**
|
8194
|
+
@private
|
8195
|
+
Public api for the container is still in flux.
|
8196
|
+
The public api, specified on the application namespace should be considered the stable api.
|
8197
|
+
// @module container
|
8198
|
+
*/
|
8199
|
+
|
8200
|
+
/*
|
8090
8201
|
Flag to enable/disable model factory injections (disabled by default)
|
8091
8202
|
If model factory injections are enabled, models should not be
|
8092
8203
|
accessed globally (only through `container.lookupFactory('model:modelName'))`);
|
@@ -8097,11 +8208,7 @@ define("container",
|
|
8097
8208
|
[],
|
8098
8209
|
function() {
|
8099
8210
|
|
8100
|
-
|
8101
|
-
A safe and simple inheriting object.
|
8102
|
-
|
8103
|
-
@class InheritingDict
|
8104
|
-
*/
|
8211
|
+
// A safe and simple inheriting object.
|
8105
8212
|
function InheritingDict(parent) {
|
8106
8213
|
this.parent = parent;
|
8107
8214
|
this.dict = {};
|
@@ -8174,7 +8281,7 @@ define("container",
|
|
8174
8281
|
|
8175
8282
|
@method has
|
8176
8283
|
@param {String} key
|
8177
|
-
@
|
8284
|
+
@return {Boolean}
|
8178
8285
|
*/
|
8179
8286
|
has: function(key) {
|
8180
8287
|
var dict = this.dict;
|
@@ -8208,11 +8315,10 @@ define("container",
|
|
8208
8315
|
}
|
8209
8316
|
};
|
8210
8317
|
|
8211
|
-
/**
|
8212
|
-
A lightweight container that helps to assemble and decouple components.
|
8213
8318
|
|
8214
|
-
|
8215
|
-
|
8319
|
+
// A lightweight container that helps to assemble and decouple components.
|
8320
|
+
// Public api for the container is still in flux.
|
8321
|
+
// The public api, specified on the application namespace should be considered the stable api.
|
8216
8322
|
function Container(parent) {
|
8217
8323
|
this.parent = parent;
|
8218
8324
|
this.children = [];
|
@@ -8301,7 +8407,7 @@ define("container",
|
|
8301
8407
|
to correctly inherit from the current container.
|
8302
8408
|
|
8303
8409
|
@method child
|
8304
|
-
@
|
8410
|
+
@return {Container}
|
8305
8411
|
*/
|
8306
8412
|
child: function() {
|
8307
8413
|
var container = new Container(this);
|
@@ -8337,25 +8443,25 @@ define("container",
|
|
8337
8443
|
```
|
8338
8444
|
|
8339
8445
|
@method register
|
8340
|
-
@param {String}
|
8341
|
-
@param {String} name
|
8446
|
+
@param {String} fullName
|
8342
8447
|
@param {Function} factory
|
8343
8448
|
@param {Object} options
|
8344
8449
|
*/
|
8345
|
-
register: function(
|
8346
|
-
|
8347
|
-
|
8348
|
-
|
8349
|
-
options = factory;
|
8350
|
-
factory = name;
|
8351
|
-
fullName = type;
|
8352
|
-
} else {
|
8450
|
+
register: function(fullName, factory, options) {
|
8451
|
+
if (fullName.indexOf(':') === -1) {
|
8452
|
+
throw new TypeError("malformed fullName, expected: `type:name` got: " + fullName + "");
|
8453
|
+
}
|
8353
8454
|
|
8354
|
-
|
8455
|
+
if (factory === undefined) {
|
8456
|
+
throw new TypeError('Attempting to register an unknown factory: `' + fullName + '`');
|
8355
8457
|
}
|
8356
8458
|
|
8357
8459
|
var normalizedName = this.normalize(fullName);
|
8358
8460
|
|
8461
|
+
if (this.cache.has(normalizedName)) {
|
8462
|
+
throw new Error('Cannot re-register: `' + fullName +'`, as it has already been looked up.');
|
8463
|
+
}
|
8464
|
+
|
8359
8465
|
this.registry.set(normalizedName, factory);
|
8360
8466
|
this._options.set(normalizedName, options || {});
|
8361
8467
|
},
|
@@ -8415,7 +8521,7 @@ define("container",
|
|
8415
8521
|
|
8416
8522
|
@method resolve
|
8417
8523
|
@param {String} fullName
|
8418
|
-
@
|
8524
|
+
@return {Function} fullName's factory
|
8419
8525
|
*/
|
8420
8526
|
resolve: function(fullName) {
|
8421
8527
|
return this.resolver(fullName) || this.registry.get(fullName);
|
@@ -8450,7 +8556,7 @@ define("container",
|
|
8450
8556
|
@method makeToString
|
8451
8557
|
|
8452
8558
|
@param {any} factory
|
8453
|
-
@param {string}
|
8559
|
+
@param {string} fullName
|
8454
8560
|
@return {function} toString function
|
8455
8561
|
*/
|
8456
8562
|
makeToString: function(factory, fullName) {
|
@@ -8507,7 +8613,7 @@ define("container",
|
|
8507
8613
|
|
8508
8614
|
var value = instantiate(this, fullName);
|
8509
8615
|
|
8510
|
-
if (
|
8616
|
+
if (value === undefined) { return; }
|
8511
8617
|
|
8512
8618
|
if (isSingleton(this, fullName) && options.singleton !== false) {
|
8513
8619
|
this.cache.set(fullName, value);
|
@@ -8585,7 +8691,7 @@ define("container",
|
|
8585
8691
|
this.optionsForType(type, options);
|
8586
8692
|
},
|
8587
8693
|
|
8588
|
-
|
8694
|
+
/**
|
8589
8695
|
@private
|
8590
8696
|
|
8591
8697
|
Used only via `injection`.
|
@@ -8627,7 +8733,7 @@ define("container",
|
|
8627
8733
|
addTypeInjection(this.typeInjections, type, property, fullName);
|
8628
8734
|
},
|
8629
8735
|
|
8630
|
-
|
8736
|
+
/**
|
8631
8737
|
Defines injection rules.
|
8632
8738
|
|
8633
8739
|
These rules are used to inject dependencies onto objects when they
|
@@ -8635,8 +8741,8 @@ define("container",
|
|
8635
8741
|
|
8636
8742
|
Two forms of injections are possible:
|
8637
8743
|
|
8638
|
-
|
8639
|
-
|
8744
|
+
* Injecting one fullName on another fullName
|
8745
|
+
* Injecting one fullName on a type
|
8640
8746
|
|
8641
8747
|
Example:
|
8642
8748
|
|
@@ -8682,7 +8788,7 @@ define("container",
|
|
8682
8788
|
},
|
8683
8789
|
|
8684
8790
|
|
8685
|
-
|
8791
|
+
/**
|
8686
8792
|
@private
|
8687
8793
|
|
8688
8794
|
Used only via `factoryInjection`.
|
@@ -8719,7 +8825,7 @@ define("container",
|
|
8719
8825
|
addTypeInjection(this.factoryTypeInjections, type, property, fullName);
|
8720
8826
|
},
|
8721
8827
|
|
8722
|
-
|
8828
|
+
/**
|
8723
8829
|
Defines factory injection rules.
|
8724
8830
|
|
8725
8831
|
Similar to regular injection rules, but are run against factories, via
|
@@ -8730,8 +8836,8 @@ define("container",
|
|
8730
8836
|
|
8731
8837
|
Two forms of injections are possible:
|
8732
8838
|
|
8733
|
-
|
8734
|
-
|
8839
|
+
* Injecting one fullName on another fullName
|
8840
|
+
* Injecting one fullName on a type
|
8735
8841
|
|
8736
8842
|
Example:
|
8737
8843
|
|
@@ -8833,7 +8939,7 @@ define("container",
|
|
8833
8939
|
injection = injections[i];
|
8834
8940
|
lookup = container.lookup(injection.fullName);
|
8835
8941
|
|
8836
|
-
if (lookup) {
|
8942
|
+
if (lookup !== undefined) {
|
8837
8943
|
hash[injection.property] = lookup;
|
8838
8944
|
} else {
|
8839
8945
|
throw new Error('Attempting to inject an unknown injection: `' + injection.fullName + '`');
|
@@ -8865,13 +8971,13 @@ define("container",
|
|
8865
8971
|
var cache = container.factoryCache;
|
8866
8972
|
var type = fullName.split(":")[0];
|
8867
8973
|
|
8868
|
-
if (
|
8974
|
+
if (factory === undefined) { return; }
|
8869
8975
|
|
8870
8976
|
if (cache.has(fullName)) {
|
8871
8977
|
return cache.get(fullName);
|
8872
8978
|
}
|
8873
8979
|
|
8874
|
-
if (typeof factory.extend !== 'function' || (!Ember.MODEL_FACTORY_INJECTIONS && type === 'model')) {
|
8980
|
+
if (!factory || typeof factory.extend !== 'function' || (!Ember.MODEL_FACTORY_INJECTIONS && type === 'model')) {
|
8875
8981
|
// TODO: think about a 'safe' merge style extension
|
8876
8982
|
// for now just fallback to create time injection
|
8877
8983
|
return factory;
|
@@ -9246,16 +9352,39 @@ Ember.ORDER_DEFINITION = Ember.ENV.ORDER_DEFINITION || [
|
|
9246
9352
|
Ember.keys = Object.keys;
|
9247
9353
|
|
9248
9354
|
if (!Ember.keys || Ember.create.isSimulated) {
|
9355
|
+
var prototypeProperties = [
|
9356
|
+
'constructor',
|
9357
|
+
'hasOwnProperty',
|
9358
|
+
'isPrototypeOf',
|
9359
|
+
'propertyIsEnumerable',
|
9360
|
+
'valueOf',
|
9361
|
+
'toLocaleString',
|
9362
|
+
'toString'
|
9363
|
+
],
|
9364
|
+
pushPropertyName = function(obj, array, key) {
|
9365
|
+
// Prevents browsers that don't respect non-enumerability from
|
9366
|
+
// copying internal Ember properties
|
9367
|
+
if (key.substring(0,2) === '__') return;
|
9368
|
+
if (key === '_super') return;
|
9369
|
+
if (indexOf(array, key) >= 0) return;
|
9370
|
+
if (!obj.hasOwnProperty(key)) return;
|
9371
|
+
|
9372
|
+
array.push(key);
|
9373
|
+
};
|
9374
|
+
|
9249
9375
|
Ember.keys = function(obj) {
|
9250
|
-
var ret = [];
|
9251
|
-
for(
|
9252
|
-
|
9253
|
-
|
9254
|
-
if (key.substring(0,2) === '__') continue;
|
9255
|
-
if (key === '_super') continue;
|
9376
|
+
var ret = [], key;
|
9377
|
+
for (key in obj) {
|
9378
|
+
pushPropertyName(obj, ret, key);
|
9379
|
+
}
|
9256
9380
|
|
9257
|
-
|
9381
|
+
// IE8 doesn't enumerate property that named the same as prototype properties.
|
9382
|
+
for (var i = 0, l = prototypeProperties.length; i < l; i++) {
|
9383
|
+
key = prototypeProperties[i];
|
9384
|
+
|
9385
|
+
pushPropertyName(obj, ret, key);
|
9258
9386
|
}
|
9387
|
+
|
9259
9388
|
return ret;
|
9260
9389
|
};
|
9261
9390
|
}
|
@@ -10695,6 +10824,8 @@ var get = Ember.get,
|
|
10695
10824
|
set = Ember.set,
|
10696
10825
|
guidFor = Ember.guidFor,
|
10697
10826
|
metaFor = Ember.meta,
|
10827
|
+
propertyWillChange = Ember.propertyWillChange,
|
10828
|
+
propertyDidChange = Ember.propertyDidChange,
|
10698
10829
|
addBeforeObserver = Ember.addBeforeObserver,
|
10699
10830
|
removeBeforeObserver = Ember.removeBeforeObserver,
|
10700
10831
|
addObserver = Ember.addObserver,
|
@@ -10749,11 +10880,13 @@ function ItemPropertyObserverContext (dependentArray, index, trackedArray) {
|
|
10749
10880
|
this.trackedArray = trackedArray;
|
10750
10881
|
this.beforeObserver = null;
|
10751
10882
|
this.observer = null;
|
10883
|
+
|
10884
|
+
this.destroyed = false;
|
10752
10885
|
}
|
10753
10886
|
|
10754
10887
|
DependentArraysObserver.prototype = {
|
10755
10888
|
setValue: function (newValue) {
|
10756
|
-
this.instanceMeta.setValue(newValue);
|
10889
|
+
this.instanceMeta.setValue(newValue, true);
|
10757
10890
|
},
|
10758
10891
|
getValue: function () {
|
10759
10892
|
return this.instanceMeta.getValue();
|
@@ -10818,6 +10951,7 @@ DependentArraysObserver.prototype = {
|
|
10818
10951
|
if (operation === Ember.TrackedArray.DELETE) { return; }
|
10819
10952
|
|
10820
10953
|
forEach(observerContexts, function (observerContext) {
|
10954
|
+
observerContext.destroyed = true;
|
10821
10955
|
beforeObserver = observerContext.beforeObserver;
|
10822
10956
|
observer = observerContext.observer;
|
10823
10957
|
item = observerContext.item;
|
@@ -10842,11 +10976,10 @@ DependentArraysObserver.prototype = {
|
|
10842
10976
|
var dependentArrayObserver = this;
|
10843
10977
|
|
10844
10978
|
observerContext.beforeObserver = function (obj, keyName) {
|
10845
|
-
dependentArrayObserver.
|
10846
|
-
return dependentArrayObserver.itemPropertyWillChange(obj, keyName, observerContext.dependentArray, observerContext.index);
|
10979
|
+
return dependentArrayObserver.itemPropertyWillChange(obj, keyName, observerContext.dependentArray, observerContext);
|
10847
10980
|
};
|
10848
10981
|
observerContext.observer = function (obj, keyName) {
|
10849
|
-
return dependentArrayObserver.itemPropertyDidChange(obj, keyName, observerContext.dependentArray, observerContext
|
10982
|
+
return dependentArrayObserver.itemPropertyDidChange(obj, keyName, observerContext.dependentArray, observerContext);
|
10850
10983
|
};
|
10851
10984
|
},
|
10852
10985
|
|
@@ -10854,14 +10987,14 @@ DependentArraysObserver.prototype = {
|
|
10854
10987
|
this.trackedArraysByGuid[dependentKey] = new Ember.TrackedArray(observerContexts);
|
10855
10988
|
},
|
10856
10989
|
|
10857
|
-
|
10990
|
+
trackAdd: function (dependentKey, index, newItems) {
|
10858
10991
|
var trackedArray = this.trackedArraysByGuid[dependentKey];
|
10859
10992
|
if (trackedArray) {
|
10860
10993
|
trackedArray.addItems(index, newItems);
|
10861
10994
|
}
|
10862
10995
|
},
|
10863
10996
|
|
10864
|
-
|
10997
|
+
trackRemove: function (dependentKey, index, removedCount) {
|
10865
10998
|
var trackedArray = this.trackedArraysByGuid[dependentKey];
|
10866
10999
|
|
10867
11000
|
if (trackedArray) {
|
@@ -10902,10 +11035,10 @@ DependentArraysObserver.prototype = {
|
|
10902
11035
|
sliceIndex,
|
10903
11036
|
observerContexts;
|
10904
11037
|
|
10905
|
-
observerContexts = this.
|
10906
|
-
|
11038
|
+
observerContexts = this.trackRemove(dependentKey, index, removedCount);
|
10907
11039
|
|
10908
11040
|
function removeObservers(propertyKey) {
|
11041
|
+
observerContexts[sliceIndex].destroyed = true;
|
10909
11042
|
removeBeforeObserver(item, propertyKey, this, observerContexts[sliceIndex].beforeObserver);
|
10910
11043
|
removeObserver(item, propertyKey, this, observerContexts[sliceIndex].observer);
|
10911
11044
|
}
|
@@ -10947,33 +11080,38 @@ DependentArraysObserver.prototype = {
|
|
10947
11080
|
this.instanceMeta.context, this.getValue(), item, changeMeta, this.instanceMeta.sugarMeta));
|
10948
11081
|
}, this);
|
10949
11082
|
|
10950
|
-
this.
|
11083
|
+
this.trackAdd(dependentKey, index, observerContexts);
|
10951
11084
|
},
|
10952
11085
|
|
10953
|
-
itemPropertyWillChange: function (obj, keyName, array,
|
11086
|
+
itemPropertyWillChange: function (obj, keyName, array, observerContext) {
|
10954
11087
|
var guid = guidFor(obj);
|
10955
11088
|
|
10956
11089
|
if (!this.changedItems[guid]) {
|
10957
11090
|
this.changedItems[guid] = {
|
10958
|
-
array:
|
10959
|
-
|
10960
|
-
obj:
|
10961
|
-
previousValues:
|
11091
|
+
array: array,
|
11092
|
+
observerContext: observerContext,
|
11093
|
+
obj: obj,
|
11094
|
+
previousValues: {}
|
10962
11095
|
};
|
10963
11096
|
}
|
10964
11097
|
|
10965
11098
|
this.changedItems[guid].previousValues[keyName] = get(obj, keyName);
|
10966
11099
|
},
|
10967
11100
|
|
10968
|
-
itemPropertyDidChange: function(obj, keyName, array,
|
10969
|
-
|
11101
|
+
itemPropertyDidChange: function(obj, keyName, array, observerContext) {
|
11102
|
+
this.flushChanges();
|
10970
11103
|
},
|
10971
11104
|
|
10972
11105
|
flushChanges: function() {
|
10973
11106
|
var changedItems = this.changedItems, key, c, changeMeta;
|
11107
|
+
|
10974
11108
|
for (key in changedItems) {
|
10975
11109
|
c = changedItems[key];
|
10976
|
-
|
11110
|
+
if (c.observerContext.destroyed) { continue; }
|
11111
|
+
|
11112
|
+
this.updateIndexes(c.observerContext.trackedArray, c.observerContext.dependentArray);
|
11113
|
+
|
11114
|
+
changeMeta = createChangeMeta(c.array, c.obj, c.observerContext.index, this.instanceMeta.propertyName, this.cp, c.previousValues);
|
10977
11115
|
this.setValue(
|
10978
11116
|
this.callbacks.removedItem.call(this.instanceMeta.context, this.getValue(), c.obj, changeMeta, this.instanceMeta.sugarMeta));
|
10979
11117
|
this.setValue(
|
@@ -11043,11 +11181,21 @@ ReduceComputedPropertyInstanceMeta.prototype = {
|
|
11043
11181
|
}
|
11044
11182
|
},
|
11045
11183
|
|
11046
|
-
setValue: function(newValue) {
|
11184
|
+
setValue: function(newValue, triggerObservers) {
|
11047
11185
|
// This lets sugars force a recomputation, handy for very simple
|
11048
11186
|
// implementations of eg max.
|
11049
11187
|
if (newValue !== undefined) {
|
11188
|
+
var fireObservers = triggerObservers && (newValue !== this.cache[this.propertyName]);
|
11189
|
+
|
11190
|
+
if (fireObservers) {
|
11191
|
+
propertyWillChange(this.context, this.propertyName);
|
11192
|
+
}
|
11193
|
+
|
11050
11194
|
this.cache[this.propertyName] = newValue;
|
11195
|
+
|
11196
|
+
if (fireObservers) {
|
11197
|
+
propertyDidChange(this.context, this.propertyName);
|
11198
|
+
}
|
11051
11199
|
} else {
|
11052
11200
|
delete this.cache[this.propertyName];
|
11053
11201
|
}
|
@@ -11173,13 +11321,11 @@ ReduceComputedProperty.prototype._instanceMeta = function (context, propertyName
|
|
11173
11321
|
};
|
11174
11322
|
|
11175
11323
|
ReduceComputedProperty.prototype.initialValue = function () {
|
11176
|
-
|
11177
|
-
|
11178
|
-
|
11179
|
-
|
11180
|
-
|
11181
|
-
default:
|
11182
|
-
return this.options.initialValue;
|
11324
|
+
if (typeof this.options.initialValue === 'function') {
|
11325
|
+
return this.options.initialValue();
|
11326
|
+
}
|
11327
|
+
else {
|
11328
|
+
return this.options.initialValue;
|
11183
11329
|
}
|
11184
11330
|
};
|
11185
11331
|
|
@@ -11202,25 +11348,25 @@ ReduceComputedProperty.prototype.clearItemPropertyKeys = function (dependentArra
|
|
11202
11348
|
ReduceComputedProperty.prototype.property = function () {
|
11203
11349
|
var cp = this,
|
11204
11350
|
args = a_slice.call(arguments),
|
11205
|
-
propertyArgs =
|
11351
|
+
propertyArgs = new Ember.Set(),
|
11206
11352
|
match,
|
11207
11353
|
dependentArrayKey,
|
11208
11354
|
itemPropertyKey;
|
11209
11355
|
|
11210
11356
|
forEach(a_slice.call(arguments), function (dependentKey) {
|
11211
11357
|
if (doubleEachPropertyPattern.test(dependentKey)) {
|
11212
|
-
throw new Error("Nested @each properties not supported: " + dependentKey);
|
11358
|
+
throw new Ember.Error("Nested @each properties not supported: " + dependentKey);
|
11213
11359
|
} else if (match = eachPropertyPattern.exec(dependentKey)) {
|
11214
11360
|
dependentArrayKey = match[1];
|
11215
11361
|
itemPropertyKey = match[2];
|
11216
11362
|
cp.itemPropertyKey(dependentArrayKey, itemPropertyKey);
|
11217
|
-
propertyArgs.
|
11363
|
+
propertyArgs.add(dependentArrayKey);
|
11218
11364
|
} else {
|
11219
|
-
propertyArgs.
|
11365
|
+
propertyArgs.add(dependentKey);
|
11220
11366
|
}
|
11221
11367
|
});
|
11222
11368
|
|
11223
|
-
return ComputedProperty.prototype.property.apply(this, propertyArgs);
|
11369
|
+
return ComputedProperty.prototype.property.apply(this, propertyArgs.toArray());
|
11224
11370
|
};
|
11225
11371
|
|
11226
11372
|
/**
|
@@ -11232,7 +11378,7 @@ ReduceComputedProperty.prototype.property = function () {
|
|
11232
11378
|
If there are more than one arguments the first arguments are
|
11233
11379
|
considered to be dependent property keys. The last argument is
|
11234
11380
|
required to be an options object. The options object can have the
|
11235
|
-
following four properties
|
11381
|
+
following four properties:
|
11236
11382
|
|
11237
11383
|
`initialValue` - A value or function that will be used as the initial
|
11238
11384
|
value for the computed. If this property is a function the result of calling
|
@@ -11313,6 +11459,12 @@ ReduceComputedProperty.prototype.property = function () {
|
|
11313
11459
|
to invalidate the computation. This is generally not a good idea for
|
11314
11460
|
arrayComputed but it's used in eg max and min.
|
11315
11461
|
|
11462
|
+
Note that observers will be fired if either of these functions return a value
|
11463
|
+
that differs from the accumulated value. When returning an object that
|
11464
|
+
mutates in response to array changes, for example an array that maps
|
11465
|
+
everything from some other array (see `Ember.computed.map`), it is usually
|
11466
|
+
important that the *same* array be returned to avoid accidentally triggering observers.
|
11467
|
+
|
11316
11468
|
Example
|
11317
11469
|
|
11318
11470
|
```javascript
|
@@ -11337,7 +11489,7 @@ ReduceComputedProperty.prototype.property = function () {
|
|
11337
11489
|
@for Ember
|
11338
11490
|
@param {String} [dependentKeys*]
|
11339
11491
|
@param {Object} options
|
11340
|
-
@
|
11492
|
+
@return {Ember.ComputedProperty}
|
11341
11493
|
*/
|
11342
11494
|
Ember.reduceComputed = function (options) {
|
11343
11495
|
var args;
|
@@ -11348,11 +11500,11 @@ Ember.reduceComputed = function (options) {
|
|
11348
11500
|
}
|
11349
11501
|
|
11350
11502
|
if (typeof options !== "object") {
|
11351
|
-
throw new Error("Reduce Computed Property declared without an options hash");
|
11503
|
+
throw new Ember.Error("Reduce Computed Property declared without an options hash");
|
11352
11504
|
}
|
11353
11505
|
|
11354
|
-
if (!options
|
11355
|
-
throw new Error("Reduce Computed Property declared without an initial value");
|
11506
|
+
if (!('initialValue' in options)) {
|
11507
|
+
throw new Ember.Error("Reduce Computed Property declared without an initial value");
|
11356
11508
|
}
|
11357
11509
|
|
11358
11510
|
var cp = new ReduceComputedProperty(options);
|
@@ -11520,7 +11672,7 @@ ArrayComputedProperty.prototype.resetValue = function (array) {
|
|
11520
11672
|
@for Ember
|
11521
11673
|
@param {String} [dependentKeys*]
|
11522
11674
|
@param {Object} options
|
11523
|
-
@
|
11675
|
+
@return {Ember.ComputedProperty}
|
11524
11676
|
*/
|
11525
11677
|
Ember.arrayComputed = function (options) {
|
11526
11678
|
var args;
|
@@ -11531,7 +11683,7 @@ Ember.arrayComputed = function (options) {
|
|
11531
11683
|
}
|
11532
11684
|
|
11533
11685
|
if (typeof options !== "object") {
|
11534
|
-
throw new Error("Array Computed Property declared without an options hash");
|
11686
|
+
throw new Ember.Error("Array Computed Property declared without an options hash");
|
11535
11687
|
}
|
11536
11688
|
|
11537
11689
|
var cp = new ArrayComputedProperty(options);
|
@@ -11678,7 +11830,7 @@ Ember.computed.min = function (dependentKey) {
|
|
11678
11830
|
Ember.computed.map = function(dependentKey, callback) {
|
11679
11831
|
var options = {
|
11680
11832
|
addedItem: function(array, item, changeMeta, instanceMeta) {
|
11681
|
-
var mapped = callback(item);
|
11833
|
+
var mapped = callback.call(this, item);
|
11682
11834
|
array.insertAt(changeMeta.index, mapped);
|
11683
11835
|
return array;
|
11684
11836
|
},
|
@@ -11698,16 +11850,15 @@ Ember.computed.map = function(dependentKey, callback) {
|
|
11698
11850
|
|
11699
11851
|
```javascript
|
11700
11852
|
App.Person = Ember.Object.extend({
|
11701
|
-
childAges: Ember.computed.mapBy('children', 'age')
|
11702
|
-
minChildAge: Ember.computed.min('childAges')
|
11853
|
+
childAges: Ember.computed.mapBy('children', 'age')
|
11703
11854
|
});
|
11704
11855
|
|
11705
11856
|
var lordByron = App.Person.create({children: []});
|
11706
|
-
lordByron.get('
|
11857
|
+
lordByron.get('childAges'); // []
|
11707
11858
|
lordByron.get('children').pushObject({name: 'Augusta Ada Byron', age: 7});
|
11708
|
-
lordByron.get('
|
11859
|
+
lordByron.get('childAges'); // [7]
|
11709
11860
|
lordByron.get('children').pushObjects([{name: 'Allegra Byron', age: 5}, {name: 'Elizabeth Medora Leigh', age: 8}]);
|
11710
|
-
lordByron.get('
|
11861
|
+
lordByron.get('childAges'); // [7, 5, 8]
|
11711
11862
|
```
|
11712
11863
|
|
11713
11864
|
@method computed.mapBy
|
@@ -11771,7 +11922,7 @@ Ember.computed.filter = function(dependentKey, callback) {
|
|
11771
11922
|
},
|
11772
11923
|
|
11773
11924
|
addedItem: function(array, item, changeMeta, instanceMeta) {
|
11774
|
-
var match = !!callback(item),
|
11925
|
+
var match = !!callback.call(this, item),
|
11775
11926
|
filterIndex = instanceMeta.filteredArrayIndexes.addItem(changeMeta.index, match);
|
11776
11927
|
|
11777
11928
|
if (match) {
|
@@ -12020,7 +12171,7 @@ Ember.computed.intersect = function () {
|
|
12020
12171
|
*/
|
12021
12172
|
Ember.computed.setDiff = function (setAProperty, setBProperty) {
|
12022
12173
|
if (arguments.length !== 2) {
|
12023
|
-
throw new Error("setDiff requires exactly two dependent arrays.");
|
12174
|
+
throw new Ember.Error("setDiff requires exactly two dependent arrays.");
|
12024
12175
|
}
|
12025
12176
|
return Ember.arrayComputed.call(null, setAProperty, setBProperty, {
|
12026
12177
|
addedItem: function (array, item, changeMeta, instanceMeta) {
|
@@ -12135,7 +12286,7 @@ function binarySearch(array, item, low, high) {
|
|
12135
12286
|
]});
|
12136
12287
|
|
12137
12288
|
todoList.get('sortedTodos'); // [{name:'Documentation', priority:3}, {name:'Release', priority:1}, {name:'Unit Test', priority:2}]
|
12138
|
-
todoList.get('
|
12289
|
+
todoList.get('priorityTodos'); // [{name:'Release', priority:1}, {name:'Unit Test', priority:2}, {name:'Documentation', priority:3}]
|
12139
12290
|
```
|
12140
12291
|
|
12141
12292
|
@method computed.sort
|
@@ -12275,7 +12426,7 @@ Ember.RSVP = requireModule('rsvp');
|
|
12275
12426
|
|
12276
12427
|
var STRING_DASHERIZE_REGEXP = (/[ _]/g);
|
12277
12428
|
var STRING_DASHERIZE_CACHE = {};
|
12278
|
-
var STRING_DECAMELIZE_REGEXP = (/([a-z])([A-Z])/g);
|
12429
|
+
var STRING_DECAMELIZE_REGEXP = (/([a-z\d])([A-Z])/g);
|
12279
12430
|
var STRING_CAMELIZE_REGEXP = (/(\-|_|\.|\s)+(.)?/g);
|
12280
12431
|
var STRING_UNDERSCORE_REGEXP_1 = (/([a-z\d])([A-Z]+)/g);
|
12281
12432
|
var STRING_UNDERSCORE_REGEXP_2 = (/\-|\s+/g);
|
@@ -12942,7 +13093,7 @@ Ember.Copyable = Ember.Mixin.create(/** @scope Ember.Copyable.prototype */ {
|
|
12942
13093
|
if (Ember.Freezable && Ember.Freezable.detect(this)) {
|
12943
13094
|
return get(this, 'isFrozen') ? this : this.copy().freeze();
|
12944
13095
|
} else {
|
12945
|
-
throw new Error(Ember.String.fmt("%@ does not support freezing", [this]));
|
13096
|
+
throw new Ember.Error(Ember.String.fmt("%@ does not support freezing", [this]));
|
12946
13097
|
}
|
12947
13098
|
}
|
12948
13099
|
});
|
@@ -13251,7 +13402,7 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,/**
|
|
13251
13402
|
@return this
|
13252
13403
|
*/
|
13253
13404
|
insertAt: function(idx, object) {
|
13254
|
-
if (idx > get(this, 'length')) throw new Error(OUT_OF_RANGE_EXCEPTION) ;
|
13405
|
+
if (idx > get(this, 'length')) throw new Ember.Error(OUT_OF_RANGE_EXCEPTION) ;
|
13255
13406
|
this.replace(idx, 0, [object]) ;
|
13256
13407
|
return this ;
|
13257
13408
|
},
|
@@ -13279,7 +13430,7 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,/**
|
|
13279
13430
|
if ('number' === typeof start) {
|
13280
13431
|
|
13281
13432
|
if ((start < 0) || (start >= get(this, 'length'))) {
|
13282
|
-
throw new Error(OUT_OF_RANGE_EXCEPTION);
|
13433
|
+
throw new Ember.Error(OUT_OF_RANGE_EXCEPTION);
|
13283
13434
|
}
|
13284
13435
|
|
13285
13436
|
// fast case
|
@@ -14092,18 +14243,29 @@ Ember.TargetActionSupport = Ember.Mixin.create({
|
|
14092
14243
|
*/
|
14093
14244
|
triggerAction: function(opts) {
|
14094
14245
|
opts = opts || {};
|
14095
|
-
var action = opts
|
14096
|
-
target = opts
|
14097
|
-
actionContext = opts
|
14246
|
+
var action = opts.action || get(this, 'action'),
|
14247
|
+
target = opts.target || get(this, 'targetObject'),
|
14248
|
+
actionContext = opts.actionContext;
|
14249
|
+
|
14250
|
+
function args(options, actionName) {
|
14251
|
+
var ret = [];
|
14252
|
+
if (actionName) { ret.push(actionName); }
|
14253
|
+
|
14254
|
+
return ret.concat(options);
|
14255
|
+
}
|
14256
|
+
|
14257
|
+
if (typeof actionContext === 'undefined') {
|
14258
|
+
actionContext = get(this, 'actionContextObject') || this;
|
14259
|
+
}
|
14098
14260
|
|
14099
14261
|
if (target && action) {
|
14100
14262
|
var ret;
|
14101
14263
|
|
14102
14264
|
if (target.send) {
|
14103
|
-
ret = target.send.apply(target,
|
14265
|
+
ret = target.send.apply(target, args(actionContext, action));
|
14104
14266
|
} else {
|
14105
14267
|
|
14106
|
-
ret = target[action].apply(target,
|
14268
|
+
ret = target[action].apply(target, args(actionContext));
|
14107
14269
|
}
|
14108
14270
|
|
14109
14271
|
if (ret !== false) ret = true;
|
@@ -14494,6 +14656,7 @@ function installPromise(proxy, promise) {
|
|
14494
14656
|
|
14495
14657
|
If the controller is backing a template, the attributes are
|
14496
14658
|
bindable from within that template
|
14659
|
+
|
14497
14660
|
```handlebars
|
14498
14661
|
{{#if isPending}}
|
14499
14662
|
loading...
|
@@ -14517,7 +14680,7 @@ Ember.PromiseProxyMixin = Ember.Mixin.create({
|
|
14517
14680
|
installPromise(this, promise);
|
14518
14681
|
return promise;
|
14519
14682
|
} else {
|
14520
|
-
throw new Error("PromiseProxy's promise must be set");
|
14683
|
+
throw new Ember.Error("PromiseProxy's promise must be set");
|
14521
14684
|
}
|
14522
14685
|
}),
|
14523
14686
|
|
@@ -14560,9 +14723,9 @@ Ember.TrackedArray = function (items) {
|
|
14560
14723
|
var length = get(items, 'length');
|
14561
14724
|
|
14562
14725
|
if (length) {
|
14563
|
-
this.
|
14726
|
+
this._operations = [new ArrayOperation(RETAIN, length, items)];
|
14564
14727
|
} else {
|
14565
|
-
this.
|
14728
|
+
this._operations = [];
|
14566
14729
|
}
|
14567
14730
|
};
|
14568
14731
|
|
@@ -14580,8 +14743,10 @@ Ember.TrackedArray.prototype = {
|
|
14580
14743
|
@param newItems
|
14581
14744
|
*/
|
14582
14745
|
addItems: function (index, newItems) {
|
14583
|
-
var count = get(newItems, 'length')
|
14584
|
-
|
14746
|
+
var count = get(newItems, 'length');
|
14747
|
+
if (count < 1) { return; }
|
14748
|
+
|
14749
|
+
var match = this._findArrayOperation(index),
|
14585
14750
|
arrayOperation = match.operation,
|
14586
14751
|
arrayOperationIndex = match.index,
|
14587
14752
|
arrayOperationRangeStart = match.rangeStart,
|
@@ -14596,7 +14761,7 @@ Ember.TrackedArray.prototype = {
|
|
14596
14761
|
if (arrayOperation) {
|
14597
14762
|
if (!match.split) {
|
14598
14763
|
// insert left of arrayOperation
|
14599
|
-
this.
|
14764
|
+
this._operations.splice(arrayOperationIndex, 0, newArrayOperation);
|
14600
14765
|
composeIndex = arrayOperationIndex;
|
14601
14766
|
} else {
|
14602
14767
|
this._split(arrayOperationIndex, index - arrayOperationRangeStart, newArrayOperation);
|
@@ -14604,7 +14769,7 @@ Ember.TrackedArray.prototype = {
|
|
14604
14769
|
}
|
14605
14770
|
} else {
|
14606
14771
|
// insert at end
|
14607
|
-
this.
|
14772
|
+
this._operations.push(newArrayOperation);
|
14608
14773
|
composeIndex = arrayOperationIndex;
|
14609
14774
|
}
|
14610
14775
|
|
@@ -14619,6 +14784,8 @@ Ember.TrackedArray.prototype = {
|
|
14619
14784
|
@param count
|
14620
14785
|
*/
|
14621
14786
|
removeItems: function (index, count) {
|
14787
|
+
if (count < 1) { return; }
|
14788
|
+
|
14622
14789
|
var match = this._findArrayOperation(index),
|
14623
14790
|
arrayOperation = match.operation,
|
14624
14791
|
arrayOperationIndex = match.index,
|
@@ -14629,7 +14796,7 @@ Ember.TrackedArray.prototype = {
|
|
14629
14796
|
newArrayOperation = new ArrayOperation(DELETE, count);
|
14630
14797
|
if (!match.split) {
|
14631
14798
|
// insert left of arrayOperation
|
14632
|
-
this.
|
14799
|
+
this._operations.splice(arrayOperationIndex, 0, newArrayOperation);
|
14633
14800
|
composeIndex = arrayOperationIndex;
|
14634
14801
|
} else {
|
14635
14802
|
this._split(arrayOperationIndex, index - arrayOperationRangeStart, newArrayOperation);
|
@@ -14644,30 +14811,29 @@ Ember.TrackedArray.prototype = {
|
|
14644
14811
|
items in the array.
|
14645
14812
|
|
14646
14813
|
`callback` will be called for each operation and will be passed the following arguments:
|
14647
|
-
|
14648
|
-
|
14649
|
-
|
14650
|
-
|
14651
|
-
|
14814
|
+
* {array} items The items for the given operation
|
14815
|
+
* {number} offset The computed offset of the items, ie the index in the
|
14816
|
+
array of the first item for this operation.
|
14817
|
+
* {string} operation The type of the operation. One of
|
14818
|
+
`Ember.TrackedArray.{RETAIN, DELETE, INSERT}`
|
14652
14819
|
|
14653
14820
|
@method apply
|
14654
|
-
|
14655
14821
|
@param {function} callback
|
14656
14822
|
*/
|
14657
14823
|
apply: function (callback) {
|
14658
14824
|
var items = [],
|
14659
14825
|
offset = 0;
|
14660
14826
|
|
14661
|
-
forEach(this.
|
14662
|
-
callback(arrayOperation.items, offset, arrayOperation.
|
14827
|
+
forEach(this._operations, function (arrayOperation) {
|
14828
|
+
callback(arrayOperation.items, offset, arrayOperation.type);
|
14663
14829
|
|
14664
|
-
if (arrayOperation.
|
14830
|
+
if (arrayOperation.type !== DELETE) {
|
14665
14831
|
offset += arrayOperation.count;
|
14666
14832
|
items = items.concat(arrayOperation.items);
|
14667
14833
|
}
|
14668
14834
|
});
|
14669
14835
|
|
14670
|
-
this.
|
14836
|
+
this._operations = [new ArrayOperation(RETAIN, items.length, items)];
|
14671
14837
|
},
|
14672
14838
|
|
14673
14839
|
/**
|
@@ -14689,10 +14855,10 @@ Ember.TrackedArray.prototype = {
|
|
14689
14855
|
|
14690
14856
|
// OPTIMIZE: we could search these faster if we kept a balanced tree.
|
14691
14857
|
// find leftmost arrayOperation to the right of `index`
|
14692
|
-
for (arrayOperationIndex = arrayOperationRangeStart = 0, len = this.
|
14693
|
-
arrayOperation = this.
|
14858
|
+
for (arrayOperationIndex = arrayOperationRangeStart = 0, len = this._operations.length; arrayOperationIndex < len; ++arrayOperationIndex) {
|
14859
|
+
arrayOperation = this._operations[arrayOperationIndex];
|
14694
14860
|
|
14695
|
-
if (arrayOperation.
|
14861
|
+
if (arrayOperation.type === DELETE) { continue; }
|
14696
14862
|
|
14697
14863
|
arrayOperationRangeEnd = arrayOperationRangeStart + arrayOperation.count - 1;
|
14698
14864
|
|
@@ -14710,25 +14876,24 @@ Ember.TrackedArray.prototype = {
|
|
14710
14876
|
},
|
14711
14877
|
|
14712
14878
|
_split: function (arrayOperationIndex, splitIndex, newArrayOperation) {
|
14713
|
-
var arrayOperation = this.
|
14879
|
+
var arrayOperation = this._operations[arrayOperationIndex],
|
14714
14880
|
splitItems = arrayOperation.items.slice(splitIndex),
|
14715
|
-
splitArrayOperation = new ArrayOperation(arrayOperation.
|
14881
|
+
splitArrayOperation = new ArrayOperation(arrayOperation.type, splitItems.length, splitItems);
|
14716
14882
|
|
14717
14883
|
// truncate LHS
|
14718
14884
|
arrayOperation.count = splitIndex;
|
14719
14885
|
arrayOperation.items = arrayOperation.items.slice(0, splitIndex);
|
14720
14886
|
|
14721
|
-
this.
|
14887
|
+
this._operations.splice(arrayOperationIndex + 1, 0, newArrayOperation, splitArrayOperation);
|
14722
14888
|
},
|
14723
14889
|
|
14724
|
-
// TODO: unify _composeInsert, _composeDelete
|
14725
14890
|
// see SubArray for a better implementation.
|
14726
14891
|
_composeInsert: function (index) {
|
14727
|
-
var newArrayOperation = this.
|
14728
|
-
leftArrayOperation = this.
|
14729
|
-
rightArrayOperation = this.
|
14730
|
-
leftOp = leftArrayOperation && leftArrayOperation.
|
14731
|
-
rightOp = rightArrayOperation && rightArrayOperation.
|
14892
|
+
var newArrayOperation = this._operations[index],
|
14893
|
+
leftArrayOperation = this._operations[index-1], // may be undefined
|
14894
|
+
rightArrayOperation = this._operations[index+1], // may be undefined
|
14895
|
+
leftOp = leftArrayOperation && leftArrayOperation.type,
|
14896
|
+
rightOp = rightArrayOperation && rightArrayOperation.type;
|
14732
14897
|
|
14733
14898
|
if (leftOp === INSERT) {
|
14734
14899
|
// merge left
|
@@ -14736,30 +14901,31 @@ Ember.TrackedArray.prototype = {
|
|
14736
14901
|
leftArrayOperation.items = leftArrayOperation.items.concat(newArrayOperation.items);
|
14737
14902
|
|
14738
14903
|
if (rightOp === INSERT) {
|
14739
|
-
// also merge right
|
14904
|
+
// also merge right (we have split an insert with an insert)
|
14740
14905
|
leftArrayOperation.count += rightArrayOperation.count;
|
14741
14906
|
leftArrayOperation.items = leftArrayOperation.items.concat(rightArrayOperation.items);
|
14742
|
-
this.
|
14907
|
+
this._operations.splice(index, 2);
|
14743
14908
|
} else {
|
14744
14909
|
// only merge left
|
14745
|
-
this.
|
14910
|
+
this._operations.splice(index, 1);
|
14746
14911
|
}
|
14747
14912
|
} else if (rightOp === INSERT) {
|
14748
14913
|
// merge right
|
14749
14914
|
newArrayOperation.count += rightArrayOperation.count;
|
14750
14915
|
newArrayOperation.items = newArrayOperation.items.concat(rightArrayOperation.items);
|
14751
|
-
this.
|
14916
|
+
this._operations.splice(index + 1, 1);
|
14752
14917
|
}
|
14753
14918
|
},
|
14754
14919
|
|
14755
14920
|
_composeDelete: function (index) {
|
14756
|
-
var arrayOperation = this.
|
14921
|
+
var arrayOperation = this._operations[index],
|
14757
14922
|
deletesToGo = arrayOperation.count,
|
14758
|
-
leftArrayOperation = this.
|
14759
|
-
leftOp = leftArrayOperation && leftArrayOperation.
|
14923
|
+
leftArrayOperation = this._operations[index-1], // may be undefined
|
14924
|
+
leftOp = leftArrayOperation && leftArrayOperation.type,
|
14760
14925
|
nextArrayOperation,
|
14761
14926
|
nextOp,
|
14762
14927
|
nextCount,
|
14928
|
+
removeNewAndNextOp = false,
|
14763
14929
|
removedItems = [];
|
14764
14930
|
|
14765
14931
|
if (leftOp === DELETE) {
|
@@ -14768,8 +14934,8 @@ Ember.TrackedArray.prototype = {
|
|
14768
14934
|
}
|
14769
14935
|
|
14770
14936
|
for (var i = index + 1; deletesToGo > 0; ++i) {
|
14771
|
-
nextArrayOperation = this.
|
14772
|
-
nextOp = nextArrayOperation.
|
14937
|
+
nextArrayOperation = this._operations[i];
|
14938
|
+
nextOp = nextArrayOperation.type;
|
14773
14939
|
nextCount = nextArrayOperation.count;
|
14774
14940
|
|
14775
14941
|
if (nextOp === DELETE) {
|
@@ -14778,6 +14944,7 @@ Ember.TrackedArray.prototype = {
|
|
14778
14944
|
}
|
14779
14945
|
|
14780
14946
|
if (nextCount > deletesToGo) {
|
14947
|
+
// d:2 {r,i}:5 we reduce the retain or insert, but it stays
|
14781
14948
|
removedItems = removedItems.concat(nextArrayOperation.items.splice(0, deletesToGo));
|
14782
14949
|
nextArrayOperation.count -= deletesToGo;
|
14783
14950
|
|
@@ -14789,29 +14956,57 @@ Ember.TrackedArray.prototype = {
|
|
14789
14956
|
|
14790
14957
|
deletesToGo = 0;
|
14791
14958
|
} else {
|
14959
|
+
if (nextCount === deletesToGo) {
|
14960
|
+
// Handle edge case of d:2 i:2 in which case both operations go away
|
14961
|
+
// during composition.
|
14962
|
+
removeNewAndNextOp = true;
|
14963
|
+
}
|
14792
14964
|
removedItems = removedItems.concat(nextArrayOperation.items);
|
14793
14965
|
deletesToGo -= nextCount;
|
14794
14966
|
}
|
14795
14967
|
|
14796
14968
|
if (nextOp === INSERT) {
|
14969
|
+
// d:2 i:3 will result in delete going away
|
14797
14970
|
arrayOperation.count -= nextCount;
|
14798
14971
|
}
|
14799
14972
|
}
|
14800
14973
|
|
14801
14974
|
if (arrayOperation.count > 0) {
|
14802
|
-
|
14975
|
+
// compose our new delete with possibly several operations to the right of
|
14976
|
+
// disparate types
|
14977
|
+
this._operations.splice(index+1, i-1-index);
|
14803
14978
|
} else {
|
14804
14979
|
// The delete operation can go away; it has merely reduced some other
|
14805
|
-
// operation, as in
|
14806
|
-
|
14980
|
+
// operation, as in d:3 i:4; it may also have eliminated that operation,
|
14981
|
+
// as in d:3 i:3.
|
14982
|
+
this._operations.splice(index, removeNewAndNextOp ? 2 : 1);
|
14807
14983
|
}
|
14808
14984
|
|
14809
14985
|
return removedItems;
|
14986
|
+
},
|
14987
|
+
|
14988
|
+
toString: function () {
|
14989
|
+
var str = "";
|
14990
|
+
forEach(this._operations, function (operation) {
|
14991
|
+
str += " " + operation.type + ":" + operation.count;
|
14992
|
+
});
|
14993
|
+
return str.substring(1);
|
14810
14994
|
}
|
14811
14995
|
};
|
14812
14996
|
|
14997
|
+
/**
|
14998
|
+
Internal data structure to represent an array operation.
|
14999
|
+
|
15000
|
+
@method ArrayOperation
|
15001
|
+
@private
|
15002
|
+
@property {string} type The type of the operation. One of
|
15003
|
+
`Ember.TrackedArray.{RETAIN, INSERT, DELETE}`
|
15004
|
+
@property {number} count The number of items in this operation.
|
15005
|
+
@property {array} items The items of the operation, if included. RETAIN and
|
15006
|
+
INSERT include their items, DELETE does not.
|
15007
|
+
*/
|
14813
15008
|
function ArrayOperation (operation, count, items) {
|
14814
|
-
this.
|
15009
|
+
this.type = operation; // RETAIN | INSERT | DELETE
|
14815
15010
|
this.count = count;
|
14816
15011
|
this.items = items;
|
14817
15012
|
}
|
@@ -14879,7 +15074,7 @@ Ember.SubArray.prototype = {
|
|
14879
15074
|
@param {number} index The index of the item in the tracked array.
|
14880
15075
|
@param {boolean} match `true` iff the item is included in the subarray.
|
14881
15076
|
|
14882
|
-
@
|
15077
|
+
@return {number} The index of the item in the subarray.
|
14883
15078
|
*/
|
14884
15079
|
addItem: function(index, match) {
|
14885
15080
|
var returnValue = -1,
|
@@ -14931,7 +15126,7 @@ Ember.SubArray.prototype = {
|
|
14931
15126
|
|
14932
15127
|
@param {number} index The index of the item in the tracked array.
|
14933
15128
|
|
14934
|
-
@
|
15129
|
+
@return {number} The index of the item in the subarray, or `-1` if the item
|
14935
15130
|
was not in the subarray.
|
14936
15131
|
*/
|
14937
15132
|
removeItem: function(index) {
|
@@ -14949,6 +15144,8 @@ Ember.SubArray.prototype = {
|
|
14949
15144
|
self._operations.splice(operationIndex, 1);
|
14950
15145
|
self._composeAt(operationIndex);
|
14951
15146
|
}
|
15147
|
+
}, function() {
|
15148
|
+
throw new Ember.Error("Can't remove an item that has never been added.");
|
14952
15149
|
});
|
14953
15150
|
|
14954
15151
|
return returnValue;
|
@@ -14995,6 +15192,7 @@ Ember.SubArray.prototype = {
|
|
14995
15192
|
if (otherOp.type === op.type) {
|
14996
15193
|
op.count += otherOp.count;
|
14997
15194
|
this._operations.splice(index-1, 1);
|
15195
|
+
--index;
|
14998
15196
|
}
|
14999
15197
|
}
|
15000
15198
|
|
@@ -15090,7 +15288,14 @@ function makeCtor() {
|
|
15090
15288
|
var properties = props[i];
|
15091
15289
|
|
15092
15290
|
|
15093
|
-
|
15291
|
+
if (properties === null || typeof properties !== 'object') {
|
15292
|
+
|
15293
|
+
continue;
|
15294
|
+
}
|
15295
|
+
|
15296
|
+
var keyNames = Ember.keys(properties);
|
15297
|
+
for (var j = 0, ll = keyNames.length; j < ll; j++) {
|
15298
|
+
var keyName = keyNames[j];
|
15094
15299
|
if (!properties.hasOwnProperty(keyName)) { continue; }
|
15095
15300
|
|
15096
15301
|
var value = properties[keyName],
|
@@ -15275,7 +15480,10 @@ CoreObject.PrototypeMixin = Mixin.create({
|
|
15275
15480
|
are also concatenated, in addition to `classNames`.
|
15276
15481
|
|
15277
15482
|
This feature is available for you to use throughout the Ember object model,
|
15278
|
-
although typical app developers are likely to use it infrequently.
|
15483
|
+
although typical app developers are likely to use it infrequently. Since
|
15484
|
+
it changes expectations about behavior of properties, you should properly
|
15485
|
+
document its usage in each individual concatenated property (to not
|
15486
|
+
mislead your users to think they can override the property in a subclass).
|
15279
15487
|
|
15280
15488
|
@property concatenatedProperties
|
15281
15489
|
@type Array
|
@@ -15415,6 +15623,86 @@ var ClassMixin = Mixin.create({
|
|
15415
15623
|
|
15416
15624
|
isMethod: false,
|
15417
15625
|
|
15626
|
+
/**
|
15627
|
+
Creates a new subclass.
|
15628
|
+
|
15629
|
+
```javascript
|
15630
|
+
App.Person = Ember.Object.extend({
|
15631
|
+
say: function(thing) {
|
15632
|
+
alert(thing);
|
15633
|
+
}
|
15634
|
+
});
|
15635
|
+
```
|
15636
|
+
|
15637
|
+
This defines a new subclass of Ember.Object: `App.Person`. It contains one method: `say()`.
|
15638
|
+
|
15639
|
+
You can also create a subclass from any existing class by calling its `extend()` method. For example, you might want to create a subclass of Ember's built-in `Ember.View` class:
|
15640
|
+
|
15641
|
+
```javascript
|
15642
|
+
App.PersonView = Ember.View.extend({
|
15643
|
+
tagName: 'li',
|
15644
|
+
classNameBindings: ['isAdministrator']
|
15645
|
+
});
|
15646
|
+
```
|
15647
|
+
|
15648
|
+
When defining a subclass, you can override methods but still access the implementation of your parent class by calling the special `_super()` method:
|
15649
|
+
|
15650
|
+
```javascript
|
15651
|
+
App.Person = Ember.Object.extend({
|
15652
|
+
say: function(thing) {
|
15653
|
+
var name = this.get('name');
|
15654
|
+
alert(name + ' says: ' + thing);
|
15655
|
+
}
|
15656
|
+
});
|
15657
|
+
|
15658
|
+
App.Soldier = App.Person.extend({
|
15659
|
+
say: function(thing) {
|
15660
|
+
this._super(thing + ", sir!");
|
15661
|
+
},
|
15662
|
+
march: function(numberOfHours) {
|
15663
|
+
alert(this.get('name') + ' marches for ' + numberOfHours + ' hours.')
|
15664
|
+
}
|
15665
|
+
});
|
15666
|
+
|
15667
|
+
var yehuda = App.Soldier.create({
|
15668
|
+
name: "Yehuda Katz"
|
15669
|
+
});
|
15670
|
+
|
15671
|
+
yehuda.say("Yes"); // alerts "Yehuda Katz says: Yes, sir!"
|
15672
|
+
```
|
15673
|
+
|
15674
|
+
The `create()` on line #17 creates an *instance* of the `App.Soldier` class. The `extend()` on line #8 creates a *subclass* of `App.Person`. Any instance of the `App.Person` class will *not* have the `march()` method.
|
15675
|
+
|
15676
|
+
You can also pass `Ember.Mixin` classes to add additional properties to the subclass.
|
15677
|
+
|
15678
|
+
```javascript
|
15679
|
+
App.Person = Ember.Object.extend({
|
15680
|
+
say: function(thing) {
|
15681
|
+
alert(this.get('name') + ' says: ' + thing);
|
15682
|
+
}
|
15683
|
+
});
|
15684
|
+
|
15685
|
+
App.SingingMixin = Ember.Mixin.create({
|
15686
|
+
sing: function(thing){
|
15687
|
+
alert(this.get('name') + ' sings: la la la ' + thing);
|
15688
|
+
}
|
15689
|
+
});
|
15690
|
+
|
15691
|
+
App.BroadwayStar = App.Person.extend(App.SingingMixin, {
|
15692
|
+
dance: function() {
|
15693
|
+
alert(this.get('name') + ' dances: tap tap tap tap ');
|
15694
|
+
}
|
15695
|
+
});
|
15696
|
+
```
|
15697
|
+
|
15698
|
+
The `App.BroadwayStar` class contains three methods: `say()`, `sing()`, and `dance()`.
|
15699
|
+
|
15700
|
+
@method extend
|
15701
|
+
@static
|
15702
|
+
|
15703
|
+
@param {Ember.Mixin} [mixins]* One or more Ember.Mixin classes
|
15704
|
+
@param {Object} [arguments]* Object containing values to use within the new class
|
15705
|
+
*/
|
15418
15706
|
extend: function() {
|
15419
15707
|
var Class = makeCtor(), proto;
|
15420
15708
|
Class.ClassMixin = Mixin.create(this.ClassMixin);
|
@@ -15495,10 +15783,10 @@ var ClassMixin = Mixin.create({
|
|
15495
15783
|
},
|
15496
15784
|
|
15497
15785
|
/**
|
15498
|
-
|
15786
|
+
|
15499
15787
|
Augments a constructor's prototype with additional
|
15500
15788
|
properties and functions:
|
15501
|
-
|
15789
|
+
|
15502
15790
|
```javascript
|
15503
15791
|
MyObject = Ember.Object.extend({
|
15504
15792
|
name: 'an object'
|
@@ -15518,7 +15806,7 @@ var ClassMixin = Mixin.create({
|
|
15518
15806
|
|
15519
15807
|
o.say("goodbye"); // logs "goodbye"
|
15520
15808
|
```
|
15521
|
-
|
15809
|
+
|
15522
15810
|
To add functions and properties to the constructor itself,
|
15523
15811
|
see `reopenClass`
|
15524
15812
|
|
@@ -15532,7 +15820,7 @@ var ClassMixin = Mixin.create({
|
|
15532
15820
|
|
15533
15821
|
/**
|
15534
15822
|
Augments a constructor's own properties and functions:
|
15535
|
-
|
15823
|
+
|
15536
15824
|
```javascript
|
15537
15825
|
MyObject = Ember.Object.extend({
|
15538
15826
|
name: 'an object'
|
@@ -15542,17 +15830,50 @@ var ClassMixin = Mixin.create({
|
|
15542
15830
|
MyObject.reopenClass({
|
15543
15831
|
canBuild: false
|
15544
15832
|
});
|
15545
|
-
|
15833
|
+
|
15546
15834
|
MyObject.canBuild; // false
|
15547
15835
|
o = MyObject.create();
|
15548
15836
|
```
|
15549
|
-
|
15837
|
+
|
15838
|
+
In other words, this creates static properties and functions for the class. These are only available on the class
|
15839
|
+
and not on any instance of that class.
|
15840
|
+
|
15841
|
+
```javascript
|
15842
|
+
App.Person = Ember.Object.extend({
|
15843
|
+
name : "",
|
15844
|
+
sayHello : function(){
|
15845
|
+
alert("Hello. My name is " + this.get('name'));
|
15846
|
+
}
|
15847
|
+
});
|
15848
|
+
|
15849
|
+
App.Person.reopenClass({
|
15850
|
+
species : "Homo sapiens",
|
15851
|
+
createPerson: function(newPersonsName){
|
15852
|
+
return App.Person.create({
|
15853
|
+
name:newPersonsName
|
15854
|
+
});
|
15855
|
+
}
|
15856
|
+
});
|
15857
|
+
|
15858
|
+
var tom = App.Person.create({
|
15859
|
+
name : "Tom Dale"
|
15860
|
+
});
|
15861
|
+
var yehuda = App.Person.createPerson("Yehuda Katz");
|
15862
|
+
|
15863
|
+
tom.sayHello(); // "Hello. My name is Tom Dale"
|
15864
|
+
yehuda.sayHello(); // "Hello. My name is Yehuda Katz"
|
15865
|
+
alert(App.Person.species); // "Homo sapiens"
|
15866
|
+
```
|
15867
|
+
|
15868
|
+
Note that `species` and `createPerson` are *not* valid on the `tom` and `yehuda`
|
15869
|
+
variables. They are only valid on `App.Person`.
|
15870
|
+
|
15550
15871
|
To add functions and properties to instances of
|
15551
15872
|
a constructor by extending the constructor's prototype
|
15552
15873
|
see `reopen`
|
15553
|
-
|
15874
|
+
|
15554
15875
|
@method reopenClass
|
15555
|
-
*/
|
15876
|
+
*/
|
15556
15877
|
reopenClass: function() {
|
15557
15878
|
reopen.apply(this.ClassMixin, arguments);
|
15558
15879
|
applyMixin(this, arguments, false);
|
@@ -16108,7 +16429,7 @@ Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,/** @scope Ember.Array
|
|
16108
16429
|
},
|
16109
16430
|
|
16110
16431
|
_insertAt: function(idx, object) {
|
16111
|
-
if (idx > get(this, 'content.length')) throw new Error(OUT_OF_RANGE_EXCEPTION);
|
16432
|
+
if (idx > get(this, 'content.length')) throw new Ember.Error(OUT_OF_RANGE_EXCEPTION);
|
16112
16433
|
this._replace(idx, 0, [object]);
|
16113
16434
|
return this;
|
16114
16435
|
},
|
@@ -16128,7 +16449,7 @@ Ember.ArrayProxy = Ember.Object.extend(Ember.MutableArray,/** @scope Ember.Array
|
|
16128
16449
|
indices = [], i;
|
16129
16450
|
|
16130
16451
|
if ((start < 0) || (start >= get(this, 'length'))) {
|
16131
|
-
throw new Error(OUT_OF_RANGE_EXCEPTION);
|
16452
|
+
throw new Ember.Error(OUT_OF_RANGE_EXCEPTION);
|
16132
16453
|
}
|
16133
16454
|
|
16134
16455
|
if (len === undefined) len = 1;
|
@@ -16895,7 +17216,7 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
|
|
16895
17216
|
@return {Ember.Set} An empty Set
|
16896
17217
|
*/
|
16897
17218
|
clear: function() {
|
16898
|
-
if (this.isFrozen) { throw new Error(Ember.FROZEN_ERROR); }
|
17219
|
+
if (this.isFrozen) { throw new Ember.Error(Ember.FROZEN_ERROR); }
|
16899
17220
|
|
16900
17221
|
var len = get(this, 'length');
|
16901
17222
|
if (len === 0) { return this; }
|
@@ -17005,7 +17326,7 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
|
|
17005
17326
|
@return {Object} The removed object from the set or null.
|
17006
17327
|
*/
|
17007
17328
|
pop: function() {
|
17008
|
-
if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
|
17329
|
+
if (get(this, 'isFrozen')) throw new Ember.Error(Ember.FROZEN_ERROR);
|
17009
17330
|
var obj = this.length > 0 ? this[this.length-1] : null;
|
17010
17331
|
this.remove(obj);
|
17011
17332
|
return obj;
|
@@ -17122,7 +17443,7 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
|
|
17122
17443
|
|
17123
17444
|
// implements Ember.MutableEnumerable
|
17124
17445
|
addObject: function(obj) {
|
17125
|
-
if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
|
17446
|
+
if (get(this, 'isFrozen')) throw new Ember.Error(Ember.FROZEN_ERROR);
|
17126
17447
|
if (isNone(obj)) return this; // nothing to do
|
17127
17448
|
|
17128
17449
|
var guid = guidFor(obj),
|
@@ -17150,7 +17471,7 @@ Ember.Set = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Emb
|
|
17150
17471
|
|
17151
17472
|
// implements Ember.MutableEnumerable
|
17152
17473
|
removeObject: function(obj) {
|
17153
|
-
if (get(this, 'isFrozen')) throw new Error(Ember.FROZEN_ERROR);
|
17474
|
+
if (get(this, 'isFrozen')) throw new Ember.Error(Ember.FROZEN_ERROR);
|
17154
17475
|
if (isNone(obj)) return this; // nothing to do
|
17155
17476
|
|
17156
17477
|
var guid = guidFor(obj),
|
@@ -17856,7 +18177,7 @@ Ember.ArrayController = Ember.ArrayProxy.extend(Ember.ControllerMixin,
|
|
17856
18177
|
fullName = "controller:" + controllerClass;
|
17857
18178
|
|
17858
18179
|
if (!container.has(fullName)) {
|
17859
|
-
throw new Error('Could not resolve itemController: "' + controllerClass + '"');
|
18180
|
+
throw new Ember.Error('Could not resolve itemController: "' + controllerClass + '"');
|
17860
18181
|
}
|
17861
18182
|
|
17862
18183
|
subController = container.lookupFactory(fullName).create({
|
@@ -18178,6 +18499,19 @@ function escapeAttribute(value) {
|
|
18178
18499
|
return string.replace(BAD_CHARS_REGEXP, escapeChar);
|
18179
18500
|
}
|
18180
18501
|
|
18502
|
+
// IE 6/7 have bugs arond setting names on inputs during creation.
|
18503
|
+
// From http://msdn.microsoft.com/en-us/library/ie/ms536389(v=vs.85).aspx:
|
18504
|
+
// "To include the NAME attribute at run time on objects created with the createElement method, use the eTag."
|
18505
|
+
var canSetNameOnInputs = (function() {
|
18506
|
+
var div = document.createElement('div'),
|
18507
|
+
el = document.createElement('input');
|
18508
|
+
|
18509
|
+
el.setAttribute('name', 'foo');
|
18510
|
+
div.appendChild(el);
|
18511
|
+
|
18512
|
+
return !!div.innerHTML.match('foo');
|
18513
|
+
})();
|
18514
|
+
|
18181
18515
|
/**
|
18182
18516
|
`Ember.RenderBuffer` gathers information regarding the a view and generates the
|
18183
18517
|
final representation. `Ember.RenderBuffer` will generate HTML which can be pushed
|
@@ -18537,14 +18871,22 @@ Ember._RenderBuffer.prototype =
|
|
18537
18871
|
|
18538
18872
|
generateElement: function() {
|
18539
18873
|
var tagName = this.tagNames.pop(), // pop since we don't need to close
|
18540
|
-
element = document.createElement(tagName),
|
18541
|
-
$element = Ember.$(element),
|
18542
18874
|
id = this.elementId,
|
18543
18875
|
classes = this.classes,
|
18544
18876
|
attrs = this.elementAttributes,
|
18545
18877
|
props = this.elementProperties,
|
18546
18878
|
style = this.elementStyle,
|
18547
|
-
styleBuffer = '', attr, prop;
|
18879
|
+
styleBuffer = '', attr, prop, tagString;
|
18880
|
+
|
18881
|
+
if (attrs && attrs.name && !canSetNameOnInputs) {
|
18882
|
+
// IE allows passing a tag to createElement. See note on `canSetNameOnInputs` above as well.
|
18883
|
+
tagString = '<'+stripTagName(tagName)+' name="'+escapeAttribute(attrs.name)+'">';
|
18884
|
+
} else {
|
18885
|
+
tagString = tagName;
|
18886
|
+
}
|
18887
|
+
|
18888
|
+
var element = document.createElement(tagString),
|
18889
|
+
$element = Ember.$(element);
|
18548
18890
|
|
18549
18891
|
if (id) {
|
18550
18892
|
$element.attr('id', id);
|
@@ -18937,6 +19279,7 @@ var get = Ember.get, set = Ember.set;
|
|
18937
19279
|
var guidFor = Ember.guidFor;
|
18938
19280
|
var a_forEach = Ember.EnumerableUtils.forEach;
|
18939
19281
|
var a_addObject = Ember.EnumerableUtils.addObject;
|
19282
|
+
var meta = Ember.meta;
|
18940
19283
|
|
18941
19284
|
var childViewsProperty = Ember.computed(function() {
|
18942
19285
|
var childViews = this._childViews, ret = Ember.A(), view = this;
|
@@ -18957,7 +19300,7 @@ var childViewsProperty = Ember.computed(function() {
|
|
18957
19300
|
|
18958
19301
|
return view.replace(idx, removedCount, addedViews);
|
18959
19302
|
}
|
18960
|
-
throw new Error("childViews is immutable");
|
19303
|
+
throw new Ember.Error("childViews is immutable");
|
18961
19304
|
};
|
18962
19305
|
|
18963
19306
|
return ret;
|
@@ -20643,8 +20986,8 @@ Ember.View = Ember.CoreView.extend(
|
|
20643
20986
|
If you write a `willDestroyElement()` handler, you can assume that your
|
20644
20987
|
`didInsertElement()` handler was called earlier for the same element.
|
20645
20988
|
|
20646
|
-
|
20647
|
-
want to implement the above callbacks
|
20989
|
+
You should not call or override this method yourself, but you may
|
20990
|
+
want to implement the above callbacks.
|
20648
20991
|
|
20649
20992
|
@method destroyElement
|
20650
20993
|
@return {Ember.View} receiver
|
@@ -20681,12 +21024,6 @@ Ember.View = Ember.CoreView.extend(
|
|
20681
21024
|
return viewCollection;
|
20682
21025
|
},
|
20683
21026
|
|
20684
|
-
_elementWillChange: Ember.beforeObserver(function() {
|
20685
|
-
this.forEachChildView(function(view) {
|
20686
|
-
Ember.propertyWillChange(view, 'element');
|
20687
|
-
});
|
20688
|
-
}, 'element'),
|
20689
|
-
|
20690
21027
|
/**
|
20691
21028
|
@private
|
20692
21029
|
|
@@ -20698,7 +21035,7 @@ Ember.View = Ember.CoreView.extend(
|
|
20698
21035
|
*/
|
20699
21036
|
_elementDidChange: Ember.observer(function() {
|
20700
21037
|
this.forEachChildView(function(view) {
|
20701
|
-
|
21038
|
+
delete meta(view).cache.element;
|
20702
21039
|
});
|
20703
21040
|
}, 'element'),
|
20704
21041
|
|
@@ -21143,6 +21480,7 @@ Ember.View = Ember.CoreView.extend(
|
|
21143
21480
|
|
21144
21481
|
if (priorState && priorState.exit) { priorState.exit(this); }
|
21145
21482
|
if (currentState.enter) { currentState.enter(this); }
|
21483
|
+
if (state === 'inDOM') { delete Ember.meta(this).cache.element; }
|
21146
21484
|
|
21147
21485
|
if (children !== false) {
|
21148
21486
|
this.forEachChildView(function(view) {
|
@@ -21174,6 +21512,10 @@ Ember.View = Ember.CoreView.extend(
|
|
21174
21512
|
target = null;
|
21175
21513
|
}
|
21176
21514
|
|
21515
|
+
if (!root || typeof root !== 'object') {
|
21516
|
+
return;
|
21517
|
+
}
|
21518
|
+
|
21177
21519
|
var view = this,
|
21178
21520
|
stateCheckedObserver = function() {
|
21179
21521
|
view.currentState.invokeObserver(this, observer);
|
@@ -21490,10 +21832,18 @@ Ember.merge(preRender, {
|
|
21490
21832
|
var viewCollection = view.viewHierarchyCollection();
|
21491
21833
|
|
21492
21834
|
viewCollection.trigger('willInsertElement');
|
21493
|
-
|
21835
|
+
|
21494
21836
|
fn.call(view);
|
21495
|
-
|
21496
|
-
|
21837
|
+
|
21838
|
+
// We transition to `inDOM` if the element exists in the DOM
|
21839
|
+
var element = view.get('element');
|
21840
|
+
while (element = element.parentNode) {
|
21841
|
+
if (element === document) {
|
21842
|
+
viewCollection.transitionTo('inDOM', false);
|
21843
|
+
viewCollection.trigger('didInsertElement');
|
21844
|
+
}
|
21845
|
+
}
|
21846
|
+
|
21497
21847
|
},
|
21498
21848
|
|
21499
21849
|
renderToBufferIfNeeded: function(view, buffer) {
|
@@ -21702,7 +22052,7 @@ Ember.merge(inDOM, {
|
|
21702
22052
|
}
|
21703
22053
|
|
21704
22054
|
view.addBeforeObserver('elementId', function() {
|
21705
|
-
throw new Error("Changing a view's elementId after creation is not allowed");
|
22055
|
+
throw new Ember.Error("Changing a view's elementId after creation is not allowed");
|
21706
22056
|
});
|
21707
22057
|
},
|
21708
22058
|
|
@@ -21942,30 +22292,6 @@ var ViewCollection = Ember._ViewCollection;
|
|
21942
22292
|
or layout being rendered. The HTML contents of a `Ember.ContainerView`'s DOM
|
21943
22293
|
representation will only be the rendered HTML of its child views.
|
21944
22294
|
|
21945
|
-
## Binding a View to Display
|
21946
|
-
|
21947
|
-
If you would like to display a single view in your ContainerView, you can set
|
21948
|
-
its `currentView` property. When the `currentView` property is set to a view
|
21949
|
-
instance, it will be added to the ContainerView. If the `currentView` property
|
21950
|
-
is later changed to a different view, the new view will replace the old view.
|
21951
|
-
If `currentView` is set to `null`, the last `currentView` will be removed.
|
21952
|
-
|
21953
|
-
This functionality is useful for cases where you want to bind the display of
|
21954
|
-
a ContainerView to a controller or state manager. For example, you can bind
|
21955
|
-
the `currentView` of a container to a controller like this:
|
21956
|
-
|
21957
|
-
```javascript
|
21958
|
-
App.appController = Ember.Object.create({
|
21959
|
-
view: Ember.View.create({
|
21960
|
-
templateName: 'person_template'
|
21961
|
-
})
|
21962
|
-
});
|
21963
|
-
```
|
21964
|
-
|
21965
|
-
```handlebars
|
21966
|
-
{{view Ember.ContainerView currentViewBinding="App.appController.view"}}
|
21967
|
-
```
|
21968
|
-
|
21969
22295
|
@class ContainerView
|
21970
22296
|
@namespace Ember
|
21971
22297
|
@extends Ember.View
|
@@ -22150,7 +22476,7 @@ Ember.merge(states._default, {
|
|
22150
22476
|
|
22151
22477
|
Ember.merge(states.inBuffer, {
|
22152
22478
|
childViewsDidChange: function(parentView, views, start, added) {
|
22153
|
-
throw new Error('You cannot modify child views while in the inBuffer state');
|
22479
|
+
throw new Ember.Error('You cannot modify child views while in the inBuffer state');
|
22154
22480
|
}
|
22155
22481
|
});
|
22156
22482
|
|
@@ -22641,7 +22967,9 @@ Ember.CollectionView.CONTAINER_MAP = {
|
|
22641
22967
|
|
22642
22968
|
|
22643
22969
|
(function() {
|
22644
|
-
var get = Ember.get, set = Ember.set, isNone = Ember.isNone
|
22970
|
+
var get = Ember.get, set = Ember.set, isNone = Ember.isNone,
|
22971
|
+
a_slice = Array.prototype.slice;
|
22972
|
+
|
22645
22973
|
|
22646
22974
|
/**
|
22647
22975
|
@module ember
|
@@ -22699,8 +23027,10 @@ var get = Ember.get, set = Ember.set, isNone = Ember.isNone;
|
|
22699
23027
|
|
22700
23028
|
```javascript
|
22701
23029
|
App.AppProfileComponent = Ember.Component.extend({
|
22702
|
-
|
22703
|
-
|
23030
|
+
actions: {
|
23031
|
+
hello: function(name) {
|
23032
|
+
console.log("Hello", name);
|
23033
|
+
}
|
22704
23034
|
}
|
22705
23035
|
});
|
22706
23036
|
```
|
@@ -22754,7 +23084,7 @@ Ember.Component = Ember.View.extend(Ember.TargetActionSupport, {
|
|
22754
23084
|
isVirtual: true,
|
22755
23085
|
tagName: '',
|
22756
23086
|
_contextView: parentView,
|
22757
|
-
template:
|
23087
|
+
template: template,
|
22758
23088
|
context: get(parentView, 'context'),
|
22759
23089
|
controller: get(parentView, 'controller'),
|
22760
23090
|
templateData: { keywords: parentView.cloneKeywords() }
|
@@ -22813,8 +23143,10 @@ Ember.Component = Ember.View.extend(Ember.TargetActionSupport, {
|
|
22813
23143
|
});
|
22814
23144
|
|
22815
23145
|
App.CategoriesController = Ember.Controller.extend({
|
22816
|
-
|
22817
|
-
|
23146
|
+
actions: {
|
23147
|
+
didClickCategory: function(category) {
|
23148
|
+
//Do something with the node/category that was clicked
|
23149
|
+
}
|
22818
23150
|
}
|
22819
23151
|
});
|
22820
23152
|
```
|
@@ -22828,8 +23160,9 @@ Ember.Component = Ember.View.extend(Ember.TargetActionSupport, {
|
|
22828
23160
|
@param [action] {String} the action to trigger
|
22829
23161
|
@param [context] {*} a context to send with the action
|
22830
23162
|
*/
|
22831
|
-
sendAction: function(action
|
22832
|
-
var actionName
|
23163
|
+
sendAction: function(action) {
|
23164
|
+
var actionName,
|
23165
|
+
contexts = a_slice.call(arguments, 1);
|
22833
23166
|
|
22834
23167
|
// Send the default action
|
22835
23168
|
if (action === undefined) {
|
@@ -22845,7 +23178,7 @@ Ember.Component = Ember.View.extend(Ember.TargetActionSupport, {
|
|
22845
23178
|
|
22846
23179
|
this.triggerAction({
|
22847
23180
|
action: actionName,
|
22848
|
-
actionContext:
|
23181
|
+
actionContext: contexts
|
22849
23182
|
});
|
22850
23183
|
}
|
22851
23184
|
});
|
@@ -23058,6 +23391,14 @@ define("metamorph",
|
|
23058
23391
|
range.insertNode(fragment);
|
23059
23392
|
};
|
23060
23393
|
|
23394
|
+
/**
|
23395
|
+
* @public
|
23396
|
+
*
|
23397
|
+
* Remove this object (including starting and ending
|
23398
|
+
* placeholders).
|
23399
|
+
*
|
23400
|
+
* @method remove
|
23401
|
+
*/
|
23061
23402
|
removeFunc = function() {
|
23062
23403
|
// get a range for the current metamorph object including
|
23063
23404
|
// the starting and ending placeholders.
|
@@ -23098,7 +23439,7 @@ define("metamorph",
|
|
23098
23439
|
};
|
23099
23440
|
|
23100
23441
|
} else {
|
23101
|
-
|
23442
|
+
/*
|
23102
23443
|
* This code is mostly taken from jQuery, with one exception. In jQuery's case, we
|
23103
23444
|
* have some HTML and we need to figure out how to convert it into some nodes.
|
23104
23445
|
*
|
@@ -23152,12 +23493,12 @@ define("metamorph",
|
|
23152
23493
|
}
|
23153
23494
|
};
|
23154
23495
|
|
23155
|
-
|
23496
|
+
/*
|
23156
23497
|
* Given a parent node and some HTML, generate a set of nodes. Return the first
|
23157
23498
|
* node, which will allow us to traverse the rest using nextSibling.
|
23158
23499
|
*
|
23159
23500
|
* We need to do this because innerHTML in IE does not really parse the nodes.
|
23160
|
-
|
23501
|
+
*/
|
23161
23502
|
var firstNodeFor = function(parentNode, html) {
|
23162
23503
|
var arr = wrapMap[parentNode.tagName.toLowerCase()] || wrapMap._default;
|
23163
23504
|
var depth = arr[0], start = arr[1], end = arr[2];
|
@@ -23190,7 +23531,7 @@ define("metamorph",
|
|
23190
23531
|
return element;
|
23191
23532
|
};
|
23192
23533
|
|
23193
|
-
|
23534
|
+
/*
|
23194
23535
|
* In some cases, Internet Explorer can create an anonymous node in
|
23195
23536
|
* the hierarchy with no tagName. You can create this scenario via:
|
23196
23537
|
*
|
@@ -23200,7 +23541,7 @@ define("metamorph",
|
|
23200
23541
|
*
|
23201
23542
|
* If our script markers are inside such a node, we need to find that
|
23202
23543
|
* node and use *it* as the marker.
|
23203
|
-
|
23544
|
+
*/
|
23204
23545
|
var realNode = function(start) {
|
23205
23546
|
while (start.parentNode.tagName === "") {
|
23206
23547
|
start = start.parentNode;
|
@@ -23209,7 +23550,7 @@ define("metamorph",
|
|
23209
23550
|
return start;
|
23210
23551
|
};
|
23211
23552
|
|
23212
|
-
|
23553
|
+
/*
|
23213
23554
|
* When automatically adding a tbody, Internet Explorer inserts the
|
23214
23555
|
* tbody immediately before the first <tr>. Other browsers create it
|
23215
23556
|
* before the first node, no matter what.
|
@@ -23236,7 +23577,8 @@ define("metamorph",
|
|
23236
23577
|
*
|
23237
23578
|
* This code reparents the first script tag by making it the tbody's
|
23238
23579
|
* first child.
|
23239
|
-
|
23580
|
+
*
|
23581
|
+
*/
|
23240
23582
|
var fixParentage = function(start, end) {
|
23241
23583
|
if (start.parentNode !== end.parentNode) {
|
23242
23584
|
end.parentNode.insertBefore(start, end.parentNode.firstChild);
|
@@ -23434,20 +23776,6 @@ if (!Handlebars && typeof require === 'function') {
|
|
23434
23776
|
*/
|
23435
23777
|
Ember.Handlebars = objectCreate(Handlebars);
|
23436
23778
|
|
23437
|
-
function makeBindings(options) {
|
23438
|
-
var hash = options.hash,
|
23439
|
-
hashType = options.hashTypes;
|
23440
|
-
|
23441
|
-
for (var prop in hash) {
|
23442
|
-
if (hashType[prop] === 'ID') {
|
23443
|
-
hash[prop + 'Binding'] = hash[prop];
|
23444
|
-
hashType[prop + 'Binding'] = 'STRING';
|
23445
|
-
delete hash[prop];
|
23446
|
-
delete hashType[prop];
|
23447
|
-
}
|
23448
|
-
}
|
23449
|
-
}
|
23450
|
-
|
23451
23779
|
/**
|
23452
23780
|
Register a bound helper or custom view helper.
|
23453
23781
|
|
@@ -23507,7 +23835,6 @@ Ember.Handlebars.helper = function(name, value) {
|
|
23507
23835
|
if (Ember.View.detect(value)) {
|
23508
23836
|
Ember.Handlebars.registerHelper(name, function(options) {
|
23509
23837
|
|
23510
|
-
makeBindings(options);
|
23511
23838
|
return Ember.Handlebars.helpers.view.call(this, value, options);
|
23512
23839
|
});
|
23513
23840
|
} else {
|
@@ -23555,7 +23882,6 @@ if (Handlebars.JavaScriptCompiler) {
|
|
23555
23882
|
|
23556
23883
|
Ember.Handlebars.JavaScriptCompiler.prototype.namespace = "Ember.Handlebars";
|
23557
23884
|
|
23558
|
-
|
23559
23885
|
Ember.Handlebars.JavaScriptCompiler.prototype.initializeBuffer = function() {
|
23560
23886
|
return "''";
|
23561
23887
|
};
|
@@ -23659,7 +23985,7 @@ if (Handlebars.compile) {
|
|
23659
23985
|
|
23660
23986
|
var template = Ember.Handlebars.template(templateSpec);
|
23661
23987
|
template.isMethod = false; //Make sure we don't wrap templates with ._super
|
23662
|
-
|
23988
|
+
|
23663
23989
|
return template;
|
23664
23990
|
};
|
23665
23991
|
}
|
@@ -23927,7 +24253,8 @@ Ember.Handlebars.registerBoundHelper = function(name, fn) {
|
|
23927
24253
|
data = options.data,
|
23928
24254
|
hash = options.hash,
|
23929
24255
|
view = data.view,
|
23930
|
-
|
24256
|
+
contexts = options.contexts,
|
24257
|
+
currentContext = (contexts && contexts.length) ? contexts[0] : this,
|
23931
24258
|
prefixPathForDependentKeys = '',
|
23932
24259
|
loc, len, hashOption,
|
23933
24260
|
boundOption, property,
|
@@ -24051,7 +24378,7 @@ function evaluateUnboundHelper(context, fn, normalizedProperties, options) {
|
|
24051
24378
|
|
24052
24379
|
for(loc = 0, len = normalizedProperties.length; loc < len; ++loc) {
|
24053
24380
|
property = normalizedProperties[loc];
|
24054
|
-
args.push(Ember.Handlebars.get(
|
24381
|
+
args.push(Ember.Handlebars.get(property.root, property.path, options));
|
24055
24382
|
}
|
24056
24383
|
args.push(options);
|
24057
24384
|
return fn.apply(context, args);
|
@@ -24695,16 +25022,16 @@ function bind(property, options, preserveContext, shouldDisplay, valueNormalizer
|
|
24695
25022
|
}
|
24696
25023
|
}
|
24697
25024
|
|
24698
|
-
function simpleBind(property, options) {
|
25025
|
+
function simpleBind(currentContext, property, options) {
|
24699
25026
|
var data = options.data,
|
24700
25027
|
view = data.view,
|
24701
|
-
|
24702
|
-
normalized, observer;
|
25028
|
+
normalized, observer, pathRoot, output;
|
24703
25029
|
|
24704
25030
|
normalized = normalizePath(currentContext, property, data);
|
25031
|
+
pathRoot = normalized.root;
|
24705
25032
|
|
24706
25033
|
// Set up observers for observable objects
|
24707
|
-
if ('object' === typeof
|
25034
|
+
if (pathRoot && ('object' === typeof pathRoot)) {
|
24708
25035
|
if (data.insideGroup) {
|
24709
25036
|
observer = function() {
|
24710
25037
|
Ember.run.once(view, 'rerender');
|
@@ -24736,7 +25063,8 @@ function simpleBind(property, options) {
|
|
24736
25063
|
} else {
|
24737
25064
|
// The object is not observable, so just render it out and
|
24738
25065
|
// be done with it.
|
24739
|
-
|
25066
|
+
output = handlebarsGet(currentContext, property, options);
|
25067
|
+
data.buffer.push((output === null || typeof output === 'undefined') ? '' : output);
|
24740
25068
|
}
|
24741
25069
|
}
|
24742
25070
|
|
@@ -24793,10 +25121,10 @@ EmberHandlebars.registerHelper('_triageMustache', function(property, fn) {
|
|
24793
25121
|
EmberHandlebars.registerHelper('bind', function(property, options) {
|
24794
25122
|
|
24795
25123
|
|
24796
|
-
var context = (options.contexts && options.contexts[0]
|
25124
|
+
var context = (options.contexts && options.contexts.length) ? options.contexts[0] : this;
|
24797
25125
|
|
24798
25126
|
if (!options.fn) {
|
24799
|
-
return simpleBind
|
25127
|
+
return simpleBind(context, property, options);
|
24800
25128
|
}
|
24801
25129
|
|
24802
25130
|
return bind.call(context, property, options, false, exists);
|
@@ -24821,7 +25149,7 @@ EmberHandlebars.registerHelper('bind', function(property, options) {
|
|
24821
25149
|
@return {String} HTML string
|
24822
25150
|
*/
|
24823
25151
|
EmberHandlebars.registerHelper('boundIf', function(property, fn) {
|
24824
|
-
var context = (fn.contexts && fn.contexts[0]
|
25152
|
+
var context = (fn.contexts && fn.contexts.length) ? fn.contexts[0] : this;
|
24825
25153
|
var func = function(result) {
|
24826
25154
|
var truthy = result && get(result, 'isTruthy');
|
24827
25155
|
if (typeof truthy === 'boolean') { return truthy; }
|
@@ -25265,6 +25593,35 @@ var EmberHandlebars = Ember.Handlebars;
|
|
25265
25593
|
var LOWERCASE_A_Z = /^[a-z]/;
|
25266
25594
|
var VIEW_PREFIX = /^view\./;
|
25267
25595
|
|
25596
|
+
function makeBindings(thisContext, options) {
|
25597
|
+
var hash = options.hash,
|
25598
|
+
hashType = options.hashTypes;
|
25599
|
+
|
25600
|
+
for (var prop in hash) {
|
25601
|
+
if (hashType[prop] === 'ID') {
|
25602
|
+
|
25603
|
+
var value = hash[prop];
|
25604
|
+
|
25605
|
+
if (Ember.IS_BINDING.test(prop)) {
|
25606
|
+
|
25607
|
+
} else {
|
25608
|
+
hash[prop + 'Binding'] = value;
|
25609
|
+
hashType[prop + 'Binding'] = 'STRING';
|
25610
|
+
delete hash[prop];
|
25611
|
+
delete hashType[prop];
|
25612
|
+
}
|
25613
|
+
}
|
25614
|
+
}
|
25615
|
+
|
25616
|
+
if (hash.hasOwnProperty('idBinding')) {
|
25617
|
+
// id can't be bound, so just perform one-time lookup.
|
25618
|
+
hash.id = EmberHandlebars.get(thisContext, hash.idBinding, options);
|
25619
|
+
hashType.id = 'STRING';
|
25620
|
+
delete hash.idBinding;
|
25621
|
+
delete hashType.idBinding;
|
25622
|
+
}
|
25623
|
+
}
|
25624
|
+
|
25268
25625
|
EmberHandlebars.ViewHelper = Ember.Object.create({
|
25269
25626
|
|
25270
25627
|
propertiesFromHTMLOptions: function(options, thisContext) {
|
@@ -25374,6 +25731,8 @@ EmberHandlebars.ViewHelper = Ember.Object.create({
|
|
25374
25731
|
fn = options.fn,
|
25375
25732
|
newView;
|
25376
25733
|
|
25734
|
+
makeBindings(thisContext, options);
|
25735
|
+
|
25377
25736
|
if ('string' === typeof path) {
|
25378
25737
|
|
25379
25738
|
// TODO: this is a lame conditional, this should likely change
|
@@ -25861,7 +26220,7 @@ Ember.Handlebars.registerHelper('unbound', function(property, fn) {
|
|
25861
26220
|
return out;
|
25862
26221
|
}
|
25863
26222
|
|
25864
|
-
context = (fn.contexts && fn.contexts[0]
|
26223
|
+
context = (fn.contexts && fn.contexts.length) ? fn.contexts[0] : this;
|
25865
26224
|
return handlebarsGet(context, property, fn);
|
25866
26225
|
});
|
25867
26226
|
|
@@ -25891,7 +26250,7 @@ var handlebarsGet = Ember.Handlebars.get, normalizePath = Ember.Handlebars.norma
|
|
25891
26250
|
@param {String} property
|
25892
26251
|
*/
|
25893
26252
|
Ember.Handlebars.registerHelper('log', function(property, options) {
|
25894
|
-
var context = (options.contexts && options.contexts[0]
|
26253
|
+
var context = (options.contexts && options.contexts.length) ? options.contexts[0] : this,
|
25895
26254
|
normalized = normalizePath(context, property, options.data),
|
25896
26255
|
pathRoot = normalized.root,
|
25897
26256
|
path = normalized.path,
|
@@ -26446,7 +26805,6 @@ Ember.Handlebars.registerHelper('partial', function(name, options) {
|
|
26446
26805
|
var get = Ember.get, set = Ember.set;
|
26447
26806
|
|
26448
26807
|
/**
|
26449
|
-
|
26450
26808
|
`{{yield}}` denotes an area of a template that will be rendered inside
|
26451
26809
|
of another template. It has two main uses:
|
26452
26810
|
|
@@ -26505,11 +26863,11 @@ var get = Ember.get, set = Ember.set;
|
|
26505
26863
|
<!-- application.hbs -->
|
26506
26864
|
{{#labeled-textfield value=someProperty}}
|
26507
26865
|
First name:
|
26508
|
-
{{/
|
26866
|
+
{{/labeled-textfield}}
|
26509
26867
|
```
|
26510
26868
|
|
26511
26869
|
```handlebars
|
26512
|
-
<!-- components/
|
26870
|
+
<!-- components/labeled-textfield.hbs -->
|
26513
26871
|
<label>
|
26514
26872
|
{{yield}} {{input value=value}}
|
26515
26873
|
</label>
|
@@ -26706,7 +27064,7 @@ Ember.TextSupport = Ember.Mixin.create({
|
|
26706
27064
|
Options are:
|
26707
27065
|
|
26708
27066
|
* `enter`: the user pressed enter
|
26709
|
-
* `
|
27067
|
+
* `keyPress`: the user pressed a key
|
26710
27068
|
|
26711
27069
|
@property onEvent
|
26712
27070
|
@type String
|
@@ -26749,7 +27107,7 @@ Ember.TextSupport = Ember.Mixin.create({
|
|
26749
27107
|
Called by the `Ember.TextSupport` mixin on keyUp if keycode matches 13.
|
26750
27108
|
Uses sendAction to send the `enter` action to the controller.
|
26751
27109
|
|
26752
|
-
@method
|
27110
|
+
@method insertNewline
|
26753
27111
|
@param {Event} event
|
26754
27112
|
*/
|
26755
27113
|
insertNewline: function(event) {
|
@@ -26760,8 +27118,8 @@ Ember.TextSupport = Ember.Mixin.create({
|
|
26760
27118
|
/**
|
26761
27119
|
Called when the user hits escape.
|
26762
27120
|
|
26763
|
-
Called by the `Ember.TextSupport` mixin on keyUp if keycode matches
|
26764
|
-
Uses sendAction to send the `
|
27121
|
+
Called by the `Ember.TextSupport` mixin on keyUp if keycode matches 27.
|
27122
|
+
Uses sendAction to send the `escape-press` action to the controller.
|
26765
27123
|
|
26766
27124
|
@method cancel
|
26767
27125
|
@param {Event} event
|
@@ -26851,7 +27209,7 @@ var get = Ember.get, set = Ember.set;
|
|
26851
27209
|
The internal class used to create text inputs when the `{{input}}`
|
26852
27210
|
helper is used with `type` of `text`.
|
26853
27211
|
|
26854
|
-
See Handlebars.helpers.
|
27212
|
+
See [handlebars.helpers.input](api/classes/Ember.Handlebars.helpers.html#method_input) for usage details.
|
26855
27213
|
|
26856
27214
|
## Layout and LayoutName properties
|
26857
27215
|
|
@@ -26861,7 +27219,7 @@ var get = Ember.get, set = Ember.set;
|
|
26861
27219
|
|
26862
27220
|
@class TextField
|
26863
27221
|
@namespace Ember
|
26864
|
-
@extends Ember.
|
27222
|
+
@extends Ember.Component
|
26865
27223
|
@uses Ember.TextSupport
|
26866
27224
|
*/
|
26867
27225
|
Ember.TextField = Ember.Component.extend(Ember.TextSupport,
|
@@ -27053,7 +27411,7 @@ var get = Ember.get, set = Ember.set;
|
|
27053
27411
|
The internal class used to create textarea element when the `{{textarea}}`
|
27054
27412
|
helper is used.
|
27055
27413
|
|
27056
|
-
See handlebars.helpers.textarea
|
27414
|
+
See [handlebars.helpers.textarea](/api/classes/Ember.Handlebars.helpers.html#method_textarea) for usage details.
|
27057
27415
|
|
27058
27416
|
## Layout and LayoutName properties
|
27059
27417
|
|
@@ -27063,7 +27421,7 @@ var get = Ember.get, set = Ember.set;
|
|
27063
27421
|
|
27064
27422
|
@class TextArea
|
27065
27423
|
@namespace Ember
|
27066
|
-
@extends Ember.
|
27424
|
+
@extends Ember.Component
|
27067
27425
|
@uses Ember.TextSupport
|
27068
27426
|
*/
|
27069
27427
|
Ember.TextArea = Ember.Component.extend(Ember.TextSupport, {
|
@@ -27182,7 +27540,7 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
|
|
27182
27540
|
`content` property. The underlying data object of the selected `<option>` is
|
27183
27541
|
stored in the `Element.Select`'s `value` property.
|
27184
27542
|
|
27185
|
-
|
27543
|
+
## The Content Property (array of strings)
|
27186
27544
|
|
27187
27545
|
The simplest version of an `Ember.Select` takes an array of strings as its
|
27188
27546
|
`content` property. The string will be used as both the `value` property and
|
@@ -27197,7 +27555,7 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
|
|
27197
27555
|
```
|
27198
27556
|
|
27199
27557
|
```handlebars
|
27200
|
-
{{view Ember.Select
|
27558
|
+
{{view Ember.Select content=names}}
|
27201
27559
|
```
|
27202
27560
|
|
27203
27561
|
Would result in the following HTML:
|
@@ -27210,7 +27568,7 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
|
|
27210
27568
|
```
|
27211
27569
|
|
27212
27570
|
You can control which `<option>` is selected through the `Ember.Select`'s
|
27213
|
-
`value` property
|
27571
|
+
`value` property:
|
27214
27572
|
|
27215
27573
|
```javascript
|
27216
27574
|
App.ApplicationController = Ember.Controller.extend({
|
@@ -27221,8 +27579,8 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
|
|
27221
27579
|
|
27222
27580
|
```handlebars
|
27223
27581
|
{{view Ember.Select
|
27224
|
-
|
27225
|
-
|
27582
|
+
content=names
|
27583
|
+
value=selectedName
|
27226
27584
|
}}
|
27227
27585
|
```
|
27228
27586
|
|
@@ -27238,7 +27596,7 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
|
|
27238
27596
|
A user interacting with the rendered `<select>` to choose "Yehuda" would
|
27239
27597
|
update the value of `selectedName` to "Yehuda".
|
27240
27598
|
|
27241
|
-
|
27599
|
+
## The Content Property (array of Objects)
|
27242
27600
|
|
27243
27601
|
An `Ember.Select` can also take an array of JavaScript or Ember objects as
|
27244
27602
|
its `content` property.
|
@@ -27263,7 +27621,7 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
|
|
27263
27621
|
|
27264
27622
|
```handlebars
|
27265
27623
|
{{view Ember.Select
|
27266
|
-
|
27624
|
+
content=programmers
|
27267
27625
|
optionValuePath="content.id"
|
27268
27626
|
optionLabelPath="content.firstName"}}
|
27269
27627
|
```
|
@@ -27278,8 +27636,7 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
|
|
27278
27636
|
```
|
27279
27637
|
|
27280
27638
|
The `value` attribute of the selected `<option>` within an `Ember.Select`
|
27281
|
-
can be bound to a property on another object
|
27282
|
-
`valueBinding` option:
|
27639
|
+
can be bound to a property on another object:
|
27283
27640
|
|
27284
27641
|
```javascript
|
27285
27642
|
App.ApplicationController = Ember.Controller.extend({
|
@@ -27295,10 +27652,10 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
|
|
27295
27652
|
|
27296
27653
|
```handlebars
|
27297
27654
|
{{view Ember.Select
|
27298
|
-
|
27655
|
+
content=programmers
|
27299
27656
|
optionValuePath="content.id"
|
27300
27657
|
optionLabelPath="content.firstName"
|
27301
|
-
|
27658
|
+
value=currentProgrammer.id}}
|
27302
27659
|
```
|
27303
27660
|
|
27304
27661
|
Would result in the following HTML with a selected option:
|
@@ -27315,8 +27672,8 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
|
|
27315
27672
|
to match the `value` property of the newly selected `<option>`.
|
27316
27673
|
|
27317
27674
|
Alternatively, you can control selection through the underlying objects
|
27318
|
-
used to render each object
|
27319
|
-
`<option>` is changed, the property path provided to `
|
27675
|
+
used to render each object by binding the `selection` option. When the selected
|
27676
|
+
`<option>` is changed, the property path provided to `selection`
|
27320
27677
|
will be updated to match the content object of the rendered `<option>`
|
27321
27678
|
element:
|
27322
27679
|
|
@@ -27332,10 +27689,10 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
|
|
27332
27689
|
|
27333
27690
|
```handlebars
|
27334
27691
|
{{view Ember.Select
|
27335
|
-
|
27692
|
+
content=programmers
|
27336
27693
|
optionValuePath="content.id"
|
27337
27694
|
optionLabelPath="content.firstName"
|
27338
|
-
|
27695
|
+
selection=selectedPerson}}
|
27339
27696
|
```
|
27340
27697
|
|
27341
27698
|
Would result in the following HTML with a selected option:
|
@@ -27348,11 +27705,11 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
|
|
27348
27705
|
```
|
27349
27706
|
|
27350
27707
|
Interacting with the rendered element by selecting the first option
|
27351
|
-
('Yehuda') will update the `selectedPerson` to match the object of
|
27708
|
+
('Yehuda') will update the `selectedPerson` to match the object of
|
27352
27709
|
the newly selected `<option>`. In this case it is the first object
|
27353
27710
|
in the `programmers`
|
27354
27711
|
|
27355
|
-
|
27712
|
+
## Supplying a Prompt
|
27356
27713
|
|
27357
27714
|
A `null` value for the `Ember.Select`'s `value` or `selection` property
|
27358
27715
|
results in there being no `<option>` with a `selected` attribute:
|
@@ -27369,8 +27726,8 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
|
|
27369
27726
|
|
27370
27727
|
``` handlebars
|
27371
27728
|
{{view Ember.Select
|
27372
|
-
|
27373
|
-
|
27729
|
+
content=programmers
|
27730
|
+
value=selectedProgrammer
|
27374
27731
|
}}
|
27375
27732
|
```
|
27376
27733
|
|
@@ -27401,8 +27758,8 @@ Ember.SelectOptgroup = Ember.CollectionView.extend({
|
|
27401
27758
|
|
27402
27759
|
```handlebars
|
27403
27760
|
{{view Ember.Select
|
27404
|
-
|
27405
|
-
|
27761
|
+
content=programmers
|
27762
|
+
value=selectedProgrammer
|
27406
27763
|
prompt="Please select a name"
|
27407
27764
|
}}
|
27408
27765
|
```
|
@@ -27454,11 +27811,11 @@ function program3(depth0,data) {
|
|
27454
27811
|
function program4(depth0,data) {
|
27455
27812
|
|
27456
27813
|
var hashContexts, hashTypes;
|
27457
|
-
hashContexts = {'
|
27458
|
-
hashTypes = {'
|
27814
|
+
hashContexts = {'content': depth0,'label': depth0};
|
27815
|
+
hashTypes = {'content': "ID",'label': "ID"};
|
27459
27816
|
data.buffer.push(escapeExpression(helpers.view.call(depth0, "view.groupView", {hash:{
|
27460
|
-
'
|
27461
|
-
'
|
27817
|
+
'content': ("content"),
|
27818
|
+
'label': ("label")
|
27462
27819
|
},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
27463
27820
|
}
|
27464
27821
|
|
@@ -27474,10 +27831,10 @@ function program6(depth0,data) {
|
|
27474
27831
|
function program7(depth0,data) {
|
27475
27832
|
|
27476
27833
|
var hashContexts, hashTypes;
|
27477
|
-
hashContexts = {'
|
27478
|
-
hashTypes = {'
|
27834
|
+
hashContexts = {'content': depth0};
|
27835
|
+
hashTypes = {'content': "ID"};
|
27479
27836
|
data.buffer.push(escapeExpression(helpers.view.call(depth0, "view.optionView", {hash:{
|
27480
|
-
'
|
27837
|
+
'content': ("")
|
27481
27838
|
},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
|
27482
27839
|
}
|
27483
27840
|
|
@@ -27508,7 +27865,7 @@ function program7(depth0,data) {
|
|
27508
27865
|
The `disabled` attribute of the select element. Indicates whether
|
27509
27866
|
the element is disabled from interactions.
|
27510
27867
|
|
27511
|
-
@property
|
27868
|
+
@property disabled
|
27512
27869
|
@type Boolean
|
27513
27870
|
@default false
|
27514
27871
|
*/
|
@@ -27617,8 +27974,9 @@ function program7(depth0,data) {
|
|
27617
27974
|
groupedContent: Ember.computed(function() {
|
27618
27975
|
var groupPath = get(this, 'optionGroupPath');
|
27619
27976
|
var groupedContent = Ember.A();
|
27977
|
+
var content = get(this, 'content') || [];
|
27620
27978
|
|
27621
|
-
forEach(
|
27979
|
+
forEach(content, function(item) {
|
27622
27980
|
var label = get(item, groupPath);
|
27623
27981
|
|
27624
27982
|
if (get(groupedContent, 'lastObject.label') !== label) {
|
@@ -27770,18 +28128,9 @@ function program7(depth0,data) {
|
|
27770
28128
|
(function() {
|
27771
28129
|
/**
|
27772
28130
|
@module ember
|
27773
|
-
@submodule ember-handlebars
|
28131
|
+
@submodule ember-handlebars-compiler
|
27774
28132
|
*/
|
27775
28133
|
|
27776
|
-
function normalizeHash(hash, hashTypes) {
|
27777
|
-
for (var prop in hash) {
|
27778
|
-
if (hashTypes[prop] === 'ID') {
|
27779
|
-
hash[prop + 'Binding'] = hash[prop];
|
27780
|
-
delete hash[prop];
|
27781
|
-
}
|
27782
|
-
}
|
27783
|
-
}
|
27784
|
-
|
27785
28134
|
/**
|
27786
28135
|
|
27787
28136
|
The `{{input}}` helper inserts an HTML `<input>` tag into the template,
|
@@ -27793,30 +28142,32 @@ function normalizeHash(hash, hashTypes) {
|
|
27793
28142
|
An `{{input}}` with no `type` or a `type` of `text` will render an HTML text input.
|
27794
28143
|
The following HTML attributes can be set via the helper:
|
27795
28144
|
|
27796
|
-
|
27797
|
-
|
27798
|
-
|
27799
|
-
|
27800
|
-
|
27801
|
-
|
27802
|
-
|
27803
|
-
|
28145
|
+
* `value`
|
28146
|
+
* `size`
|
28147
|
+
* `name`
|
28148
|
+
* `pattern`
|
28149
|
+
* `placeholder`
|
28150
|
+
* `disabled`
|
28151
|
+
* `maxlength`
|
28152
|
+
* `tabindex`
|
28153
|
+
|
27804
28154
|
|
27805
28155
|
When set to a quoted string, these values will be directly applied to the HTML
|
27806
28156
|
element. When left unquoted, these values will be bound to a property on the
|
27807
28157
|
template's current rendering context (most typically a controller instance).
|
27808
28158
|
|
27809
|
-
Unbound:
|
28159
|
+
## Unbound:
|
27810
28160
|
|
27811
28161
|
```handlebars
|
27812
28162
|
{{input value="http://www.facebook.com"}}
|
27813
28163
|
```
|
27814
28164
|
|
28165
|
+
|
27815
28166
|
```html
|
27816
28167
|
<input type="text" value="http://www.facebook.com"/>
|
27817
28168
|
```
|
27818
28169
|
|
27819
|
-
Bound:
|
28170
|
+
## Bound:
|
27820
28171
|
|
27821
28172
|
```javascript
|
27822
28173
|
App.ApplicationController = Ember.Controller.extend({
|
@@ -27825,15 +28176,18 @@ function normalizeHash(hash, hashTypes) {
|
|
27825
28176
|
});
|
27826
28177
|
```
|
27827
28178
|
|
28179
|
+
|
27828
28180
|
```handlebars
|
27829
28181
|
{{input type="text" value=firstName disabled=entryNotAllowed size="50"}}
|
27830
28182
|
```
|
27831
28183
|
|
28184
|
+
|
27832
28185
|
```html
|
27833
28186
|
<input type="text" value="Stanley" disabled="disabled" size="50"/>
|
27834
28187
|
```
|
27835
28188
|
|
27836
|
-
|
28189
|
+
## Extension
|
28190
|
+
|
27837
28191
|
Internally, `{{input type="text"}}` creates an instance of `Ember.TextField`, passing
|
27838
28192
|
arguments from the helper to `Ember.TextField`'s `create` method. You can extend the
|
27839
28193
|
capablilties of text inputs in your applications by reopening this class. For example,
|
@@ -27846,21 +28200,29 @@ function normalizeHash(hash, hashTypes) {
|
|
27846
28200
|
});
|
27847
28201
|
```
|
27848
28202
|
|
28203
|
+
Keep in mind when writing `Ember.TextField` subclasses that `Ember.TextField`
|
28204
|
+
itself extends `Ember.Component`, meaning that it does NOT inherit
|
28205
|
+
the `controller` of the parent view.
|
28206
|
+
|
28207
|
+
See more about [Ember components](api/classes/Ember.Component.html)
|
28208
|
+
|
28209
|
+
|
27849
28210
|
## Use as checkbox
|
28211
|
+
|
27850
28212
|
An `{{input}}` with a `type` of `checkbox` will render an HTML checkbox input.
|
27851
28213
|
The following HTML attributes can be set via the helper:
|
27852
28214
|
|
27853
|
-
|
27854
|
-
|
27855
|
-
|
27856
|
-
|
27857
|
-
|
28215
|
+
* `checked`
|
28216
|
+
* `disabled`
|
28217
|
+
* `tabindex`
|
28218
|
+
* `indeterminate`
|
28219
|
+
* `name`
|
27858
28220
|
|
27859
28221
|
When set to a quoted string, these values will be directly applied to the HTML
|
27860
28222
|
element. When left unquoted, these values will be bound to a property on the
|
27861
28223
|
template's current rendering context (most typically a controller instance).
|
27862
28224
|
|
27863
|
-
Unbound:
|
28225
|
+
## Unbound:
|
27864
28226
|
|
27865
28227
|
```handlebars
|
27866
28228
|
{{input type="checkbox" name="isAdmin"}}
|
@@ -27870,7 +28232,7 @@ function normalizeHash(hash, hashTypes) {
|
|
27870
28232
|
<input type="checkbox" name="isAdmin" />
|
27871
28233
|
```
|
27872
28234
|
|
27873
|
-
Bound:
|
28235
|
+
## Bound:
|
27874
28236
|
|
27875
28237
|
```javascript
|
27876
28238
|
App.ApplicationController = Ember.Controller.extend({
|
@@ -27878,15 +28240,18 @@ function normalizeHash(hash, hashTypes) {
|
|
27878
28240
|
});
|
27879
28241
|
```
|
27880
28242
|
|
28243
|
+
|
27881
28244
|
```handlebars
|
27882
28245
|
{{input type="checkbox" checked=isAdmin }}
|
27883
28246
|
```
|
27884
28247
|
|
28248
|
+
|
27885
28249
|
```html
|
27886
28250
|
<input type="checkbox" checked="checked" />
|
27887
28251
|
```
|
27888
28252
|
|
27889
|
-
|
28253
|
+
## Extension
|
28254
|
+
|
27890
28255
|
Internally, `{{input type="checkbox"}}` creates an instance of `Ember.Checkbox`, passing
|
27891
28256
|
arguments from the helper to `Ember.Checkbox`'s `create` method. You can extend the
|
27892
28257
|
capablilties of checkbox inputs in your applications by reopening this class. For example,
|
@@ -27898,6 +28263,7 @@ function normalizeHash(hash, hashTypes) {
|
|
27898
28263
|
});
|
27899
28264
|
```
|
27900
28265
|
|
28266
|
+
|
27901
28267
|
@method input
|
27902
28268
|
@for Ember.Handlebars.helpers
|
27903
28269
|
@param {Hash} options
|
@@ -27913,8 +28279,6 @@ Ember.Handlebars.registerHelper('input', function(options) {
|
|
27913
28279
|
delete hash.type;
|
27914
28280
|
delete hash.on;
|
27915
28281
|
|
27916
|
-
normalizeHash(hash, types);
|
27917
|
-
|
27918
28282
|
if (inputType === 'checkbox') {
|
27919
28283
|
return Ember.Handlebars.helpers.view.call(this, Ember.Checkbox, options);
|
27920
28284
|
} else {
|
@@ -28044,7 +28408,7 @@ Ember.Handlebars.registerHelper('input', function(options) {
|
|
28044
28408
|
</textarea>
|
28045
28409
|
```
|
28046
28410
|
|
28047
|
-
|
28411
|
+
## Extension
|
28048
28412
|
|
28049
28413
|
Internally, `{{textarea}}` creates an instance of `Ember.TextArea`, passing
|
28050
28414
|
arguments from the helper to `Ember.TextArea`'s `create` method. You can
|
@@ -28061,6 +28425,12 @@ Ember.Handlebars.registerHelper('input', function(options) {
|
|
28061
28425
|
});
|
28062
28426
|
```
|
28063
28427
|
|
28428
|
+
Keep in mind when writing `Ember.TextArea` subclasses that `Ember.TextArea`
|
28429
|
+
itself extends `Ember.Component`, meaning that it does NOT inherit
|
28430
|
+
the `controller` of the parent view.
|
28431
|
+
|
28432
|
+
See more about [Ember components](api/classes/Ember.Component.html)
|
28433
|
+
|
28064
28434
|
@method textarea
|
28065
28435
|
@for Ember.Handlebars.helpers
|
28066
28436
|
@param {Hash} options
|
@@ -28071,7 +28441,6 @@ Ember.Handlebars.registerHelper('textarea', function(options) {
|
|
28071
28441
|
var hash = options.hash,
|
28072
28442
|
types = options.hashTypes;
|
28073
28443
|
|
28074
|
-
normalizeHash(hash, types);
|
28075
28444
|
return Ember.Handlebars.helpers.view.call(this, Ember.TextArea, options);
|
28076
28445
|
});
|
28077
28446
|
|
@@ -28122,7 +28491,7 @@ Ember.Handlebars.bootstrap = function(ctx) {
|
|
28122
28491
|
|
28123
28492
|
// Check if template of same name already exists
|
28124
28493
|
if (Ember.TEMPLATES[templateName] !== undefined) {
|
28125
|
-
throw new Error('Template named "' + templateName + '" already exists.');
|
28494
|
+
throw new Ember.Error('Template named "' + templateName + '" already exists.');
|
28126
28495
|
}
|
28127
28496
|
|
28128
28497
|
// For templates which have a name, we save them and then remove them from the DOM
|
@@ -28152,13 +28521,14 @@ function registerComponents(container) {
|
|
28152
28521
|
function registerComponent(container, name) {
|
28153
28522
|
|
28154
28523
|
|
28155
|
-
container.injection('component:' + name, 'layout', 'template:components/' + name);
|
28156
|
-
|
28157
28524
|
var fullName = 'component:' + name;
|
28525
|
+
|
28526
|
+
container.injection(fullName, 'layout', 'template:components/' + name);
|
28527
|
+
|
28158
28528
|
var Component = container.lookupFactory(fullName);
|
28159
28529
|
|
28160
28530
|
if (!Component) {
|
28161
|
-
container.register(
|
28531
|
+
container.register(fullName, Ember.Component);
|
28162
28532
|
Component = container.lookupFactory(fullName);
|
28163
28533
|
}
|
28164
28534
|
|
@@ -30174,8 +30544,12 @@ Ember.Router = Ember.Object.extend({
|
|
30174
30544
|
|
30175
30545
|
if (name === 'application') {
|
30176
30546
|
// Inject default `error` handler.
|
30177
|
-
|
30178
|
-
|
30547
|
+
// Note: `events` is deprecated, but we'll let the
|
30548
|
+
// deprecation warnings be handled at event-handling time rather
|
30549
|
+
// than duplicating that logic here.
|
30550
|
+
var actions = handler._actions || handler.events;
|
30551
|
+
if (!actions) { actions = handler._actions = {}; }
|
30552
|
+
actions.error = actions.error || Ember.Router._defaultErrorHandler;
|
30179
30553
|
}
|
30180
30554
|
|
30181
30555
|
handler.routeName = name;
|
@@ -30241,8 +30615,10 @@ Ember.Router = Ember.Object.extend({
|
|
30241
30615
|
|
30242
30616
|
transitionPromise.then(function(route) {
|
30243
30617
|
self._transitionCompleted(route);
|
30244
|
-
}, function(error){
|
30618
|
+
}, function(error) {
|
30619
|
+
if (error.name === "UnrecognizedURLError") {
|
30245
30620
|
|
30621
|
+
}
|
30246
30622
|
});
|
30247
30623
|
|
30248
30624
|
// We want to return the configurable promise object
|
@@ -30288,7 +30664,7 @@ function triggerEvent(handlerInfos, ignoreFailure, args) {
|
|
30288
30664
|
|
30289
30665
|
if (!handlerInfos) {
|
30290
30666
|
if (ignoreFailure) { return; }
|
30291
|
-
throw new Error("Could not trigger event '" + name + "'. There are no active handlers");
|
30667
|
+
throw new Ember.Error("Could not trigger event '" + name + "'. There are no active handlers");
|
30292
30668
|
}
|
30293
30669
|
|
30294
30670
|
var eventWasHandled = false;
|
@@ -30314,7 +30690,7 @@ function triggerEvent(handlerInfos, ignoreFailure, args) {
|
|
30314
30690
|
}
|
30315
30691
|
|
30316
30692
|
if (!eventWasHandled && !ignoreFailure) {
|
30317
|
-
throw new Error("Nothing handled the event '" + name + "'.");
|
30693
|
+
throw new Ember.Error("Nothing handled the event '" + name + "'.");
|
30318
30694
|
}
|
30319
30695
|
}
|
30320
30696
|
|
@@ -30633,6 +31009,7 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
|
|
30633
31009
|
@deprecated
|
30634
31010
|
|
30635
31011
|
Please use `actions` instead.
|
31012
|
+
@method events
|
30636
31013
|
*/
|
30637
31014
|
events: null,
|
30638
31015
|
|
@@ -30655,11 +31032,13 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
|
|
30655
31032
|
activate: Ember.K,
|
30656
31033
|
|
30657
31034
|
/**
|
30658
|
-
Transition into another route. Optionally supply
|
30659
|
-
route in question.
|
30660
|
-
|
31035
|
+
Transition into another route. Optionally supply model(s) for the
|
31036
|
+
route in question. If multiple models are supplied they will be applied
|
31037
|
+
last to first recursively up the resource tree (see Multiple Models Example
|
31038
|
+
below). The model(s) will be serialized into the URL using the appropriate
|
31039
|
+
route's `serialize` hook. See also 'replaceWith'.
|
30661
31040
|
|
30662
|
-
Example
|
31041
|
+
Simple Transition Example
|
30663
31042
|
|
30664
31043
|
```javascript
|
30665
31044
|
App.Router.map(function() {
|
@@ -30680,9 +31059,31 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
|
|
30680
31059
|
});
|
30681
31060
|
```
|
30682
31061
|
|
31062
|
+
Multiple Models Example
|
31063
|
+
|
31064
|
+
```javascript
|
31065
|
+
App.Router.map(function() {
|
31066
|
+
this.route("index");
|
31067
|
+
this.resource('breakfast', {path:':breakfastId'}, function(){
|
31068
|
+
this.resource('cereal', {path: ':cerealId'});
|
31069
|
+
});
|
31070
|
+
});
|
31071
|
+
|
31072
|
+
App.IndexRoute = Ember.Route.extend({
|
31073
|
+
actions: {
|
31074
|
+
moveToChocolateCereal: function(){
|
31075
|
+
var cereal = { cerealId: "ChocolateYumminess"},
|
31076
|
+
breakfast = {breakfastId: "CerealAndMilk"};
|
31077
|
+
|
31078
|
+
this.transitionTo('cereal', breakfast, cereal);
|
31079
|
+
}
|
31080
|
+
}
|
31081
|
+
});
|
31082
|
+
|
30683
31083
|
@method transitionTo
|
30684
31084
|
@param {String} name the name of the route
|
30685
|
-
@param {...Object} models
|
31085
|
+
@param {...Object} models the model(s) to be used while transitioning
|
31086
|
+
to the route.
|
30686
31087
|
*/
|
30687
31088
|
transitionTo: function(name, context) {
|
30688
31089
|
var router = this.router;
|
@@ -30690,8 +31091,10 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
|
|
30690
31091
|
},
|
30691
31092
|
|
30692
31093
|
/**
|
30693
|
-
Transition into another route while replacing the current URL if
|
30694
|
-
|
31094
|
+
Transition into another route while replacing the current URL, if possible.
|
31095
|
+
This will replace the current history entry instead of adding a new one.
|
31096
|
+
Beside that, it is identical to `transitionTo` in all other respects. See
|
31097
|
+
'transitionTo' for additional information regarding multiple models.
|
30695
31098
|
|
30696
31099
|
Example
|
30697
31100
|
|
@@ -30712,7 +31115,8 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
|
|
30712
31115
|
|
30713
31116
|
@method replaceWith
|
30714
31117
|
@param {String} name the name of the route
|
30715
|
-
@param {...Object} models
|
31118
|
+
@param {...Object} models the model(s) to be used while transitioning
|
31119
|
+
to the route.
|
30716
31120
|
*/
|
30717
31121
|
replaceWith: function() {
|
30718
31122
|
var router = this.router;
|
@@ -30791,15 +31195,15 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
|
|
30791
31195
|
},
|
30792
31196
|
|
30793
31197
|
/**
|
30794
|
-
@deprecated
|
30795
|
-
|
30796
31198
|
A hook you can implement to optionally redirect to another route.
|
30797
31199
|
|
30798
31200
|
If you call `this.transitionTo` from inside of this hook, this route
|
30799
31201
|
will not be entered in favor of the other hook.
|
30800
31202
|
|
30801
|
-
|
30802
|
-
|
31203
|
+
Note that this hook is called by the default implementation of
|
31204
|
+
`afterModel`, so if you override `afterModel`, you must either
|
31205
|
+
explicitly call `redirect` or just put your redirecting
|
31206
|
+
`this.transitionTo()` call within `afterModel`.
|
30803
31207
|
|
30804
31208
|
@method redirect
|
30805
31209
|
@param {Object} model the model for this route
|
@@ -30893,7 +31297,7 @@ Ember.Route = Ember.Object.extend(Ember.ActionHandler, {
|
|
30893
31297
|
resolved.
|
30894
31298
|
|
30895
31299
|
```js
|
30896
|
-
App.
|
31300
|
+
App.PostsRoute = Ember.Route.extend({
|
30897
31301
|
afterModel: function(posts, transition) {
|
30898
31302
|
if (posts.length === 1) {
|
30899
31303
|
this.transitionTo('post.show', posts[0]);
|
@@ -31809,6 +32213,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
|
31809
32213
|
|
31810
32214
|
This method is invoked by observers installed during `init` that fire
|
31811
32215
|
whenever the helpers
|
32216
|
+
@method _paramsChanged
|
31812
32217
|
*/
|
31813
32218
|
_paramsChanged: function() {
|
31814
32219
|
this.notifyPropertyChange('resolvedParams');
|
@@ -31981,7 +32386,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
|
31981
32386
|
@property href
|
31982
32387
|
**/
|
31983
32388
|
href: Ember.computed(function() {
|
31984
|
-
if (get(this, 'tagName') !== 'a') { return
|
32389
|
+
if (get(this, 'tagName') !== 'a') { return; }
|
31985
32390
|
|
31986
32391
|
var router = get(this, 'router'),
|
31987
32392
|
routeArgs = get(this, 'routeArgs');
|
@@ -32040,7 +32445,44 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
|
32040
32445
|
|
32041
32446
|
To override this option for your entire application, see
|
32042
32447
|
"Overriding Application-wide Defaults".
|
32043
|
-
|
32448
|
+
|
32449
|
+
### Disabling the `link-to` helper
|
32450
|
+
By default `{{link-to}}` is enabled.
|
32451
|
+
any passed value to `disabled` helper property will disable the `link-to` helper.
|
32452
|
+
|
32453
|
+
static use: the `disabled` option:
|
32454
|
+
|
32455
|
+
```handlebars
|
32456
|
+
{{#link-to 'photoGallery' disabled=true}}
|
32457
|
+
Great Hamster Photos
|
32458
|
+
{{/link-to}}
|
32459
|
+
```
|
32460
|
+
|
32461
|
+
dynamic use: the `disabledWhen` option:
|
32462
|
+
|
32463
|
+
```handlebars
|
32464
|
+
{{#link-to 'photoGallery' disabledWhen=controller.someProperty}}
|
32465
|
+
Great Hamster Photos
|
32466
|
+
{{/link-to}}
|
32467
|
+
```
|
32468
|
+
|
32469
|
+
any passed value to `disabled` will disable it except `undefined`.
|
32470
|
+
to ensure that only `true` disable the `link-to` helper you can
|
32471
|
+
override the global behaviour of `Ember.LinkView`.
|
32472
|
+
|
32473
|
+
```javascript
|
32474
|
+
Ember.LinkView.reopen({
|
32475
|
+
disabled: Ember.computed(function(key, value) {
|
32476
|
+
if (value !== undefined) {
|
32477
|
+
this.set('_isDisabled', value === true);
|
32478
|
+
}
|
32479
|
+
return value === true ? get(this, 'disabledClass') : false;
|
32480
|
+
})
|
32481
|
+
});
|
32482
|
+
```
|
32483
|
+
|
32484
|
+
see "Overriding Application-wide Defaults" for more.
|
32485
|
+
|
32044
32486
|
### Handling `href`
|
32045
32487
|
`{{link-to}}` will use your application's Router to
|
32046
32488
|
fill the element's `href` property with a url that
|
@@ -32096,7 +32538,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
|
32096
32538
|
```javascript
|
32097
32539
|
App.Router.map(function() {
|
32098
32540
|
this.resource("photoGallery", {path: "hamster-photos/:photo_id"});
|
32099
|
-
})
|
32541
|
+
});
|
32100
32542
|
```
|
32101
32543
|
|
32102
32544
|
```handlebars
|
@@ -32138,6 +32580,34 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
|
32138
32580
|
A+++ would snuggle again.
|
32139
32581
|
</a>
|
32140
32582
|
```
|
32583
|
+
|
32584
|
+
### Supplying an explicit dynamic segment value
|
32585
|
+
If you don't have a model object available to pass to `{{link-to}}`,
|
32586
|
+
an optional string or integer argument can be passed for routes whose
|
32587
|
+
paths contain dynamic segments. This argument will become the value
|
32588
|
+
of the dynamic segment:
|
32589
|
+
|
32590
|
+
```javascript
|
32591
|
+
App.Router.map(function() {
|
32592
|
+
this.resource("photoGallery", {path: "hamster-photos/:photo_id"});
|
32593
|
+
});
|
32594
|
+
```
|
32595
|
+
|
32596
|
+
```handlebars
|
32597
|
+
{{#link-to 'photoGallery' aPhotoId}}
|
32598
|
+
{{aPhoto.title}}
|
32599
|
+
{{/link-to}}
|
32600
|
+
```
|
32601
|
+
|
32602
|
+
```html
|
32603
|
+
<a href="/hamster-photos/42">
|
32604
|
+
Tomster
|
32605
|
+
</a>
|
32606
|
+
```
|
32607
|
+
|
32608
|
+
When transitioning into the linked route, the `model` hook will
|
32609
|
+
be triggered with parameters including this passed identifier.
|
32610
|
+
|
32141
32611
|
### Overriding attributes
|
32142
32612
|
You can override any given property of the Ember.LinkView
|
32143
32613
|
that is generated by the `{{link-to}}` helper by passing
|
@@ -32147,8 +32617,9 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
|
32147
32617
|
{{#link-to aPhoto tagName='li' title='Following this link will change your life' classNames=['pic', 'sweet']}}
|
32148
32618
|
Uh-mazing!
|
32149
32619
|
{{/link-to}}
|
32620
|
+
```
|
32150
32621
|
|
32151
|
-
See
|
32622
|
+
See [Ember.LinkView](/api/classes/Ember.LinkView.html) for a
|
32152
32623
|
complete list of overrideable properties. Be sure to also
|
32153
32624
|
check out inherited properties of `LinkView`.
|
32154
32625
|
|
@@ -32178,7 +32649,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
|
32178
32649
|
@for Ember.Handlebars.helpers
|
32179
32650
|
@param {String} routeName
|
32180
32651
|
@param {Object} [context]*
|
32181
|
-
@param [options] {Object} Handlebars key/value pairs of options, you can
|
32652
|
+
@param [options] {Object} Handlebars key/value pairs of options, you can override any property of Ember.LinkView
|
32182
32653
|
@return {String} HTML string
|
32183
32654
|
@see {Ember.LinkView}
|
32184
32655
|
*/
|
@@ -32199,7 +32670,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
|
32199
32670
|
});
|
32200
32671
|
|
32201
32672
|
/**
|
32202
|
-
See
|
32673
|
+
See [link-to](/api/classes/Ember.Handlebars.helpers.html#method_link-to)
|
32203
32674
|
|
32204
32675
|
@method linkTo
|
32205
32676
|
@for Ember.Handlebars.helpers
|
@@ -32344,7 +32815,7 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
|
32344
32815
|
Example:
|
32345
32816
|
|
32346
32817
|
```javascript
|
32347
|
-
App.NavigationController = Ember.Controller.
|
32818
|
+
App.NavigationController = Ember.Controller.extend({
|
32348
32819
|
who: "world"
|
32349
32820
|
});
|
32350
32821
|
```
|
@@ -32502,6 +32973,10 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
|
32502
32973
|
return isSimpleClick(event);
|
32503
32974
|
}
|
32504
32975
|
|
32976
|
+
if (allowedKeys.indexOf("any") >= 0) {
|
32977
|
+
return true;
|
32978
|
+
}
|
32979
|
+
|
32505
32980
|
var allowed = true;
|
32506
32981
|
|
32507
32982
|
forEach.call(keys, function(key) {
|
@@ -32555,16 +33030,16 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
|
32555
33030
|
|
32556
33031
|
/**
|
32557
33032
|
The `{{action}}` helper registers an HTML element within a template for DOM
|
32558
|
-
event handling and forwards that interaction to the
|
33033
|
+
event handling and forwards that interaction to the templates's controller
|
32559
33034
|
or supplied `target` option (see 'Specifying a Target').
|
32560
33035
|
|
32561
|
-
If the
|
33036
|
+
If the controller does not implement the event, the event is sent
|
32562
33037
|
to the current route, and it bubbles up the route hierarchy from there.
|
32563
33038
|
|
32564
33039
|
User interaction with that element will invoke the supplied action name on
|
32565
33040
|
the appropriate target.
|
32566
33041
|
|
32567
|
-
Given the following Handlebars template on the page
|
33042
|
+
Given the following application Handlebars template on the page
|
32568
33043
|
|
32569
33044
|
```handlebars
|
32570
33045
|
<div {{action 'anActionName'}}>
|
@@ -32575,17 +33050,13 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
|
32575
33050
|
And application code
|
32576
33051
|
|
32577
33052
|
```javascript
|
32578
|
-
|
32579
|
-
|
32580
|
-
|
32581
|
-
|
32582
|
-
|
32583
|
-
|
32584
|
-
templateName: 'a-template'
|
33053
|
+
App.ApplicationController = Ember.Controller.extend({
|
33054
|
+
actions: {
|
33055
|
+
anActionName: function() {
|
33056
|
+
|
33057
|
+
}
|
33058
|
+
}
|
32585
33059
|
});
|
32586
|
-
|
32587
|
-
aView = AView.create();
|
32588
|
-
aView.appendTo('body');
|
32589
33060
|
```
|
32590
33061
|
|
32591
33062
|
Will result in the following rendered HTML
|
@@ -32598,8 +33069,8 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
|
32598
33069
|
</div>
|
32599
33070
|
```
|
32600
33071
|
|
32601
|
-
Clicking "click me" will trigger the `anActionName`
|
32602
|
-
`
|
33072
|
+
Clicking "click me" will trigger the `anActionName` action of the
|
33073
|
+
`App.ApplicationController`. In this case, no additional parameters will be passed.
|
32603
33074
|
|
32604
33075
|
If you provide additional parameters to the helper:
|
32605
33076
|
|
@@ -32632,11 +33103,9 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
|
32632
33103
|
supply an `on` option to the helper to specify a different DOM event name:
|
32633
33104
|
|
32634
33105
|
```handlebars
|
32635
|
-
<
|
32636
|
-
|
32637
|
-
|
32638
|
-
</div>
|
32639
|
-
</script>
|
33106
|
+
<div {{action "anActionName" on="doubleClick"}}>
|
33107
|
+
click me
|
33108
|
+
</div>
|
32640
33109
|
```
|
32641
33110
|
|
32642
33111
|
See `Ember.View` 'Responding to Browser Events' for a list of
|
@@ -32654,15 +33123,21 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
|
32654
33123
|
keys. You can supply an `allowedKeys` option to specify which keys should not be ignored.
|
32655
33124
|
|
32656
33125
|
```handlebars
|
32657
|
-
<
|
32658
|
-
|
32659
|
-
|
32660
|
-
</div>
|
32661
|
-
</script>
|
33126
|
+
<div {{action "anActionName" allowedKeys="alt"}}>
|
33127
|
+
click me
|
33128
|
+
</div>
|
32662
33129
|
```
|
32663
33130
|
|
32664
33131
|
This way the `{{action}}` will fire when clicking with the alt key pressed down.
|
32665
33132
|
|
33133
|
+
Alternatively, supply "any" to the `allowedKeys` option to accept any combination of modifier keys.
|
33134
|
+
|
33135
|
+
```handlebars
|
33136
|
+
<div {{action "anActionName" allowedKeys="any"}}>
|
33137
|
+
click me with any key pressed
|
33138
|
+
</div>
|
33139
|
+
```
|
33140
|
+
|
32666
33141
|
### Specifying a Target
|
32667
33142
|
|
32668
33143
|
There are several possible target objects for `{{action}}` helpers:
|
@@ -32676,43 +33151,21 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
|
32676
33151
|
to an object, accessible in the current context:
|
32677
33152
|
|
32678
33153
|
```handlebars
|
32679
|
-
|
32680
|
-
|
32681
|
-
|
32682
|
-
|
32683
|
-
</script>
|
32684
|
-
```
|
32685
|
-
|
32686
|
-
Clicking "click me" in the rendered HTML of the above template will trigger
|
32687
|
-
the `anActionName` method of the object at `MyApplication.someObject`.
|
32688
|
-
|
32689
|
-
If an action's target does not implement a method that matches the supplied
|
32690
|
-
action name an error will be thrown.
|
32691
|
-
|
32692
|
-
```handlebars
|
32693
|
-
<script type="text/x-handlebars" data-template-name='a-template'>
|
32694
|
-
<div {{action 'aMethodNameThatIsMissing'}}>
|
32695
|
-
click me
|
32696
|
-
</div>
|
32697
|
-
</script>
|
33154
|
+
{{! the application template }}
|
33155
|
+
<div {{action "anActionName" target=view}}>
|
33156
|
+
click me
|
33157
|
+
</div>
|
32698
33158
|
```
|
32699
33159
|
|
32700
|
-
With the following application code
|
32701
|
-
|
32702
33160
|
```javascript
|
32703
|
-
|
32704
|
-
|
32705
|
-
|
32706
|
-
|
33161
|
+
App.ApplicationView = Ember.View.extend({
|
33162
|
+
actions: {
|
33163
|
+
anActionName: function(){}
|
33164
|
+
}
|
32707
33165
|
});
|
32708
33166
|
|
32709
|
-
aView = AView.create();
|
32710
|
-
aView.appendTo('body');
|
32711
33167
|
```
|
32712
33168
|
|
32713
|
-
Will throw `Uncaught TypeError: Cannot call method 'call' of undefined` when
|
32714
|
-
"click me" is clicked.
|
32715
|
-
|
32716
33169
|
### Additional Parameters
|
32717
33170
|
|
32718
33171
|
You may specify additional parameters to the `{{action}}` helper. These
|
@@ -32720,17 +33173,15 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
|
|
32720
33173
|
implementing the action.
|
32721
33174
|
|
32722
33175
|
```handlebars
|
32723
|
-
|
32724
|
-
{{
|
32725
|
-
|
32726
|
-
|
32727
|
-
|
32728
|
-
{{/each}}
|
32729
|
-
</script>
|
33176
|
+
{{#each person in people}}
|
33177
|
+
<div {{action "edit" person}}>
|
33178
|
+
click me
|
33179
|
+
</div>
|
33180
|
+
{{/each}}
|
32730
33181
|
```
|
32731
33182
|
|
32732
|
-
Clicking "click me" will trigger the `edit` method on the current
|
32733
|
-
|
33183
|
+
Clicking "click me" will trigger the `edit` method on the current controller
|
33184
|
+
with the value of `person` as a parameter.
|
32734
33185
|
|
32735
33186
|
@method action
|
32736
33187
|
@for Ember.Handlebars.helpers
|
@@ -32914,8 +33365,23 @@ Ember.ControllerMixin.reopen({
|
|
32914
33365
|
aController.transitionToRoute('blogPost', aPost);
|
32915
33366
|
```
|
32916
33367
|
|
33368
|
+
Multiple models will be applied last to first recursively up the
|
33369
|
+
resource tree.
|
33370
|
+
|
33371
|
+
```javascript
|
33372
|
+
|
33373
|
+
this.resource('blogPost', {path:':blogPostId'}, function(){
|
33374
|
+
this.resource('blogComment', {path: ':blogCommentId'});
|
33375
|
+
});
|
33376
|
+
|
33377
|
+
aController.transitionToRoute('blogComment', aPost, aComment);
|
33378
|
+
```
|
33379
|
+
|
33380
|
+
See also 'replaceRoute'.
|
33381
|
+
|
32917
33382
|
@param {String} name the name of the route
|
32918
|
-
@param {...Object} models the
|
33383
|
+
@param {...Object} models the model(s) to be used while transitioning
|
33384
|
+
to the route.
|
32919
33385
|
@for Ember.ControllerMixin
|
32920
33386
|
@method transitionToRoute
|
32921
33387
|
*/
|
@@ -32937,8 +33403,9 @@ Ember.ControllerMixin.reopen({
|
|
32937
33403
|
},
|
32938
33404
|
|
32939
33405
|
/**
|
32940
|
-
|
32941
|
-
|
33406
|
+
Transition into another route while replacing the current URL, if possible.
|
33407
|
+
This will replace the current history entry instead of adding a new one.
|
33408
|
+
Beside that, it is identical to `transitionToRoute` in all other respects.
|
32942
33409
|
|
32943
33410
|
```javascript
|
32944
33411
|
aController.replaceRoute('blogPosts');
|
@@ -32953,8 +33420,21 @@ Ember.ControllerMixin.reopen({
|
|
32953
33420
|
aController.replaceRoute('blogPost', aPost);
|
32954
33421
|
```
|
32955
33422
|
|
33423
|
+
Multiple models will be applied last to first recursively up the
|
33424
|
+
resource tree.
|
33425
|
+
|
33426
|
+
```javascript
|
33427
|
+
|
33428
|
+
this.resource('blogPost', {path:':blogPostId'}, function(){
|
33429
|
+
this.resource('blogComment', {path: ':blogCommentId'});
|
33430
|
+
});
|
33431
|
+
|
33432
|
+
aController.replaceRoute('blogComment', aPost, aComment);
|
33433
|
+
```
|
33434
|
+
|
32956
33435
|
@param {String} name the name of the route
|
32957
|
-
@param {...Object} models the
|
33436
|
+
@param {...Object} models the model(s) to be used while transitioning
|
33437
|
+
to the route.
|
32958
33438
|
@for Ember.ControllerMixin
|
32959
33439
|
@method replaceRoute
|
32960
33440
|
*/
|
@@ -33757,7 +34237,7 @@ DAG.prototype.addEdge = function(fromName, toName) {
|
|
33757
34237
|
}
|
33758
34238
|
function checkCycle(vertex, path) {
|
33759
34239
|
if (vertex.name === toName) {
|
33760
|
-
throw new Error("cycle detected: " + toName + " <- " + path.join(" <- "));
|
34240
|
+
throw new Ember.Error("cycle detected: " + toName + " <- " + path.join(" <- "));
|
33761
34241
|
}
|
33762
34242
|
}
|
33763
34243
|
visit(from, checkCycle);
|
@@ -33825,11 +34305,11 @@ var get = Ember.get,
|
|
33825
34305
|
container lookups before consulting the container for registered
|
33826
34306
|
items:
|
33827
34307
|
|
33828
|
-
|
33829
|
-
|
33830
|
-
|
33831
|
-
|
33832
|
-
|
34308
|
+
* templates are looked up on `Ember.TEMPLATES`
|
34309
|
+
* other names are looked up on the application after converting
|
34310
|
+
the name. For example, `controller:post` looks up
|
34311
|
+
`App.PostController` by default.
|
34312
|
+
* there are some nuances (see examples below)
|
33833
34313
|
|
33834
34314
|
### How Resolving Works
|
33835
34315
|
|
@@ -34195,16 +34675,15 @@ DeprecatedContainer.prototype = {
|
|
34195
34675
|
example, the `keypress` event causes the `keyPress` method on the view to be
|
34196
34676
|
called, the `dblclick` event causes `doubleClick` to be called, and so on.
|
34197
34677
|
|
34198
|
-
If there is a browser event that Ember does not listen for by
|
34199
|
-
can specify custom events and their corresponding view method
|
34200
|
-
setting the application's `customEvents` property:
|
34678
|
+
If there is a bubbling browser event that Ember does not listen for by
|
34679
|
+
default, you can specify custom events and their corresponding view method
|
34680
|
+
names by setting the application's `customEvents` property:
|
34201
34681
|
|
34202
34682
|
```javascript
|
34203
34683
|
App = Ember.Application.create({
|
34204
34684
|
customEvents: {
|
34205
|
-
// add support for the
|
34206
|
-
|
34207
|
-
'loadedmetadata': "loadedMetadata"
|
34685
|
+
// add support for the paste event
|
34686
|
+
'paste: "paste"
|
34208
34687
|
}
|
34209
34688
|
});
|
34210
34689
|
```
|
@@ -34317,7 +34796,7 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
|
|
34317
34796
|
`keyup`, and delegates them to your application's `Ember.View`
|
34318
34797
|
instances.
|
34319
34798
|
|
34320
|
-
If you would like additional events to be delegated to your
|
34799
|
+
If you would like additional bubbling events to be delegated to your
|
34321
34800
|
views, set your `Ember.Application`'s `customEvents` property
|
34322
34801
|
to a hash containing the DOM event name as the key and the
|
34323
34802
|
corresponding view method name as the value. For example:
|
@@ -34325,9 +34804,8 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
|
|
34325
34804
|
```javascript
|
34326
34805
|
App = Ember.Application.create({
|
34327
34806
|
customEvents: {
|
34328
|
-
// add support for the
|
34329
|
-
|
34330
|
-
'loadedmetadata': "loadedMetadata"
|
34807
|
+
// add support for the paste event
|
34808
|
+
'paste: "paste"
|
34331
34809
|
}
|
34332
34810
|
});
|
34333
34811
|
```
|
@@ -34353,12 +34831,17 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
|
|
34353
34831
|
|
34354
34832
|
this.scheduleInitialize();
|
34355
34833
|
|
34356
|
-
|
34357
|
-
|
34358
|
-
|
34834
|
+
Ember.libraries.registerCoreLibrary('Handlebars', Ember.Handlebars.VERSION);
|
34835
|
+
Ember.libraries.registerCoreLibrary('jQuery', Ember.$().jquery);
|
34359
34836
|
|
34837
|
+
if ( Ember.LOG_VERSION ) {
|
34838
|
+
Ember.LOG_VERSION = false; // we only need to see this once per Application#init
|
34839
|
+
var maxNameLength = Math.max.apply(this, Ember.A(Ember.libraries).mapBy("name.length"));
|
34360
34840
|
|
34841
|
+
Ember.libraries.each(function(name, version) {
|
34842
|
+
var spaces = new Array(maxNameLength - name.length + 1).join(" ");
|
34361
34843
|
|
34844
|
+
});
|
34362
34845
|
|
34363
34846
|
}
|
34364
34847
|
},
|
@@ -34492,19 +34975,20 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
|
|
34492
34975
|
```javascript
|
34493
34976
|
App = Ember.Application.create();
|
34494
34977
|
|
34495
|
-
App.Person
|
34496
|
-
App.Orange
|
34497
|
-
App.Email
|
34978
|
+
App.Person = Ember.Object.extend({});
|
34979
|
+
App.Orange = Ember.Object.extend({});
|
34980
|
+
App.Email = Ember.Object.extend({});
|
34981
|
+
App.Session = Ember.Object.create({});
|
34498
34982
|
|
34499
34983
|
App.register('model:user', App.Person, {singleton: false });
|
34500
34984
|
App.register('fruit:favorite', App.Orange);
|
34501
34985
|
App.register('communication:main', App.Email, {singleton: false});
|
34986
|
+
App.register('session', App.Session, {instantiate: false});
|
34502
34987
|
```
|
34503
34988
|
|
34504
34989
|
@method register
|
34505
|
-
@param
|
34506
|
-
@param
|
34507
|
-
@param factory {String}
|
34990
|
+
@param fullName {String} type:name (e.g., 'model:user')
|
34991
|
+
@param factory {Function} (e.g., App.Person)
|
34508
34992
|
@param options {String} (optional)
|
34509
34993
|
**/
|
34510
34994
|
register: function() {
|
@@ -34561,7 +35045,9 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
|
|
34561
35045
|
if (this.isDestroyed) { return; }
|
34562
35046
|
|
34563
35047
|
// At this point, the App.Router must already be assigned
|
34564
|
-
|
35048
|
+
if (this.Router) {
|
35049
|
+
this.register('router:main', this.Router);
|
35050
|
+
}
|
34565
35051
|
|
34566
35052
|
this.runInitializers();
|
34567
35053
|
Ember.runLoadHooks('application', this);
|
@@ -34671,10 +35157,10 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
|
|
34671
35157
|
container = this.__container__,
|
34672
35158
|
graph = new Ember.DAG(),
|
34673
35159
|
namespace = this,
|
34674
|
-
|
35160
|
+
name, initializer;
|
34675
35161
|
|
34676
|
-
for (
|
34677
|
-
initializer = initializers[
|
35162
|
+
for (name in initializers) {
|
35163
|
+
initializer = initializers[name];
|
34678
35164
|
graph.addEdges(initializer.name, initializer.initialize, initializer.before, initializer.after);
|
34679
35165
|
}
|
34680
35166
|
|
@@ -34724,8 +35210,8 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
|
|
34724
35210
|
/**
|
34725
35211
|
@private
|
34726
35212
|
|
34727
|
-
If the application has a router, use it to route to the current URL, and
|
34728
35213
|
trigger a new call to `route` whenever the URL changes.
|
35214
|
+
If the application has a router, use it to route to the current URL, and
|
34729
35215
|
|
34730
35216
|
@method startRouting
|
34731
35217
|
@property router {Ember.Router}
|
@@ -34752,10 +35238,10 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
|
|
34752
35238
|
ready: Ember.K,
|
34753
35239
|
|
34754
35240
|
/**
|
34755
|
-
|
34756
35241
|
@deprecated Use 'Resolver' instead
|
34757
35242
|
Set this to provide an alternate class to `Ember.DefaultResolver`
|
34758
35243
|
|
35244
|
+
|
34759
35245
|
@property resolver
|
34760
35246
|
*/
|
34761
35247
|
resolver: null,
|
@@ -34779,15 +35265,22 @@ var Application = Ember.Application = Ember.Namespace.extend(Ember.DeferredMixin
|
|
34779
35265
|
});
|
34780
35266
|
|
34781
35267
|
Ember.Application.reopenClass({
|
34782
|
-
|
34783
|
-
initializers: Ember.A(),
|
35268
|
+
initializers: {},
|
34784
35269
|
initializer: function(initializer) {
|
34785
|
-
|
35270
|
+
// If this is the first initializer being added to a subclass, we are going to reopen the class
|
35271
|
+
// to make sure we have a new `initializers` object, which extends from the parent class' using
|
35272
|
+
// prototypal inheritance. Without this, attempting to add initializers to the subclass would
|
35273
|
+
// pollute the parent class as well as other subclasses.
|
35274
|
+
if (this.superclass.initializers !== undefined && this.superclass.initializers === this.initializers) {
|
35275
|
+
this.reopenClass({
|
35276
|
+
initializers: Ember.create(this.initializers)
|
35277
|
+
});
|
35278
|
+
}
|
34786
35279
|
|
34787
35280
|
|
34788
35281
|
|
34789
35282
|
|
34790
|
-
initializers.
|
35283
|
+
this.initializers[initializer.name] = initializer;
|
34791
35284
|
},
|
34792
35285
|
|
34793
35286
|
/**
|
@@ -34976,6 +35469,8 @@ Ember.ControllerMixin.reopen({
|
|
34976
35469
|
length = get(needs, 'length');
|
34977
35470
|
|
34978
35471
|
if (length > 0) {
|
35472
|
+
|
35473
|
+
|
34979
35474
|
verifyNeedsDependencies(this, this.container, needs);
|
34980
35475
|
|
34981
35476
|
// if needs then initialize controllers proxy
|
@@ -34985,6 +35480,11 @@ Ember.ControllerMixin.reopen({
|
|
34985
35480
|
this._super.apply(this, arguments);
|
34986
35481
|
},
|
34987
35482
|
|
35483
|
+
/**
|
35484
|
+
@method controllerFor
|
35485
|
+
@see {Ember.Route#controllerFor}
|
35486
|
+
@deprecated Use `needs` instead
|
35487
|
+
*/
|
34988
35488
|
controllerFor: function(controllerName) {
|
34989
35489
|
|
34990
35490
|
return Ember.controllerFor(get(this, 'container'), controllerName);
|