dist/ember-runtime.js in ember-source-1.9.0.beta.1.1 vs dist/ember-runtime.js in ember-source-1.9.0.beta.3
- old
+ new
@@ -3,11 +3,11 @@
* @copyright Copyright 2011-2014 Tilde Inc. and contributors
* Portions Copyright 2006-2011 Strobe Inc.
* Portions Copyright 2008-2011 Apple Inc. All rights reserved.
* @license Licensed under MIT license
* See https://raw.github.com/emberjs/ember.js/master/LICENSE
- * @version 1.9.0-beta.1
+ * @version 1.9.0-beta.3
*/
(function() {
var define, requireModule, require, requirejs, Ember;
@@ -191,10 +191,27 @@
}
}
}
},
+ join: function(target, method /*, args */) {
+ if (this.currentInstance) {
+ if (!method) {
+ method = target;
+ target = null;
+ }
+
+ if (isString(method)) {
+ method = target[method];
+ }
+
+ return method.apply(target, slice.call(arguments, 2));
+ } else {
+ return this.run.apply(this, arguments);
+ }
+ },
+
defer: function(queueName, target, method /* , args */) {
if (!method) {
method = target;
target = null;
}
@@ -1177,24 +1194,10 @@
this.children.push(container);
return container;
},
/**
- Sets a key-value pair on the current container. If a parent container,
- has the same key, once set on a child, the parent and child will diverge
- as expected.
-
- @method set
- @param {Object} object
- @param {String} key
- @param {any} value
- */
- set: function(object, key, value) {
- object[key] = value;
- },
-
- /**
Registers a factory for later injection.
Example:
```javascript
@@ -1445,15 +1448,17 @@
this._typeOptions[type] = options;
},
/**
@method options
- @param {String} type
+ @param {String} fullName
@param {Object} options
*/
- options: function(type, options) {
- this.optionsForType(type, options);
+ options: function(fullName, options) {
+ options = options || {};
+ var normalizedName = this.normalize(fullName);
+ this._options[normalizedName] = options;
},
/**
Used only via `injection`.
@@ -2666,11 +2671,13 @@
// add an observer on the object to be notified when the binding should be updated
addObserver(obj, fromPath, this, this.fromDidChange);
// if the binding is a two-way binding, also set up an observer on the target
- if (!this._oneWay) { addObserver(obj, toPath, this, this.toDidChange); }
+ if (!this._oneWay) {
+ addObserver(obj, toPath, this, this.toDidChange);
+ }
this._readyToSync = true;
return this;
},
@@ -2691,11 +2698,13 @@
// remove an observer on the object so we're no longer notified of
// changes that should update bindings.
removeObserver(obj, this._from, this, this.fromDidChange);
// if the binding is two-way, remove the observer from the target as well
- if (twoWay) { removeObserver(obj, this._to, this, this.toDidChange); }
+ if (twoWay) {
+ removeObserver(obj, this._to, this, this.toDidChange);
+ }
this._readyToSync = false; // disable scheduled syncs...
return this;
},
@@ -3077,11 +3086,13 @@
if (pendingQueue.length === 0) { return; } // nothing to do
var queue = pendingQueue;
pendingQueue = [];
- forEach.call(queue, function(q) { q[0].add(q[1]); });
+ forEach.call(queue, function(q) {
+ q[0].add(q[1]);
+ });
warn('Watching an undefined global, Ember expects watched globals to be' +
' setup by the time the run loop is flushed, check for typos', pendingQueue.length === 0);
}
@@ -3093,11 +3104,13 @@
if (!m.hasOwnProperty('chainWatchers')) {
nodes = m.chainWatchers = {};
}
- if (!nodes[keyName]) { nodes[keyName] = []; }
+ if (!nodes[keyName]) {
+ nodes[keyName] = [];
+ }
nodes[keyName].push(node);
watchKey(obj, keyName, m);
}
function removeChainWatcher(obj, keyName, node) {
@@ -3137,11 +3150,13 @@
this._value = value;
this._paths = {};
if (this._watching) {
this._object = parent.value();
- if (this._object) { addChainWatcher(this._object, this._key, this); }
+ if (this._object) {
+ addChainWatcher(this._object, this._key, this);
+ }
}
// Special-case: the EachProxy relies on immediate evaluation to
// establish its observers.
//
@@ -3157,13 +3172,17 @@
function lazyGet(obj, key) {
if (!obj) return undefined;
var meta = obj['__ember_meta__'];
// check if object meant only to be a prototype
- if (meta && meta.proto === obj) return undefined;
+ if (meta && meta.proto === obj) {
+ return undefined;
+ }
- if (key === "@each") return get(obj, key);
+ if (key === "@each") {
+ return get(obj, key);
+ }
// if a CP only return cached value
var desc = meta && meta.descs[key];
if (desc && desc._cacheable) {
if (key in meta.cache) {
@@ -3185,11 +3204,13 @@
};
ChainNodePrototype.destroy = function() {
if (this._watching) {
var obj = this._object;
- if (obj) { removeChainWatcher(obj, this._key, this); }
+ if (obj) {
+ removeChainWatcher(obj, this._key, this);
+ }
this._watching = false; // so future calls do nothing
}
};
// copies a top level object only
@@ -3197,11 +3218,14 @@
var ret = new ChainNode(null, null, obj);
var paths = this._paths;
var path;
for (path in paths) {
- if (paths[path] <= 0) { continue; } // this check will also catch non-number vals.
+ // this check will also catch non-number vals.
+ if (paths[path] <= 0) {
+ continue;
+ }
ret.add(path);
}
return ret;
};
@@ -3244,11 +3268,13 @@
// path
ChainNodePrototype.remove = function(path) {
var obj, tuple, key, src, paths;
paths = this._paths;
- if (paths[path] > 0) { paths[path]--; }
+ if (paths[path] > 0) {
+ paths[path]--;
+ }
obj = this.value();
tuple = normalizeTuple(obj, path);
if (tuple[0] === obj) {
path = tuple[1];
@@ -3267,14 +3293,18 @@
ChainNodePrototype.count = 0;
ChainNodePrototype.chain = function(key, path, src) {
var chains = this._chains;
var node;
- if (!chains) { chains = this._chains = {}; }
+ if (!chains) {
+ chains = this._chains = {};
+ }
node = chains[key];
- if (!node) { node = chains[key] = new ChainNode(this, key, src); }
+ if (!node) {
+ node = chains[key] = new ChainNode(this, key, src);
+ }
node.count++; // count chains...
// chain rest of path if there is one
if (path) {
key = firstKey(path);
@@ -3286,14 +3316,14 @@
ChainNodePrototype.unchain = function(key, path) {
var chains = this._chains;
var node = chains[key];
// unchain rest of path first...
- if (path && path.length>1) {
- key = firstKey(path);
- path = path.slice(key.length+1);
- node.unchain(key, path);
+ if (path && path.length > 1) {
+ var nextKey = firstKey(path);
+ var nextPath = path.slice(nextKey.length + 1);
+ node.unchain(nextKey, nextPath);
}
// delete node if needed.
node.count--;
if (node.count<=0) {
@@ -3305,20 +3335,26 @@
ChainNodePrototype.willChange = function(events) {
var chains = this._chains;
if (chains) {
for(var key in chains) {
- if (!chains.hasOwnProperty(key)) { continue; }
+ if (!chains.hasOwnProperty(key)) {
+ continue;
+ }
chains[key].willChange(events);
}
}
- if (this._parent) { this._parent.chainWillChange(this, this._key, 1, events); }
+ if (this._parent) {
+ this._parent.chainWillChange(this, this._key, 1, events);
+ }
};
ChainNodePrototype.chainWillChange = function(chain, path, depth, events) {
- if (this._key) { path = this._key + '.' + path; }
+ if (this._key) {
+ path = this._key + '.' + path;
+ }
if (this._parent) {
this._parent.chainWillChange(this, path, depth+1, events);
} else {
if (depth > 1) {
@@ -3330,11 +3366,14 @@
}
}
};
ChainNodePrototype.chainDidChange = function(chain, path, depth, events) {
- if (this._key) { path = this._key + '.' + path; }
+ if (this._key) {
+ path = this._key + '.' + path;
+ }
+
if (this._parent) {
this._parent.chainDidChange(this, path, depth+1, events);
} else {
if (depth > 1) {
events.push(this.value(), path);
@@ -3357,12 +3396,13 @@
}
this._value = undefined;
// Special-case: the EachProxy relies on immediate evaluation to
// establish its observers.
- if (this._parent && this._parent._key === '@each')
+ if (this._parent && this._parent._key === '@each') {
this.value();
+ }
}
// then notify chains...
var chains = this._chains;
if (chains) {
@@ -3371,26 +3411,34 @@
chains[key].didChange(events);
}
}
// if no events are passed in then we only care about the above wiring update
- if (events === null) { return; }
+ if (events === null) {
+ return;
+ }
// and finally tell parent about my path changing...
- if (this._parent) { this._parent.chainDidChange(this, this._key, 1, events); }
+ if (this._parent) {
+ this._parent.chainDidChange(this, this._key, 1, events);
+ }
};
function finishChains(obj) {
// We only create meta if we really have to
- var m = obj['__ember_meta__'],
- chains, chainWatchers, chainNodes;
+ var m = obj['__ember_meta__'];
+ var chains, chainWatchers, chainNodes;
+
if (m) {
// finish any current chains node watchers that reference obj
chainWatchers = m.chainWatchers;
if (chainWatchers) {
for(var key in chainWatchers) {
- if (!chainWatchers.hasOwnProperty(key)) { continue; }
+ if (!chainWatchers.hasOwnProperty(key)) {
+ continue;
+ }
+
chainNodes = chainWatchers[key];
if (chainNodes) {
for (var i=0,l=chainNodes.length;i<l;i++) {
chainNodes[i].didChange(null);
}
@@ -3439,22 +3487,22 @@
// ..........................................................
// COMPUTED PROPERTY
//
/**
- A computed property transforms an objects function into a property.
+ A computed property transforms an object's function into a property.
By default the function backing the computed property will only be called
once and the result will be cached. You can specify various properties
- that your computed property is dependent on. This will force the cached
+ that your computed property depends on. This will force the cached
result to be recomputed if the dependencies are modified.
In the following example we declare a computed property (by calling
- `.property()` on the fullName function) and setup the properties
+ `.property()` on the fullName function) and setup the property
dependencies (depending on firstName and lastName). The fullName function
will be called once (regardless of how many times it is accessed) as long
- as it's dependencies have not been changed. Once firstName or lastName are updated
+ as its dependencies have not changed. Once firstName or lastName are updated
any future calls (or anything bound) to fullName will incorporate the new
values.
```javascript
var Person = Ember.Object.extend({
@@ -3746,11 +3794,13 @@
} else {
cache[keyName] = ret;
}
chainNodes = meta.chainWatchers && meta.chainWatchers[keyName];
- if (chainNodes) { finishChains(chainNodes); }
+ if (chainNodes) {
+ finishChains(chainNodes);
+ }
addDependentKeys(this, obj, keyName, meta);
} else {
ret = this.func.call(obj, keyName);
}
return ret;
@@ -3988,11 +4038,13 @@
function cacheFor(obj, key) {
var meta = obj['__ember_meta__'];
var cache = meta && meta.cache;
var ret = cache && cache[key];
- if (ret === UNDEFINED) { return undefined; }
+ if (ret === UNDEFINED) {
+ return undefined;
+ }
return ret;
}
cacheFor.set = function(cache, key, value) {
if (value === undefined) {
@@ -4002,11 +4054,13 @@
}
};
cacheFor.get = function(cache, key) {
var ret = cache[key];
- if (ret === UNDEFINED) { return undefined; }
+ if (ret === UNDEFINED) {
+ return undefined;
+ }
return ret;
};
cacheFor.remove = function(cache, key) {
cache[key] = undefined;
@@ -4747,11 +4801,11 @@
The core Runtime framework is based on the jQuery API with a number of
performance optimizations.
@class Ember
@static
- @version 1.9.0-beta.1
+ @version 1.9.0-beta.3
*/
if ('undefined' === typeof Ember) {
// Create core object. Make it act like an instance of Ember.Namespace so that
// objects assigned to it are given a sane string representation.
@@ -4774,14 +4828,14 @@
/**
@property VERSION
@type String
- @default '1.9.0-beta.1'
+ @default '1.9.0-beta.3'
@static
*/
- Ember.VERSION = '1.9.0-beta.1';
+ Ember.VERSION = '1.9.0-beta.3';
/**
Standard environmental variables. You can define these in a global `EmberENV`
variable before loading Ember to control various configuration settings.
@@ -4892,11 +4946,11 @@
@default true
*/
Ember.LOG_STACKTRACE_ON_DEPRECATION = (Ember.ENV.LOG_STACKTRACE_ON_DEPRECATION !== false);
/**
- Determines whether Ember should add ECMAScript 5 shims to older browsers.
+ Determines whether Ember should add ECMAScript 5 Array shims to older browsers.
@property SHIM_ES5
@type Boolean
@default Ember.EXTEND_PROTOTYPES
*/
@@ -6425,11 +6479,12 @@
return function keys(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
- var result = [], prop, i;
+ var result = [];
+ var prop, i;
for (prop in obj) {
if (prop !== '_super' &&
prop.lastIndexOf('__',0) !== 0 &&
hasOwnProperty.call(obj, prop)) {
@@ -6515,12 +6570,16 @@
}
var method = typeof consoleObj === 'object' ? consoleObj[name] : null;
if (method) {
- // Older IE doesn't support apply, but Chrome needs it
- if (typeof method.apply === 'function') {
+ // Older IE doesn't support bind, but Chrome needs it
+ if (typeof method.bind === 'function') {
+ logToConsole = method.bind(consoleObj);
+ logToConsole.displayName = 'console.' + name;
+ return logToConsole;
+ } else if (typeof method.apply === 'function') {
logToConsole = function() {
method.apply(consoleObj, arguments);
};
logToConsole.displayName = 'console.' + name;
return logToConsole;
@@ -7209,11 +7268,10 @@
*/
var Ember = __dependency1__["default"];
// warn, assert, wrap, et;
var merge = __dependency2__["default"];
- var a_map = __dependency3__.map;
var a_indexOf = __dependency3__.indexOf;
var a_forEach = __dependency3__.forEach;
var o_create = __dependency4__.create;
var get = __dependency5__.get;
var set = __dependency6__.set;
@@ -7264,26 +7322,10 @@
ret = m.mixins = o_create(ret);
}
return ret;
}
- function initMixin(mixin, args) {
- if (args && args.length > 0) {
- mixin.mixins = a_map.call(args, function(x) {
- if (x instanceof Mixin) { return x; }
-
- // Note: Manually setup a primitive mixin here. This is the only
- // way to actually get a primitive mixin. This way normal creation
- // of mixins will give you combined mixins...
- var mixin = new Mixin();
- mixin.properties = x;
- return mixin;
- });
- }
- return mixin;
- }
-
function isMethod(obj) {
return 'function' === typeof obj &&
obj.isMethod !== false &&
obj !== Boolean &&
obj !== Object &&
@@ -7726,17 +7768,34 @@
@class Mixin
@namespace Ember
*/
__exports__["default"] = Mixin;
- function Mixin() { return initMixin(this, arguments); }
- Mixin.prototype = {
- properties: null,
- mixins: null,
- ownerConstructor: null
- };
+ function Mixin(args, properties) {
+ this.properties = properties;
+ var length = args && args.length;
+
+ if (length > 0) {
+ var m = new Array(length);
+
+ for (var i = 0; i < length; i++) {
+ var x = args[i];
+ if (x instanceof Mixin) {
+ m[i] = x;
+ } else {
+ m[i] = new Mixin(undefined, x);
+ }
+ }
+
+ this.mixins = m;
+ } else {
+ this.mixins = undefined;
+ }
+ this.ownerConstructor = undefined;
+ }
+
Mixin._apply = applyMixin;
Mixin.applyPartial = function(obj) {
var args = a_slice.call(arguments, 1);
return applyMixin(obj, args, true);
@@ -7754,26 +7813,30 @@
*/
Mixin.create = function() {
// ES6TODO: this relies on a global state?
Ember.anyUnprocessedMixins = true;
var M = this;
- return initMixin(new M(), arguments);
+ var length = arguments.length;
+ var args = new Array(length);
+ for (var i = 0; i < length; i++) {
+ args[i] = arguments[i];
+ }
+ return new M(args, undefined);
};
var MixinPrototype = Mixin.prototype;
/**
@method reopen
@param arguments*
*/
MixinPrototype.reopen = function() {
- var mixin, tmp;
+ var mixin;
if (this.properties) {
- mixin = Mixin.create();
- mixin.properties = this.properties;
- delete this.properties;
+ mixin = new Mixin(undefined, this.properties);
+ this.properties = undefined;
this.mixins = [mixin];
} else if (!this.mixins) {
this.mixins = [];
}
@@ -7788,13 +7851,11 @@
Object.prototype.toString.call(mixin) !== '[object Array]');
if (mixin instanceof Mixin) {
mixins.push(mixin);
} else {
- tmp = Mixin.create();
- tmp.properties = mixin;
- mixins.push(tmp);
+ mixins.push(new Mixin(undefined, mixin));
}
}
return this;
};
@@ -7842,11 +7903,11 @@
}
return false;
};
MixinPrototype.without = function() {
- var ret = new Mixin(this);
+ var ret = new Mixin([this]);
ret._without = a_slice.call(arguments);
return ret;
};
function _keys(ret, mixin, seen) {
@@ -7867,11 +7928,13 @@
var keys = {};
var seen = {};
var ret = [];
_keys(keys, this, seen);
for(var key in keys) {
- if (keys.hasOwnProperty(key)) { ret.push(key); }
+ if (keys.hasOwnProperty(key)) {
+ ret.push(key);
+ }
}
return ret;
};
// returns the mixins currently applied to the specified object
@@ -8825,13 +8888,22 @@
var m = obj['__ember_meta__'];
var watching = (m && m.watching[keyName] > 0) || keyName === 'length';
var proto = m && m.proto;
var desc = m && m.descs[keyName];
- if (!watching) { return; }
- if (proto === obj) { return; }
- if (desc && desc.willChange) { desc.willChange(obj, keyName); }
+ if (!watching) {
+ return;
+ }
+
+ if (proto === obj) {
+ return;
+ }
+
+ if (desc && desc.willChange) {
+ desc.willChange(obj, keyName);
+ }
+
dependentKeysWillChange(obj, keyName, m);
chainsWillChange(obj, keyName, m);
notifyBeforeObservers(obj, keyName);
}
@@ -8854,16 +8926,23 @@
var m = obj['__ember_meta__'];
var watching = (m && m.watching[keyName] > 0) || keyName === 'length';
var proto = m && m.proto;
var desc = m && m.descs[keyName];
- if (proto === obj) { return; }
+ if (proto === obj) {
+ return;
+ }
// shouldn't this mean that we're watching this key?
- if (desc && desc.didChange) { desc.didChange(obj, keyName); }
- if (!watching && keyName !== 'length') { return; }
+ if (desc && desc.didChange) {
+ desc.didChange(obj, keyName);
+ }
+ if (!watching && keyName !== 'length') {
+ return;
+ }
+
if (m && m.deps && m.deps[keyName]) {
dependentKeysDidChange(obj, keyName, m);
}
chainsDidChange(obj, keyName, m, false);
@@ -8877,13 +8956,20 @@
var deps;
if (meta && meta.deps && (deps = meta.deps[depKey])) {
var seen = WILL_SEEN;
var top = !seen;
- if (top) { seen = WILL_SEEN = {}; }
+
+ if (top) {
+ seen = WILL_SEEN = {};
+ }
+
iterDeps(propertyWillChange, obj, deps, depKey, seen, meta);
- if (top) { WILL_SEEN = null; }
+
+ if (top) {
+ WILL_SEEN = null;
+ }
}
}
// called whenever a property has just changed to update dependent keys
function dependentKeysDidChange(obj, depKey, meta) {
@@ -8891,37 +8977,59 @@
var deps;
if (meta && meta.deps && (deps = meta.deps[depKey])) {
var seen = DID_SEEN;
var top = !seen;
- if (top) { seen = DID_SEEN = {}; }
+
+ if (top) {
+ seen = DID_SEEN = {};
+ }
+
iterDeps(propertyDidChange, obj, deps, depKey, seen, meta);
- if (top) { DID_SEEN = null; }
+
+ if (top) {
+ DID_SEEN = null;
+ }
}
}
function keysOf(obj) {
var keys = [];
- for (var key in obj) keys.push(key);
+
+ for (var key in obj) {
+ keys.push(key);
+ }
+
return keys;
}
function iterDeps(method, obj, deps, depKey, seen, meta) {
var keys, key, i, desc;
var guid = guidFor(obj);
var current = seen[guid];
- if (!current) current = seen[guid] = {};
- if (current[depKey]) return;
+
+ if (!current) {
+ current = seen[guid] = {};
+ }
+
+ if (current[depKey]) {
+ return;
+ }
+
current[depKey] = true;
if (deps) {
keys = keysOf(deps);
var descs = meta.descs;
for (i=0; i<keys.length; i++) {
key = keys[i];
desc = descs[key];
- if (desc && desc._suspended === obj) continue;
+
+ if (desc && desc._suspended === obj) {
+ continue;
+ }
+
method(obj, key);
}
}
}
@@ -9490,18 +9598,12 @@
then it will be looked up on the passed target.
@param {Object} [args*] Any additional arguments you wish to pass to the method.
@return {Object} Return value from invoking the passed function. Please note,
when called within an existing loop, no return value is possible.
*/
- run.join = function(target, method /* args */) {
- if (!run.currentRunLoop) {
- return Ember.run.apply(Ember, arguments);
- }
-
- var args = slice.call(arguments);
- args.unshift('actions');
- run.schedule.apply(run, args);
+ run.join = function() {
+ return backburner.join.apply(backburner, arguments);
};
/**
Provides a useful utility for when integrating with non-Ember libraries
that provide asynchronous callbacks.
@@ -11304,11 +11406,12 @@
}
};
function unwatchKey(obj, keyName, meta) {
- var m = meta || metaFor(obj), watching = m.watching;
+ var m = meta || metaFor(obj);
+ var watching = m.watching;
if (watching[keyName] === 1) {
watching[keyName] = 0;
var desc = m.descs[keyName];
@@ -13721,11 +13824,11 @@
```
Then, create a view that binds to your new controller:
```handlebars
- {{#each MyApp.listController}}
- {{firstName}} {{lastName}}
+ {{#each person in MyApp.listController}}
+ {{person.firstName}} {{person.lastName}}
{{/each}}
```
Although you are binding to the controller, the behavior of this controller
is to pass through any methods or properties to the underlying array. This