dist/ember-runtime.js in ember-source-1.0.0.rc1.4 vs dist/ember-runtime.js in ember-source-1.0.0.rc2.0

- old
+ new

@@ -1,7 +1,7 @@ -// Version: v1.0.0-rc.1-188-gb6bb967 -// Last commit: b6bb967 (2013-03-16 18:09:42 -0700) +// Version: v1.0.0-rc.1-240-gd3a6cc4 +// Last commit: d3a6cc4 (2013-03-25 04:06:07 -0400) (function() { /*global __fail__*/ @@ -138,22 +138,23 @@ no warnings will be shown in production. @method deprecateFunc @param {String} message A description of the deprecation. @param {Function} func The function to be deprecated. + @return {Function} a new function that wrapped the original function with a deprecation warning */ Ember.deprecateFunc = function(message, func) { return function() { Ember.deprecate(message); return func.apply(this, arguments); }; }; })(); -// Version: v1.0.0-rc.1-203-ga1cbd22 -// Last commit: a1cbd22 (2013-03-18 10:31:41 -0700) +// Version: v1.0.0-rc.1-275-g9104bf1 +// Last commit: 9104bf1 (2013-03-29 13:59:19 -0700) (function() { var define, requireModule; @@ -209,11 +210,11 @@ The core Runtime framework is based on the jQuery API with a number of performance optimizations. @class Ember @static - @version 1.0.0-rc.1 + @version 1.0.0-rc.2 */ 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. @@ -236,14 +237,14 @@ /** @property VERSION @type String - @default '1.0.0-rc.1' + @default '1.0.0-rc.2' @final */ -Ember.VERSION = '1.0.0-rc.1'; +Ember.VERSION = '1.0.0-rc.2'; /** Standard environmental variables. You can define these in a global `ENV` variable before loading Ember to control various configuration settings. @@ -822,11 +823,11 @@ @private @param {Object} obj The object to retrieve meta for @param {Boolean} [writable=true] Pass `false` if you do not intend to modify the meta hash, allowing the method to avoid making an unnecessary copy. - @return {Hash} + @return {Object} the meta hash for an object */ Ember.meta = function meta(obj, writable) { var ret = obj[META_KEY]; if (writable===false) return ret || EMPTY_META; @@ -974,11 +975,11 @@ ``` @method isArray @for Ember @param {Object} obj The object to test - @return {Boolean} + @return {Boolean} true if the passed object is an array or Array-like */ Ember.isArray = function(obj) { if (!obj || obj.setInterval) { return false; } if (Array.isArray && Array.isArray(obj)) { return true; } if (Ember.Array && Ember.Array.detect(obj)) { return true; } @@ -3368,10 +3369,11 @@ Properties are cacheable by default. @method cacheable @param {Boolean} aFlag optional set to `false` to disable caching + @return {Ember.ComputedProperty} this @chainable */ ComputedPropertyPrototype.cacheable = function(aFlag) { this._cacheable = aFlag !== false; return this; @@ -3388,10 +3390,11 @@ }.property().volatile() }); ``` @method volatile + @return {Ember.ComputedProperty} this @chainable */ ComputedPropertyPrototype.volatile = function() { return this.cacheable(false); }; @@ -3409,10 +3412,11 @@ MyApp.person.set('guid', 'new-guid'); // will throw an exception ``` @method readOnly + @return {Ember.ComputedProperty} this @chainable */ ComputedPropertyPrototype.readOnly = function(readOnly) { this._readOnly = readOnly === undefined || !!readOnly; return this; @@ -3433,10 +3437,11 @@ }); ``` @method property @param {String} path* zero or more property paths + @return {Ember.ComputedProperty} this @chainable */ ComputedPropertyPrototype.property = function() { var args = []; for (var i = 0, l = arguments.length; i < l; i++) { @@ -3662,71 +3667,253 @@ @method cacheFor @for Ember @param {Object} obj the object whose property you want to check @param {String} key the name of the property whose cached value you want to return + @return {any} the cached value */ Ember.cacheFor = function cacheFor(obj, key) { var cache = metaFor(obj, false).cache; if (cache && key in cache) { return cache[key]; } }; +function getProperties(self, propertyNames) { + var ret = {}; + for(var i = 0; i < propertyNames.length; i++) { + ret[propertyNames[i]] = get(self, propertyNames[i]); + } + return ret; +} + +function registerComputed(name, macro) { + Ember.computed[name] = function(dependentKey) { + var args = a_slice.call(arguments); + return Ember.computed(dependentKey, function() { + return macro.apply(this, args); + }); + }; +} + +function registerComputedWithProperties(name, macro) { + Ember.computed[name] = function() { + var properties = a_slice.call(arguments); + + var computed = Ember.computed(function() { + return macro.apply(this, [getProperties(this, properties)]); + }); + + return computed.property.apply(computed, properties); + }; +} + /** - @method computed.not + @method computed.empty @for Ember @param {String} dependentKey + @return {Ember.ComputedProperty} computed property which negate + the original value for property */ -Ember.computed.not = function(dependentKey) { - return Ember.computed(dependentKey, function(key) { - return !get(this, dependentKey); - }); -}; +registerComputed('empty', function(dependentKey) { + return Ember.isEmpty(get(this, dependentKey)); +}); /** + @method computed.notEmpty + @for Ember + @param {String} dependentKey + @return {Ember.ComputedProperty} computed property which returns true if + original value for property is not empty. +*/ +registerComputed('notEmpty', function(dependentKey) { + return !Ember.isEmpty(get(this, dependentKey)); +}); + +/** @method computed.none @for Ember @param {String} dependentKey + @return {Ember.ComputedProperty} computed property which + rturns true if original value for property is null or undefined. */ -Ember.computed.none = function(dependentKey) { - return Ember.computed(dependentKey, function(key) { - var val = get(this, dependentKey); - return Ember.isNone(val); - }); -}; +registerComputed('none', function(dependentKey) { + return Ember.isNone(get(this, dependentKey)); +}); /** - @method computed.empty + @method computed.not @for Ember @param {String} dependentKey + @return {Ember.ComputedProperty} computed property which returns + inverse of the original value for property */ -Ember.computed.empty = function(dependentKey) { - return Ember.computed(dependentKey, function(key) { - var val = get(this, dependentKey); - return Ember.isEmpty(val); - }); -}; +registerComputed('not', function(dependentKey) { + return !get(this, dependentKey); +}); /** @method computed.bool @for Ember @param {String} dependentKey + @return {Ember.ComputedProperty} computed property which convert + to boolean the original value for property */ -Ember.computed.bool = function(dependentKey) { - return Ember.computed(dependentKey, function(key) { - return !!get(this, dependentKey); - }); -}; +registerComputed('bool', function(dependentKey) { + return !!get(this, dependentKey); +}); /** - @method computed.alias + @method computed.match @for Ember + @param {String} dependentKey + @param {RegExp} regexp + @return {Ember.ComputedProperty} computed property which match + the original value for property against a given RegExp +*/ +registerComputed('match', function(dependentKey, regexp) { + var value = get(this, dependentKey); + return typeof value === 'string' ? !!value.match(regexp) : false; +}); +/** + @method computed.equal + @for Ember @param {String} dependentKey + @param {String|Number|Object} value + @return {Ember.ComputedProperty} computed property which returns true if + the original value for property is equal to the given value. */ +registerComputed('equal', function(dependentKey, value) { + return get(this, dependentKey) === value; +}); + +/** + @method computed.gt + @for Ember + @param {String} dependentKey + @param {Number} value + @return {Ember.ComputedProperty} computed property which returns true if + the original value for property is greater then given value. +*/ +registerComputed('gt', function(dependentKey, value) { + return get(this, dependentKey) > value; +}); + +/** + @method computed.gte + @for Ember + @param {String} dependentKey + @param {Number} value + @return {Ember.ComputedProperty} computed property which returns true if + the original value for property is greater or equal then given value. +*/ +registerComputed('gte', function(dependentKey, value) { + return get(this, dependentKey) >= value; +}); + +/** + @method computed.lt + @for Ember + @param {String} dependentKey + @param {Number} value + @return {Ember.ComputedProperty} computed property which returns true if + the original value for property is less then given value. +*/ +registerComputed('lt', function(dependentKey, value) { + return get(this, dependentKey) < value; +}); + +/** + @method computed.lte + @for Ember + @param {String} dependentKey + @param {Number} value + @return {Ember.ComputedProperty} computed property which returns true if + the original value for property is less or equal then given value. +*/ +registerComputed('lte', function(dependentKey, value) { + return get(this, dependentKey) <= value; +}); + +/** + @method computed.and + @for Ember + @param {String} dependentKey, [dependentKey...] + @return {Ember.ComputedProperty} computed property which peforms + a logical `and` on the values of all the original values for properties. +*/ +registerComputedWithProperties('and', function(properties) { + for (var key in properties) { + if (properties.hasOwnProperty(key) && !properties[key]) { + return false; + } + } + return true; +}); + +/** + @method computed.or + @for Ember + @param {String} dependentKey, [dependentKey...] + @return {Ember.ComputedProperty} computed property which peforms + a logical `or` on the values of all the original values for properties. +*/ +registerComputedWithProperties('or', function(properties) { + for (var key in properties) { + if (properties.hasOwnProperty(key) && properties[key]) { + return true; + } + } + return false; +}); + +/** + @method computed.any + @for Ember + @param {String} dependentKey, [dependentKey...] + @return {Ember.ComputedProperty} computed property which returns + the first trouthy value of given list of properties. +*/ +registerComputedWithProperties('any', function(properties) { + for (var key in properties) { + if (properties.hasOwnProperty(key) && properties[key]) { + return properties[key]; + } + } + return null; +}); + +/** + @method computed.map + @for Ember + @param {String} dependentKey, [dependentKey...] + @return {Ember.ComputedProperty} computed property which maps + values of all passed properties in to an array. +*/ +registerComputedWithProperties('map', function(properties) { + var res = []; + for (var key in properties) { + if (properties.hasOwnProperty(key)) { + if (Ember.isNone(properties[key])) { + res.push(null); + } else { + res.push(properties[key]); + } + } + } + return res; +}); + +/** + @method computed.alias + @for Ember + @param {String} dependentKey + @return {Ember.ComputedProperty} computed property which creates an + alias to the original value for property. +*/ Ember.computed.alias = function(dependentKey) { return Ember.computed(dependentKey, function(key, value){ if (arguments.length > 1) { set(this, dependentKey, value); return value; @@ -3734,10 +3921,27 @@ return get(this, dependentKey); } }); }; +/** + @method computed.defaultTo + @for Ember + @param {String} defaultPath + @return {Ember.ComputedProperty} computed property which acts like + a standard getter and setter, but defaults to the value from `defaultPath`. +*/ +Ember.computed.defaultTo = function(defaultPath) { + return Ember.computed(function(key, newValue, cachedValue) { + var result; + if (arguments.length === 1) { + return cachedValue != null ? cachedValue : get(this, defaultPath); + } + return newValue != null ? newValue : get(this, defaultPath); + }); +}; + })(); (function() { @@ -4566,12 +4770,11 @@ @param {Object} [target] target of method to invoke @param {Function|String} method The method to invoke. If you pass a string it will be resolved on the target at the time the method is invoked. @param {Object} [args*] Optional arguments to pass to the timeout. - @param {Number} wait - Number of milliseconds to wait. + @param {Number} wait Number of milliseconds to wait. @return {String} a string you can use to cancel the timer in {{#crossLink "Ember/run.cancel"}}{{/crossLink}} later. */ Ember.run.later = function(target, method) { var args, expires, timer, guid, wait; @@ -4689,19 +4892,58 @@ Ember.run.scheduleOnce = function(queue, target, method, args) { return scheduleOnce(queue, target, method, slice.call(arguments, 3)); }; /** - Schedules an item to run after control has been returned to the system. - This is equivalent to calling `Ember.run.later` with a wait time of 1ms. + Schedules an item to run from within a separate run loop, after + control has been returned to the system. This is equivalent to calling + `Ember.run.later` with a wait time of 1ms. ```javascript Ember.run.next(myContext, function(){ - // code to be executed in the next RunLoop, which will be scheduled after the current one + // code to be executed in the next run loop, which will be scheduled after the current one }); ``` + Multiple operations scheduled with `Ember.run.next` will coalesce + into the same later run loop, along with any other operations + scheduled by `Ember.run.later` that expire right around the same + time that `Ember.run.next` operations will fire. + + Note that there are often alternatives to using `Ember.run.next`. + For instance, if you'd like to schedule an operation to happen + after all DOM element operations have completed within the current + run loop, you can make use of the `afterRender` run loop queue (added + by the `ember-views` package, along with the preceding `render` queue + where all the DOM element operations happen). Example: + + ```javascript + App.MyCollectionView = Ember.CollectionView.extend({ + didInsertElement: function() { + Ember.run.scheduleOnce('afterRender', this, 'processChildElements'); + }, + processChildElements: function() { + // ... do something with collectionView's child view + // elements after they've finished rendering, which + // can't be done within the CollectionView's + // `didInsertElement` hook because that gets run + // before the child elements have been added to the DOM. + } + }); + ``` + + One benefit of the above approach compared to using `Ember.run.next` is + that you will be able to perform DOM/CSS operations before unprocessed + elements are rendered to the screen, which may prevent flickering or + other artifacts caused by delaying processing until after rendering. + + The other major benefit to the above approach is that `Ember.run.next` + introduces an element of non-determinism, which can make things much + harder to test, due to its reliance on `setTimeout`; it's much harder + to guarantee the order of scheduled operations when they are scheduled + outside of the current run loop, i.e. with `Ember.run.next`. + @method next @param {Object} [target] target of method to invoke @param {Function|String} method The method to invoke. If you pass a string it will be resolved on the target at the time the method is invoked. @@ -4864,10 +5106,14 @@ oneWay: function() { this._oneWay = true; return this; }, + /** + @method toString + @return {String} string representation of binding + */ toString: function() { var oneWay = this._oneWay ? '[oneWay]' : ''; return "Ember.Binding<" + guidFor(this) + ">(" + this._from + " -> " + this._to + ")" + oneWay; }, @@ -6252,11 +6498,11 @@ if (type.indexOf(':') !== -1){ options = factory; factory = name; fullName = type; } else { - Ember.deprecate('register("'+type +'", "'+ name+'") is now deprecated in-favour of register("'+type+':'+name+'");', true); + Ember.deprecate('register("'+type +'", "'+ name+'") is now deprecated in-favour of register("'+type+':'+name+'");', false); fullName = type + ":" + name; } var normalizedName = this.normalize(fullName); @@ -8000,21 +8246,23 @@ this.forEach(function(o, idx) { ret[idx] = o; }); return ret ; }, /** - Returns a copy of the array with all null elements removed. + Returns a copy of the array with all null and undefined elements removed. ```javascript - var arr = ["a", null, "c", null]; + var arr = ["a", null, "c", undefined]; arr.compact(); // ["a", "c"] ``` @method compact - @return {Array} the array without null elements. + @return {Array} the array without null and undefined elements. */ - compact: function() { return this.without(null); }, + compact: function() { + return this.filter(function(value) { return value != null; }); + }, /** Returns a new enumerable that excludes the passed value. The default implementation returns an array regardless of the receiver type unless the receiver does not contain the value. @@ -8065,10 +8313,11 @@ For plain enumerables, this property is read only. `Ember.Array` overrides this method. @property [] @type Ember.Array + @return this */ '[]': Ember.computed(function(key, value) { return this; }), @@ -8081,10 +8330,11 @@ mixin. @method addEnumerableObserver @param {Object} target @param {Hash} [opts] + @return this */ addEnumerableObserver: function(target, opts) { var willChange = (opts && opts.willChange) || 'enumerableWillChange', didChange = (opts && opts.didChange) || 'enumerableDidChange'; @@ -8100,10 +8350,11 @@ Removes a registered enumerable observer. @method removeEnumerableObserver @param {Object} target @param {Hash} [opts] + @return this */ removeEnumerableObserver: function(target, opts) { var willChange = (opts && opts.willChange) || 'enumerableWillChange', didChange = (opts && opts.didChange) || 'enumerableDidChange'; @@ -8289,10 +8540,11 @@ arr.objectAt(5); // undefined ``` @method objectAt @param {Number} idx The index of the item to return. + @return {any} item at index or undefined */ objectAt: function(idx) { if ((idx < 0) || (idx>=get(this, 'length'))) return undefined ; return get(this, idx); }, @@ -8306,10 +8558,11 @@ arr.objectsAt([2, 3, 4]); // ["c", "d", undefined] ``` @method objectsAt @param {Array} indexes An array of indexes of items to return. + @return {Array} */ objectsAt: function(indexes) { var self = this; return map(indexes, function(idx){ return self.objectAt(idx); }); }, @@ -8325,10 +8578,11 @@ array, it will replace the current content. This property overrides the default property defined in `Ember.Enumerable`. @property [] + @return this */ '[]': Ember.computed(function(key, value) { if (value !== undefined) this.replace(0, get(this, 'length'), value) ; return this ; }), @@ -9042,10 +9296,11 @@ ``` @method insertAt @param {Number} idx index of insert the object at. @param {Object} object object to insert + @return this */ insertAt: function(idx, object) { if (idx > get(this, 'length')) throw new Error(OUT_OF_RANGE_EXCEPTION) ; this.replace(idx, 0, [object]) ; return this ; @@ -9095,10 +9350,11 @@ colors.pushObject(["yellow", "orange"]); // ["red", "green", "blue", "black", ["yellow", "orange"]] ``` @method pushObject @param {anything} obj object to push + @return {any} the same obj passed as param */ pushObject: function(obj) { this.insertAt(get(this, 'length'), obj) ; return obj ; }, @@ -9174,10 +9430,11 @@ colors.unshiftObject(["black", "white"]); // [["black", "white"], "yellow", "red", "green", "blue"] ``` @method unshiftObject @param {anything} obj object to unshift + @return {any} the same obj passed as param */ unshiftObject: function(obj) { this.insertAt(0, obj) ; return obj ; }, @@ -9900,10 +10157,11 @@ @method on @param {String} name The name of the event @param {Object} [target] The "this" binding for the callback @param {Function} method The callback to execute + @return this */ on: function(name, target, method) { Ember.addListener(this, name, target, method); return this; }, @@ -9919,10 +10177,11 @@ @method one @param {String} name The name of the event @param {Object} [target] The "this" binding for the callback @param {Function} method The callback to execute + @return this */ one: function(name, target, method) { if (!method) { method = target; target = null; @@ -9968,10 +10227,11 @@ @method off @param {String} name The name of the event @param {Object} target The target of the subscription @param {Function} method The function of the subscription + @return this */ off: function(name, target, method) { Ember.removeListener(this, name, target, method); return this; }, @@ -10324,15 +10584,25 @@ @default null */ concatenatedProperties: null, /** + Destroyed object property flag. + + if this property is `true` the observers and bindings were already + removed by the effect of calling the `destroy()` method. + @property isDestroyed @default false */ isDestroyed: false, /** + Destruction scheduled flag. The `destroy()` method has been called. + + The object stays intact until the end of the run loop at which point + the `isDestroyed` flag is set. + @property isDestroying @default false */ isDestroying: false,