dist/ember-runtime.js in ember-source-1.0.0.rc5.1 vs dist/ember-runtime.js in ember-source-1.0.0.rc6
- old
+ new
@@ -1,7 +1,7 @@
-// Version: v1.0.0-rc.5-2-g9dc4ad8
-// Last commit: 9dc4ad8 (2013-07-25 20:19:21 -0400)
+// Version: v1.0.0-rc.6-1-g42f0c68
+// Last commit: 42f0c68 (2013-06-23 15:43:35 -0400)
(function() {
/*global __fail__*/
@@ -47,11 +47,16 @@
the text of the Error thrown if the assertion fails.
@param {Boolean} test Must be truthy for the assertion to pass. If
falsy, an exception will be thrown.
*/
Ember.assert = function(desc, test) {
- if (!test) throw new Error("assertion failed: "+desc);
+ Ember.Logger.assert(test, desc);
+
+ if (Ember.testing && !test) {
+ // when testing, ensure test failures when assertions fail
+ throw new Error("Assertion Failed: " + desc);
+ }
};
/**
Display a warning with the provided message. Ember build tools will
@@ -93,16 +98,16 @@
@param {String} message A description of the deprecation.
@param {Boolean} test An optional boolean. If falsy, the deprecation
will be displayed.
*/
Ember.deprecate = function(message, test) {
- if (Ember && Ember.TESTING_DEPRECATION) { return; }
+ if (Ember.TESTING_DEPRECATION) { return; }
if (arguments.length === 1) { test = false; }
if (test) { return; }
- if (Ember && Ember.ENV.RAISE_ON_DEPRECATION) { throw new Error(message); }
+ if (Ember.ENV.RAISE_ON_DEPRECATION) { throw new Error(message); }
var error;
// When using new Error, we can't do the arguments check for Chrome. Alternatives are welcome
try { __fail__.fail(); } catch (e) { error = e; }
@@ -149,12 +154,12 @@
};
};
})();
-// Version: v1.0.0-rc.5-2-g9dc4ad8
-// Last commit: 9dc4ad8 (2013-07-25 20:19:21 -0400)
+// Version: v1.0.0-rc.6-1-g42f0c68
+// Last commit: 42f0c68 (2013-06-23 15:43:35 -0400)
(function() {
var define, requireModule;
@@ -217,11 +222,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.5
+ @version 1.0.0-rc.6
*/
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.
@@ -244,14 +249,14 @@
/**
@property VERSION
@type String
- @default '1.0.0-rc.5'
+ @default '1.0.0-rc.6'
@final
*/
-Ember.VERSION = '1.0.0-rc.5';
+Ember.VERSION = '1.0.0-rc.6';
/**
Standard environmental variables. You can define these in a global `ENV`
variable before loading Ember to control various configuration
settings.
@@ -362,10 +367,23 @@
};
}
}
}
+function assertPolyfill(test, message) {
+ if (!test) {
+ try {
+ // attempt to preserve the stack
+ throw new Error("assertion failed: " + message);
+ } catch(error) {
+ setTimeout(function(){
+ throw error;
+ }, 0);
+ }
+ }
+}
+
/**
Inside Ember-Metal, simply uses the methods from `imports.console`.
Override this to provide more robust logging functionality.
@class Logger
@@ -374,11 +392,12 @@
Ember.Logger = {
log: consoleMethod('log') || Ember.K,
warn: consoleMethod('warn') || Ember.K,
error: consoleMethod('error') || Ember.K,
info: consoleMethod('info') || Ember.K,
- debug: consoleMethod('debug') || consoleMethod('info') || Ember.K
+ debug: consoleMethod('debug') || consoleMethod('info') || Ember.K,
+ assert: consoleMethod('assert') || assertPolyfill
};
// ..........................................................
// ERROR HANDLING
@@ -1642,10 +1661,11 @@
if (!keyName && 'string'===typeof obj) {
keyName = obj;
obj = null;
}
+ Ember.assert("Cannot call get with "+ keyName +" key.", !!keyName);
Ember.assert("Cannot call get with '"+ keyName +"' on an undefined object.", obj !== undefined);
if (obj === null || keyName.indexOf('.') !== -1) {
return getPath(obj, keyName);
}
@@ -1674,34 +1694,43 @@
Ember.get = get;
Ember.config.overrideAccessors();
get = Ember.get;
}
-function firstKey(path) {
- return path.match(FIRST_KEY)[0];
-}
+/**
+ @private
-// assumes path is already normalized
-function normalizeTuple(target, path) {
+ Normalizes a target/path pair to reflect that actual target/path that should
+ be observed, etc. This takes into account passing in global property
+ paths (i.e. a path beginning with a captial letter not defined on the
+ target) and * separators.
+
+ @method normalizeTuple
+ @for Ember
+ @param {Object} target The current target. May be `null`.
+ @param {String} path A path on the target or a global property path.
+ @return {Array} a temporary array with the normalized target/path pair.
+*/
+var normalizeTuple = Ember.normalizeTuple = function(target, path) {
var hasThis = HAS_THIS.test(path),
isGlobal = !hasThis && IS_GLOBAL_PATH.test(path),
key;
if (!target || isGlobal) target = Ember.lookup;
if (hasThis) path = path.slice(5);
if (target === Ember.lookup) {
- key = firstKey(path);
+ key = path.match(FIRST_KEY)[0];
target = get(target, key);
path = path.slice(key.length+1);
}
// must return some kind of path to be valid else other things will break.
if (!path || path.length===0) throw new Error('Invalid Path');
return [ target, path ];
-}
+};
var getPath = Ember._getPath = function(root, path) {
var hasThis, parts, tuple, idx, len;
// If there is no root and path is a key name, return that
@@ -1726,28 +1755,10 @@
if (root && root.isDestroyed) { return undefined; }
}
return root;
};
-/**
- @private
-
- Normalizes a target/path pair to reflect that actual target/path that should
- be observed, etc. This takes into account passing in global property
- paths (i.e. a path beginning with a captial letter not defined on the
- target) and * separators.
-
- @method normalizeTuple
- @for Ember
- @param {Object} target The current target. May be `null`.
- @param {String} path A path on the target or a global property path.
- @return {Array} a temporary array with the normalized target/path pair.
-*/
-Ember.normalizeTuple = function(target, path) {
- return normalizeTuple(target, path);
-};
-
Ember.getWithDefault = function(root, key, defaultValue) {
var value = get(root, key);
if (value === undefined) { return defaultValue; }
return value;
@@ -2463,10 +2474,12 @@
value = keyName;
keyName = obj;
obj = null;
}
+ Ember.assert("Cannot call set with "+ keyName +" key.", !!keyName);
+
if (!obj || keyName.indexOf('.') !== -1) {
return setPath(obj, keyName, value, tolerant);
}
Ember.assert("You need to provide an object and key to `set`.", !!obj && keyName !== undefined);
@@ -3114,13 +3127,13 @@
Set a list of properties on an object. These properties are set inside
a single `beginPropertyChanges` and `endPropertyChanges` batch, so
observers will be buffered.
@method setProperties
- @param target
- @param {Hash} properties
- @return target
+ @param self
+ @param {Object} hash
+ @return self
*/
Ember.setProperties = function(self, hash) {
changeProperties(function(){
for(var prop in hash) {
if (hash.hasOwnProperty(prop)) { set(self, prop, hash[prop]); }
@@ -4756,19 +4769,21 @@
hasTimers: function() {
return !!timers.length || autorun;
},
cancel: function(timer) {
- if (typeof timer === 'object' && timer.queue && timer.method) { // we're cancelling a deferOnce
+ if (timer && typeof timer === 'object' && timer.queue && timer.method) { // we're cancelling a deferOnce
return timer.queue.cancel(timer);
} else if (typeof timer === 'function') { // we're cancelling a setTimeout
for (var i = 0, l = timers.length; i < l; i += 2) {
if (timers[i + 1] === timer) {
timers.splice(i, 2); // remove the two elements
return true;
}
}
+ } else {
+ return; // timer was null or not a timer
}
}
};
Backburner.prototype.schedule = Backburner.prototype.defer;
@@ -4857,11 +4872,11 @@
outerloop:
while (queueNameIndex < numberOfQueues) {
queueName = queueNames[queueNameIndex];
queue = queues[queueName];
- queueItems = queue._queue.slice();
+ queueItems = queue._queueBeingFlushed = queue._queue.slice();
queue._queue = [];
var options = queue.options,
before = options && options.before,
after = options && options.after,
@@ -4875,19 +4890,23 @@
args = queueItems[queueIndex+2];
stack = queueItems[queueIndex+3]; // Debugging assistance
if (typeof method === 'string') { method = target[method]; }
- // TODO: error handling
- if (args && args.length > 0) {
- method.apply(target, args);
- } else {
- method.call(target);
+ // method could have been nullified / canceled during flush
+ if (method) {
+ // TODO: error handling
+ if (args && args.length > 0) {
+ method.apply(target, args);
+ } else {
+ method.call(target);
+ }
}
queueIndex += 4;
}
+ queue._queueBeingFlushed = null;
if (numberOfQueueItems && after) { after(); }
if ((priorQueueNameIndex = indexOfPriorQueueWithActions(this, queueNameIndex)) !== -1) {
queueNameIndex = priorQueueNameIndex;
continue outerloop;
@@ -4908,10 +4927,11 @@
}
return -1;
}
+
__exports__.DeferredActionQueues = DeferredActionQueues;
});
define("backburner/queue",
["exports"],
@@ -4997,16 +5017,34 @@
if (currentTarget === actionToCancel.target && currentMethod === actionToCancel.method) {
queue.splice(i, 4);
return true;
}
}
+
+ // if not found in current queue
+ // could be in the queue that is being flushed
+ queue = this._queueBeingFlushed;
+ if (!queue) {
+ return;
+ }
+ for (i = 0, l = queue.length; i < l; i += 4) {
+ currentTarget = queue[i];
+ currentMethod = queue[i+1];
+
+ if (currentTarget === actionToCancel.target && currentMethod === actionToCancel.method) {
+ // don't mess with array during flush
+ // just nullify the method
+ queue[i+1] = null;
+ return true;
+ }
+ }
}
};
+
__exports__.Queue = Queue;
});
-
})();
(function() {
@@ -5110,11 +5148,11 @@
@param {Object} [target] target of method to call
@param {Function|String} method Method to invoke.
May be a function or a string. If you pass a string
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,
+ @return {Object} return value from invoking the passed function. Please note,
when called within an existing loop, no return value is possible.
*/
Ember.run.join = function(target, method) {
if (!Ember.run.currentRunLoop) {
return Ember.run.apply(Ember.run, arguments);
@@ -5246,11 +5284,13 @@
@method sync
@return {void}
*/
Ember.run.sync = function() {
- backburner.currentInstance.queues.sync.flush();
+ if (backburner.currentInstance) {
+ backburner.currentInstance.queues.sync.flush();
+ }
};
/**
Invokes the passed target/method and optional arguments after a specified
period if time. The last parameter of this method must always be a number
@@ -5439,10 +5479,42 @@
*/
Ember.run.cancel = function(timer) {
return backburner.cancel(timer);
};
+/**
+ Execute the passed method in a specified amount of time, reset timer
+ upon additional calls.
+
+ ```javascript
+ var myFunc = function() { console.log(this.name + ' ran.'); };
+ var myContext = {name: 'debounce'};
+
+ Ember.run.debounce(myContext, myFunc, 150);
+
+ // less than 150ms passes
+
+ Ember.run.debounce(myContext, myFunc, 150);
+
+ // 150ms passes
+ // myFunc is invoked with context myContext
+ // console logs 'debounce ran.' one time.
+ ```
+
+ @method debounce
+ @param {Object} [target] target of method to invoke
+ @param {Function|String} method The method to invoke.
+ May be a function or a string. If you pass a string
+ then it will be looked up on the passed target.
+ @param {Object} [args*] Optional arguments to pass to the timeout.
+ @param {Number} wait Number of milliseconds to wait.
+ @return {void}
+*/
+Ember.run.debounce = function() {
+ return backburner.debounce.apply(backburner, arguments);
+};
+
// Make sure it's not an autorun during testing
function checkAutoRun() {
if (!Ember.run.currentRunLoop) {
Ember.assert("You have turned on testing mode, which disabled the run-loop's autorun. You will need to wrap any code with asynchronous side-effects in an Ember.run", !Ember.testing);
}
@@ -7228,10 +7300,12 @@
__exports__.configure = configure;
__exports__.resolve = resolve;
__exports__.reject = reject;
});
+
+
})();
(function() {
define("container",
[],
@@ -7352,10 +7426,14 @@
}
return value;
},
+ lookupFactory: function(fullName) {
+ return factoryFor(this, fullName);
+ },
+
has: function(fullName) {
if (this.cache.has(fullName)) {
return true;
}
@@ -8072,12 +8150,12 @@
'css-class-name'.capitalize() // 'Css-class-name'
'my favorite items'.capitalize() // 'My favorite items'
```
@method capitalize
- @param {String} str
- @return {String}
+ @param {String} str The string to capitalize.
+ @return {String} The capitalized string.
*/
capitalize: function(str) {
return str.charAt(0).toUpperCase() + str.substr(1);
}
@@ -9446,19 +9524,19 @@
/**
Adds an array observer to the receiving array. The array observer object
normally must implement two methods:
- * `arrayWillChange(start, removeCount, addCount)` - This method will be
+ * `arrayWillChange(observedObj, start, removeCount, addCount)` - This method will be
called just before the array is modified.
- * `arrayDidChange(start, removeCount, addCount)` - This method will be
+ * `arrayDidChange(observedObj, start, removeCount, addCount)` - This method will be
called just after the array is modified.
- Both callbacks will be passed the starting index of the change as well a
- a count of the items to be removed and added. You can use these callbacks
- to optionally inspect the array during the change, clear caches, or do
- any other bookkeeping necessary.
+ Both callbacks will be passed the observed object, starting index of the
+ change as well a a count of the items to be removed and added. You can use
+ these callbacks to optionally inspect the array during the change, clear
+ caches, or do any other bookkeeping necessary.
In addition to passing a target, you can also include an options hash
which you can use to override the method names that will be invoked on the
target.
@@ -13462,20 +13540,43 @@
Specifies the arrangedContent's sort direction
@property {Boolean} sortAscending
*/
sortAscending: true,
+
+ /**
+ The function used to compare two values. You can override this if you
+ want to do custom comparisons.Functions must be of the type expected by
+ Array#sort, i.e.
+ return 0 if the two parameters are equal,
+ return a negative value if the first parameter is smaller than the second or
+ return a positive value otherwise:
+ ```javascript
+ function(x,y){ // These are assumed to be integers
+ if(x === y)
+ return 0;
+ return x < y ? -1 : 1;
+ }
+ ```
+
+ @property sortFunction
+ @type {Function}
+ @default Ember.compare
+ */
+ sortFunction: Ember.compare,
+
orderBy: function(item1, item2) {
var result = 0,
sortProperties = get(this, 'sortProperties'),
- sortAscending = get(this, 'sortAscending');
+ sortAscending = get(this, 'sortAscending'),
+ sortFunction = get(this, 'sortFunction');
Ember.assert("you need to define `sortProperties`", !!sortProperties);
forEach(sortProperties, function(propertyName) {
if (result === 0) {
- result = Ember.compare(get(item1, propertyName), get(item2, propertyName));
+ result = sortFunction(get(item1, propertyName), get(item2, propertyName));
if ((result !== 0) && !sortAscending) {
result = (-1) * result;
}
}
});