dist/ember-runtime.js in ember-source-1.7.1 vs dist/ember-runtime.js in ember-source-1.8.0.beta.1

- old
+ new

@@ -3,19 +3,19 @@ * @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.7.1 + * @version 1.8.0-beta.1 */ (function() { var define, requireModule, require, requirejs, Ember; (function() { Ember = this.Ember = this.Ember || {}; - if (typeof Ember === 'undefined') { Ember = {} }; + if (typeof Ember === 'undefined') { Ember = {}; }; if (typeof Ember.__loader === 'undefined') { var registry = {}, seen = {}; define = function(name, deps, callback) { @@ -28,15 +28,15 @@ if (!registry[name]) { throw new Error("Could not find module " + name); } - var mod = registry[name], - deps = mod.deps, - callback = mod.callback, - reified = [], - exports; + var mod = registry[name]; + var deps = mod.deps; + var callback = mod.callback; + var reified = []; + var exports; for (var i=0, l=deps.length; i<l; i++) { if (deps[i] === 'exports') { reified.push(exports = {}); } else { @@ -71,60 +71,47 @@ requirejs = require = requireModule = Ember.__loader.require; } })(); define("backburner", - ["backburner/utils","backburner/deferred_action_queues","exports"], - function(__dependency1__, __dependency2__, __exports__) { + ["backburner/utils","backburner/platform","backburner/binary-search","backburner/deferred-action-queues","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) { "use strict"; - var Utils = __dependency1__["default"]; - var DeferredActionQueues = __dependency2__.DeferredActionQueues; + var each = __dependency1__.each; + var isString = __dependency1__.isString; + var isFunction = __dependency1__.isFunction; + var isNumber = __dependency1__.isNumber; + var isCoercableNumber = __dependency1__.isCoercableNumber; + var wrapInTryCatch = __dependency1__.wrapInTryCatch; - var slice = [].slice, - pop = [].pop, - each = Utils.each, - isString = Utils.isString, - isFunction = Utils.isFunction, - isNumber = Utils.isNumber, - timers = [], - global = this, - NUMBER = /\d+/; + var needsIETryCatchFix = __dependency2__.needsIETryCatchFix; - // In IE 6-8, try/finally doesn't work without a catch. - // Unfortunately, this is impossible to test for since wrapping it in a parent try/catch doesn't trigger the bug. - // This tests for another broken try/catch behavior that only exhibits in the same versions of IE. - var needsIETryCatchFix = (function(e,x){ - try{ x(); } - catch(e) { } // jshint ignore:line - return !!e; - })(); + var searchTimer = __dependency3__["default"]; - function isCoercableNumber(number) { - return isNumber(number) || NUMBER.test(number); - } + var DeferredActionQueues = __dependency4__["default"]; + var slice = [].slice; + var pop = [].pop; + var global = this; + function Backburner(queueNames, options) { this.queueNames = queueNames; this.options = options || {}; if (!this.options.defaultQueue) { this.options.defaultQueue = queueNames[0]; } this.instanceStack = []; this._debouncees = []; this._throttlers = []; + this._timers = []; } Backburner.prototype = { - queueNames: null, - options: null, - currentInstance: null, - instanceStack: null, - begin: function() { - var options = this.options, - onBegin = options && options.onBegin, - previousInstance = this.currentInstance; + var options = this.options; + var onBegin = options && options.onBegin; + var previousInstance = this.currentInstance; if (previousInstance) { this.instanceStack.push(previousInstance); } @@ -133,14 +120,14 @@ onBegin(this.currentInstance, previousInstance); } }, end: function() { - var options = this.options, - onEnd = options && options.onEnd, - currentInstance = this.currentInstance, - nextInstance = null; + var options = this.options; + var onEnd = options && options.onEnd; + var currentInstance = this.currentInstance; + var nextInstance = null; // Prevent double-finally bug in Safari 6.0.2 and iOS 6 // This bug appears to be resolved in Safari 6.0.5 and iOS 7 var finallyAlreadyCalled = false; try { @@ -213,12 +200,23 @@ if (isString(method)) { method = target[method]; } - var stack = this.DEBUG ? new Error() : undefined, - args = arguments.length > 3 ? slice.call(arguments, 3) : undefined; + var stack = this.DEBUG ? new Error() : undefined; + var length = arguments.length; + var args; + + if (length > 3) { + args = new Array(length - 3); + for (var i = 3; i < length; i++) { + args[i-3] = arguments[i]; + } + } else { + args = undefined; + } + if (!this.currentInstance) { createAutorun(this); } return this.currentInstance.schedule(queueName, target, method, args, false, stack); }, deferOnce: function(queueName, target, method /* , args */) { @@ -229,19 +227,36 @@ if (isString(method)) { method = target[method]; } - var stack = this.DEBUG ? new Error() : undefined, - args = arguments.length > 3 ? slice.call(arguments, 3) : undefined; - if (!this.currentInstance) { createAutorun(this); } + var stack = this.DEBUG ? new Error() : undefined; + var length = arguments.length; + var args; + + if (length > 3) { + args = new Array(length - 3); + for (var i = 3; i < length; i++) { + args[i-3] = arguments[i]; + } + } else { + args = undefined; + } + + if (!this.currentInstance) { + createAutorun(this); + } return this.currentInstance.schedule(queueName, target, method, args, true, stack); }, setTimeout: function() { - var args = slice.call(arguments), - length = args.length, + var l = arguments.length; + var args = new Array(l); + for (var x = 0; x < l; x++) { + args[x] = arguments[x]; + } + var length = args.length, method, wait, target, methodOrTarget, methodOrWait, methodOrArgs; if (length === 0) { return; @@ -304,27 +319,24 @@ method.apply(target, args); } } // find position to insert - var i = searchTimer(executeAt, timers); + var i = searchTimer(executeAt, this._timers); - timers.splice(i, 0, executeAt, fn); + this._timers.splice(i, 0, executeAt, fn); updateLaterTimer(this, executeAt, wait); return fn; }, throttle: function(target, method /* , args, wait, [immediate] */) { - var self = this, - args = arguments, - immediate = pop.call(args), - wait, - throttler, - index, - timer; + var self = this; + var args = arguments; + var immediate = pop.call(args); + var wait, throttler, index, timer; if (isNumber(immediate) || isString(immediate)) { wait = immediate; immediate = true; } else { @@ -356,17 +368,14 @@ return throttler; }, debounce: function(target, method /* , args, wait, [immediate] */) { - var self = this, - args = arguments, - immediate = pop.call(args), - wait, - index, - debouncee, - timer; + var self = this; + var args = arguments; + var immediate = pop.call(args); + var wait, index, debouncee, timer; if (isNumber(immediate) || isString(immediate)) { wait = immediate; immediate = false; } else { @@ -395,11 +404,15 @@ if (immediate && index === -1) { self.run.apply(self, args); } - debouncee = [target, method, timer]; + debouncee = [ + target, + method, + timer + ]; self._debouncees.push(debouncee); return debouncee; }, @@ -417,31 +430,40 @@ if (this._laterTimer) { clearTimeout(this._laterTimer); this._laterTimer = null; } - timers = []; + this._timers = []; if (this._autorun) { clearTimeout(this._autorun); this._autorun = null; } }, hasTimers: function() { - return !!timers.length || !!this._debouncees.length || !!this._throttlers.length || this._autorun; + return !!this._timers.length || !!this._debouncees.length || !!this._throttlers.length || this._autorun; }, cancel: function(timer) { var timerType = typeof timer; if (timer && timerType === 'object' && timer.queue && timer.method) { // we're cancelling a deferOnce return timer.queue.cancel(timer); } else if (timerType === '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 + for (var i = 0, l = this._timers.length; i < l; i += 2) { + if (this._timers[i + 1] === timer) { + this._timers.splice(i, 2); // remove the two elements + if (i === 0) { + if (this._laterTimer) { // Active timer? Then clear timer and reset for future timer + clearTimeout(this._laterTimer); + this._laterTimer = null; + } + if (this._timers.length > 0) { // Update to next available timer when available + updateLaterTimer(this, this._timers[0], this._timers[0] - (+new Date())); + } + } return true; } } } else if (Object.prototype.toString.call(timer) === "[object Array]"){ // we're cancelling a throttle or debounce return this._cancelItem(findThrottler, this._throttlers, timer) || @@ -450,22 +472,21 @@ return; // timer was null or not a timer } }, _cancelItem: function(findMethod, array, timer){ - var item, - index; + var item, index; if (timer.length < 3) { return false; } index = findMethod(timer[0], timer[1], array); - if(index > -1) { + if (index > -1) { item = array[index]; - if(item[2] === timer[2]){ + if (item[2] === timer[2]) { array.splice(index, 1); clearTimeout(timer[2]); return true; } } @@ -484,60 +505,64 @@ var originalEnd = Backburner.prototype.end; Backburner.prototype.end = wrapInTryCatch(originalEnd); } - function wrapInTryCatch(func) { - return function () { - try { - return func.apply(this, arguments); - } catch (e) { - throw e; - } - }; - } - function getOnError(options) { return options.onError || (options.onErrorTarget && options.onErrorTarget[options.onErrorMethod]); } - function createAutorun(backburner) { backburner.begin(); backburner._autorun = global.setTimeout(function() { backburner._autorun = null; backburner.end(); }); } function updateLaterTimer(self, executeAt, wait) { - if (!self._laterTimer || executeAt < self._laterTimerExpiresAt) { + var now = (+new Date()); + if (!self._laterTimer || executeAt < self._laterTimerExpiresAt || self._laterTimerExpiresAt < now) { + + if (self._laterTimer) { + // Clear when: + // - Already expired + // - New timer is earlier + clearTimeout(self._laterTimer); + + if (self._laterTimerExpiresAt < now) { // If timer was never triggered + // Calculate the left-over wait-time + wait = Math.max(0, executeAt - now); + } + } + self._laterTimer = global.setTimeout(function() { self._laterTimer = null; self._laterTimerExpiresAt = null; executeTimers(self); }, wait); - self._laterTimerExpiresAt = executeAt; + + self._laterTimerExpiresAt = now + wait; } } function executeTimers(self) { - var now = +new Date(), - time, fns, i, l; + var now = +new Date(); + var fns, i, l; self.run(function() { - i = searchTimer(now, timers); + i = searchTimer(now, self._timers); - fns = timers.splice(0, i); + fns = self._timers.splice(0, i); for (i = 1, l = fns.length; i < l; i += 2) { self.schedule(self.options.defaultQueue, null, fns[i]); } }); - if (timers.length) { - updateLaterTimer(self, timers[0], timers[0] - now); + if (self._timers.length) { + updateLaterTimer(self, self._timers[0], self._timers[0] - now); } } function findDebouncee(target, method, debouncees) { return findItem(target, method, debouncees); @@ -546,12 +571,12 @@ function findThrottler(target, method, throttlers) { return findItem(target, method, throttlers); } function findItem(target, method, collection) { - var item, - index = -1; + var item; + var index = -1; for (var i = 0, l = collection.length; i < l; i++) { item = collection[i]; if (item[0] === target && item[1] === method) { index = i; @@ -560,15 +585,36 @@ } return index; } - function searchTimer(time, timers) { - var start = 0, - end = timers.length - 2, - middle, l; + __exports__["default"] = Backburner; + }); +define("backburner.umd", + ["./backburner"], + function(__dependency1__) { + "use strict"; + var Backburner = __dependency1__["default"]; + /* global define:true module:true window: true */ + if (typeof define === 'function' && define.amd) { + define(function() { return Backburner; }); + } else if (typeof module !== 'undefined' && module.exports) { + module.exports = Backburner; + } else if (typeof this !== 'undefined') { + this['Backburner'] = Backburner; + } + }); +define("backburner/binary-search", + ["exports"], + function(__exports__) { + "use strict"; + __exports__["default"] = function binarySearch(time, timers) { + var start = 0; + var end = timers.length - 2; + var middle, l; + while (start < end) { // since timers is an array of pairs 'l' will always // be an integer l = (end - start) / 2; @@ -583,121 +629,118 @@ } } return (time >= timers[start]) ? start + 2 : start; } - - __exports__.Backburner = Backburner; }); -define("backburner/deferred_action_queues", - ["backburner/utils","backburner/queue","exports"], +define("backburner/deferred-action-queues", + ["./utils","./queue","exports"], function(__dependency1__, __dependency2__, __exports__) { "use strict"; - var Utils = __dependency1__["default"]; - var Queue = __dependency2__.Queue; + var each = __dependency1__.each; + var isString = __dependency1__.isString; + var Queue = __dependency2__["default"]; - var each = Utils.each, - isString = Utils.isString; - function DeferredActionQueues(queueNames, options) { var queues = this.queues = {}; this.queueNames = queueNames = queueNames || []; this.options = options; each(queueNames, function(queueName) { - queues[queueName] = new Queue(this, queueName, options); + queues[queueName] = new Queue(queueName, options[queueName], options); }); } + function noSuchQueue(name) { + throw new Error("You attempted to schedule an action in a queue (" + name + ") that doesn't exist"); + } + DeferredActionQueues.prototype = { - queueNames: null, - queues: null, - options: null, + schedule: function(name, target, method, args, onceFlag, stack) { + var queues = this.queues; + var queue = queues[name]; - schedule: function(queueName, target, method, args, onceFlag, stack) { - var queues = this.queues, - queue = queues[queueName]; + if (!queue) { noSuchQueue(name); } - if (!queue) { throw new Error("You attempted to schedule an action in a queue (" + queueName + ") that doesn't exist"); } - if (onceFlag) { return queue.pushUnique(target, method, args, stack); } else { return queue.push(target, method, args, stack); } }, - invoke: function(target, method, args, _) { + invoke: function(target, method, args, _, _errorRecordedForStack) { if (args && args.length > 0) { method.apply(target, args); } else { method.call(target); } }, - invokeWithOnError: function(target, method, args, onError) { + invokeWithOnError: function(target, method, args, onError, errorRecordedForStack) { try { if (args && args.length > 0) { method.apply(target, args); } else { method.call(target); } } catch(error) { - onError(error); + onError(error, errorRecordedForStack); } }, flush: function() { - var queues = this.queues, - queueNames = this.queueNames, - queueName, queue, queueItems, priorQueueNameIndex, - queueNameIndex = 0, numberOfQueues = queueNames.length, - options = this.options, - onError = options.onError || (options.onErrorTarget && options.onErrorTarget[options.onErrorMethod]), - invoke = onError ? this.invokeWithOnError : this.invoke; + var queues = this.queues; + var queueNames = this.queueNames; + var queueName, queue, queueItems, priorQueueNameIndex; + var queueNameIndex = 0; + var numberOfQueues = queueNames.length; + var options = this.options; + var onError = options.onError || (options.onErrorTarget && options.onErrorTarget[options.onErrorMethod]); + var invoke = onError ? this.invokeWithOnError : this.invoke; - outerloop: while (queueNameIndex < numberOfQueues) { queueName = queueNames[queueNameIndex]; queue = queues[queueName]; queueItems = queue._queueBeingFlushed = queue._queue.slice(); queue._queue = []; + queue.guidBucket = Object.create(null); - var queueOptions = queue.options, // TODO: write a test for this - before = queueOptions && queueOptions.before, - after = queueOptions && queueOptions.after, - target, method, args, stack, - queueIndex = 0, numberOfQueueItems = queueItems.length; + var queueOptions = queue.options; // TODO: write a test for this + var before = queueOptions && queueOptions.before; + var after = queueOptions && queueOptions.after; + var target, method, args, errorRecordedForStack; + var queueIndex = 0; + var numberOfQueueItems = queueItems.length; if (numberOfQueueItems && before) { before(); } while (queueIndex < numberOfQueueItems) { - target = queueItems[queueIndex]; - method = queueItems[queueIndex+1]; - args = queueItems[queueIndex+2]; - stack = queueItems[queueIndex+3]; // Debugging assistance + target = queueItems[queueIndex]; + method = queueItems[queueIndex+1]; + args = queueItems[queueIndex+2]; + errorRecordedForStack = queueItems[queueIndex+3]; // Debugging assistance if (isString(method)) { method = target[method]; } // method could have been nullified / canceled during flush if (method) { - invoke(target, method, args, onError); + invoke(target, method, args, onError, errorRecordedForStack); } queueIndex += 4; } queue._queueBeingFlushed = null; if (numberOfQueueItems && after) { after(); } if ((priorQueueNameIndex = indexOfPriorQueueWithActions(this, queueNameIndex)) !== -1) { queueNameIndex = priorQueueNameIndex; - continue outerloop; + } else { + queueNameIndex++; } - - queueNameIndex++; } } }; function indexOfPriorQueueWithActions(daq, currentQueueIndex) { @@ -710,65 +753,139 @@ } return -1; } - __exports__.DeferredActionQueues = DeferredActionQueues; + __exports__["default"] = DeferredActionQueues; }); +define("backburner/platform", + ["exports"], + function(__exports__) { + "use strict"; + // In IE 6-8, try/finally doesn't work without a catch. + // Unfortunately, this is impossible to test for since wrapping it in a parent try/catch doesn't trigger the bug. + // This tests for another broken try/catch behavior that only exhibits in the same versions of IE. + var needsIETryCatchFix = (function(e,x){ + try{ x(); } + catch(e) { } // jshint ignore:line + return !!e; + })(); + __exports__.needsIETryCatchFix = needsIETryCatchFix; + }); define("backburner/queue", ["exports"], function(__exports__) { "use strict"; - function Queue(daq, name, options) { - this.daq = daq; + function Queue(name, options, globalOptions) { this.name = name; - this.globalOptions = options; - this.options = options[name]; + this.globalOptions = globalOptions || {}; + this.options = options; this._queue = []; + this.targetQueues = Object.create(null); + this._queueBeingFlushed = undefined; } Queue.prototype = { - daq: null, - name: null, - options: null, - onError: null, - _queue: null, - push: function(target, method, args, stack) { var queue = this._queue; queue.push(target, method, args, stack); - return {queue: this, target: target, method: method}; + + return { + queue: this, + target: target, + method: method + }; }, - pushUnique: function(target, method, args, stack) { - var queue = this._queue, currentTarget, currentMethod, i, l; + pushUniqueWithoutGuid: function(target, method, args, stack) { + var queue = this._queue; - for (i = 0, l = queue.length; i < l; i += 4) { - currentTarget = queue[i]; - currentMethod = queue[i+1]; + for (var i = 0, l = queue.length; i < l; i += 4) { + var currentTarget = queue[i]; + var currentMethod = queue[i+1]; if (currentTarget === target && currentMethod === method) { - queue[i+2] = args; // replace args + queue[i+2] = args; // replace args queue[i+3] = stack; // replace stack - return {queue: this, target: target, method: method}; + return; } } queue.push(target, method, args, stack); - return {queue: this, target: target, method: method}; }, + targetQueue: function(targetQueue, target, method, args, stack) { + var queue = this._queue; + + for (var i = 0, l = targetQueue.length; i < l; i += 4) { + var currentMethod = targetQueue[i]; + var currentIndex = targetQueue[i + 1]; + + if (currentMethod === method) { + queue[currentIndex + 2] = args; // replace args + queue[currentIndex + 3] = stack; // replace stack + return; + } + } + + targetQueue.push( + method, + queue.push(target, method, args, stack) - 4 + ); + }, + + pushUniqueWithGuid: function(guid, target, method, args, stack) { + var hasLocalQueue = this.targetQueues[guid]; + + if (hasLocalQueue) { + this.targetQueue(hasLocalQueue, target, method, args, stack); + } else { + this.targetQueues[guid] = [ + method, + this._queue.push(target, method, args, stack) - 4 + ]; + } + + return { + queue: this, + target: target, + method: method + }; + }, + + pushUnique: function(target, method, args, stack) { + var queue = this._queue, currentTarget, currentMethod, i, l; + var KEY = this.globalOptions.GUID_KEY; + + if (target && KEY) { + var guid = target[KEY]; + if (guid) { + return this.pushUniqueWithGuid(guid, target, method, args, stack); + } + } + + this.pushUniqueWithoutGuid(target, method, args, stack); + + return { + queue: this, + target: target, + method: method + }; + }, + // TODO: remove me, only being used for Ember.run.sync flush: function() { - var queue = this._queue, - globalOptions = this.globalOptions, - options = this.options, - before = options && options.before, - after = options && options.after, - onError = globalOptions.onError || (globalOptions.onErrorTarget && globalOptions.onErrorTarget[globalOptions.onErrorMethod]), - target, method, args, stack, i, l = queue.length; + var queue = this._queue; + var globalOptions = this.globalOptions; + var options = this.options; + var before = options && options.before; + var after = options && options.after; + var onError = globalOptions.onError || (globalOptions.onErrorTarget && globalOptions.onErrorTarget[globalOptions.onErrorMethod]); + var target, method, args, stack, i, l = queue.length; + this.targetQueues = Object.create(null); + if (l && before) { before(); } for (i = 0; i < l; i += 4) { target = queue[i]; method = queue[i+1]; args = queue[i+2]; @@ -839,37 +956,52 @@ } } } }; - __exports__.Queue = Queue; + __exports__["default"] = Queue; }); define("backburner/utils", ["exports"], function(__exports__) { "use strict"; - __exports__["default"] = { - each: function(collection, callback) { - for (var i = 0; i < collection.length; i++) { - callback(collection[i]); - } - }, + var NUMBER = /\d+/; - isString: function(suspect) { - return typeof suspect === 'string'; - }, + function each(collection, callback) { + for (var i = 0; i < collection.length; i++) { + callback(collection[i]); + } + } - isFunction: function(suspect) { - return typeof suspect === 'function'; - }, + __exports__.each = each;function isString(suspect) { + return typeof suspect === 'string'; + } - isNumber: function(suspect) { - return typeof suspect === 'number'; - } - }; - }); + __exports__.isString = isString;function isFunction(suspect) { + return typeof suspect === 'function'; + } + __exports__.isFunction = isFunction;function isNumber(suspect) { + return typeof suspect === 'number'; + } + + __exports__.isNumber = isNumber;function isCoercableNumber(number) { + return isNumber(number) || NUMBER.test(number); + } + + __exports__.isCoercableNumber = isCoercableNumber;function wrapInTryCatch(func) { + return function () { + try { + return func.apply(this, arguments); + } catch (e) { + throw e; + } + }; + } + + __exports__.wrapInTryCatch = wrapInTryCatch; + }); define("calculateVersion", [], function() { "use strict"; 'use strict'; @@ -935,38 +1067,39 @@ var Container = __dependency1__["default"]; __exports__["default"] = Container; }); define("container/container", - ["container/inheriting_dict","ember-metal/core","exports"], + ["ember-metal/core","ember-metal/dictionary","exports"], function(__dependency1__, __dependency2__, __exports__) { "use strict"; - var InheritingDict = __dependency1__["default"]; - var Ember = __dependency2__["default"]; + var Ember = __dependency1__["default"]; // Ember.assert + var dictionary = __dependency2__["default"]; // A lightweight container that helps to assemble and decouple components. // Public api for the container is still in flux. // The public api, specified on the application namespace should be considered the stable api. function Container(parent) { this.parent = parent; this.children = []; this.resolver = parent && parent.resolver || function() {}; - this.registry = new InheritingDict(parent && parent.registry); - this.cache = new InheritingDict(parent && parent.cache); - this.factoryCache = new InheritingDict(parent && parent.factoryCache); - this.resolveCache = new InheritingDict(parent && parent.resolveCache); - this.typeInjections = new InheritingDict(parent && parent.typeInjections); - this.injections = {}; + this.registry = dictionary(parent ? parent.registry : null); + this.cache = dictionary(parent ? parent.cache : null); + this.factoryCache = dictionary(parent ? parent.factoryCache : null); + this.resolveCache = dictionary(parent ? parent.resolveCache : null); + this.typeInjections = dictionary(parent ? parent.typeInjections : null); + this.injections = dictionary(null); + this.normalizeCache = dictionary(null); - this.factoryTypeInjections = new InheritingDict(parent && parent.factoryTypeInjections); - this.factoryInjections = {}; + this.factoryTypeInjections = dictionary(parent ? parent.factoryTypeInjections : null); + this.factoryInjections = dictionary(null); - this._options = new InheritingDict(parent && parent._options); - this._typeOptions = new InheritingDict(parent && parent._typeOptions); + this._options = dictionary(parent ? parent._options : null); + this._typeOptions = dictionary(parent ? parent._typeOptions : null); } Container.prototype = { /** @@ -1083,16 +1216,16 @@ throw new TypeError('Attempting to register an unknown factory: `' + fullName + '`'); } var normalizedName = this.normalize(fullName); - if (this.cache.has(normalizedName)) { + if (normalizedName in this.cache) { throw new Error('Cannot re-register: `' + fullName +'`, as it has already been looked up.'); } - this.registry.set(normalizedName, factory); - this._options.set(normalizedName, options || {}); + this.registry[normalizedName] = factory; + this._options[normalizedName] = (options || {}); }, /** Unregister a fullName @@ -1112,15 +1245,15 @@ unregister: function(fullName) { Ember.assert('fullName must be a proper full name', validateFullName(fullName)); var normalizedName = this.normalize(fullName); - this.registry.remove(normalizedName); - this.cache.remove(normalizedName); - this.factoryCache.remove(normalizedName); - this.resolveCache.remove(normalizedName); - this._options.remove(normalizedName); + delete this.registry[normalizedName]; + delete this.cache[normalizedName]; + delete this.factoryCache[normalizedName]; + delete this.resolveCache[normalizedName]; + delete this._options[normalizedName]; }, /** Given a fullName return the corresponding factory. @@ -1175,16 +1308,29 @@ }, /** A hook to enable custom fullName normalization behaviour + @method normalizeFullName + @param {String} fullName + @return {string} normalized fullName + */ + normalizeFullName: function(fullName) { + return fullName; + }, + + /** + normalize a fullName based on the applications conventions + @method normalize @param {String} fullName @return {string} normalized fullName */ normalize: function(fullName) { - return fullName; + return this.normalizeCache[fullName] || ( + this.normalizeCache[fullName] = this.normalizeFullName(fullName) + ); }, /** @method makeToString @@ -1293,11 +1439,11 @@ @param {Object} options */ optionsForType: function(type, options) { if (this.parent) { illegalChildOperation('optionsForType'); } - this._typeOptions.set(type, options); + this._typeOptions[type] = options; }, /** @method options @param {String} type @@ -1342,16 +1488,18 @@ @param {String} property @param {String} fullName */ typeInjection: function(type, property, fullName) { Ember.assert('fullName must be a proper full name', validateFullName(fullName)); + if (this.parent) { illegalChildOperation('typeInjection'); } var fullNameType = fullName.split(':')[0]; - if(fullNameType === type) { + if (fullNameType === type) { throw new Error('Cannot inject a `' + fullName + '` on other ' + type + '(s). Register the `' + fullName + '` as a different type and perform the typeInjection.'); } + addTypeInjection(this.typeInjections, type, property, fullName); }, /** Defines injection rules. @@ -1408,11 +1556,11 @@ } Ember.assert('fullName must be a proper full name', validateFullName(fullName)); var normalizedName = this.normalize(fullName); - if (this.cache.has(normalizedName)) { + if (this.cache[normalizedName]) { throw new Error("Attempted to register an injection for a type that has already been looked up. ('" + normalizedName + "', '" + property + "', '" + injectionName + "')"); } addInjection(this.injections, normalizedName, property, normalizedInjectionName); }, @@ -1513,11 +1661,11 @@ return this.factoryTypeInjection(normalizedName, property, normalizedInjectionName); } Ember.assert('fullName must be a proper full name', validateFullName(fullName)); - if (this.factoryCache.has(normalizedName)) { + if (this.factoryCache[normalizedName]) { throw new Error('Attempted to register a factoryInjection for a type that has already ' + 'been looked up. (\'' + normalizedName + '\', \'' + property + '\', \'' + injectionName + '\')'); } addInjection(this.factoryInjections, normalizedName, property, normalizedInjectionName); @@ -1555,40 +1703,40 @@ resetCache(this); } }; function resolve(container, normalizedName) { - var cached = container.resolveCache.get(normalizedName); + var cached = container.resolveCache[normalizedName]; if (cached) { return cached; } - var resolved = container.resolver(normalizedName) || container.registry.get(normalizedName); - container.resolveCache.set(normalizedName, resolved); + var resolved = container.resolver(normalizedName) || container.registry[normalizedName]; + container.resolveCache[normalizedName] = resolved; return resolved; } function has(container, fullName){ - if (container.cache.has(fullName)) { + if (container.cache[fullName]) { return true; } return !!container.resolve(fullName); } function lookup(container, fullName, options) { options = options || {}; - if (container.cache.has(fullName) && options.singleton !== false) { - return container.cache.get(fullName); + if (container.cache[fullName] && options.singleton !== false) { + return container.cache[fullName]; } var value = instantiate(container, fullName); if (value === undefined) { return; } if (isSingleton(container, fullName) && options.singleton !== false) { - container.cache.set(fullName, value); + container.cache[fullName] = value; } return value; } @@ -1622,73 +1770,74 @@ return hash; } function option(container, fullName, optionName) { - var options = container._options.get(fullName); + var options = container._options[fullName]; if (options && options[optionName] !== undefined) { return options[optionName]; } var type = fullName.split(':')[0]; - options = container._typeOptions.get(type); + options = container._typeOptions[type]; if (options) { return options[optionName]; } } function factoryFor(container, fullName) { var cache = container.factoryCache; - if (cache.has(fullName)) { - return cache.get(fullName); + if (cache[fullName]) { + return cache[fullName]; } var factory = container.resolve(fullName); if (factory === undefined) { return; } var type = fullName.split(':')[0]; if (!factory || typeof factory.extend !== 'function' || (!Ember.MODEL_FACTORY_INJECTIONS && type === 'model')) { // TODO: think about a 'safe' merge style extension // for now just fallback to create time injection + cache[fullName] = factory; return factory; } else { var injections = injectionsFor(container, fullName); var factoryInjections = factoryInjectionsFor(container, fullName); factoryInjections._toString = container.makeToString(factory, fullName); var injectedFactory = factory.extend(injections); injectedFactory.reopenClass(factoryInjections); - cache.set(fullName, injectedFactory); + cache[fullName] = injectedFactory; return injectedFactory; } } function injectionsFor(container, fullName) { - var splitName = fullName.split(':'), - type = splitName[0], - injections = []; + var splitName = fullName.split(':'); + var type = splitName[0]; + var injections = []; - injections = injections.concat(container.typeInjections.get(type) || []); + injections = injections.concat(container.typeInjections[type] || []); injections = injections.concat(container.injections[fullName] || []); injections = buildInjections(container, injections); injections._debugContainerKey = fullName; injections.container = container; return injections; } function factoryInjectionsFor(container, fullName) { - var splitName = fullName.split(':'), - type = splitName[0], - factoryInjections = []; + var splitName = fullName.split(':'); + var type = splitName[0]; + var factoryInjections = []; - factoryInjections = factoryInjections.concat(container.factoryTypeInjections.get(type) || []); + factoryInjections = factoryInjections.concat(container.factoryTypeInjections[type] || []); factoryInjections = factoryInjections.concat(container.factoryInjections[fullName] || []); factoryInjections = buildInjections(container, factoryInjections); factoryInjections._debugContainerKey = fullName; @@ -1719,30 +1868,38 @@ } } } function eachDestroyable(container, callback) { - container.cache.eachLocal(function(key, value) { - if (option(container, key, 'instantiate') === false) { return; } - callback(value); - }); + var cache = container.cache; + var keys = Ember.keys(cache); + var key, value; + + for (var i = 0, l = keys.length; i < l; i++) { + key = keys[i]; + value = cache[key]; + + if (option(container, key, 'instantiate') !== false) { + callback(value); + } + } } function resetCache(container) { - container.cache.eachLocal(function(key, value) { - if (option(container, key, 'instantiate') === false) { return; } + eachDestroyable(container, function(value) { value.destroy(); }); - container.cache.dict = {}; + + container.cache.dict = dictionary(null); } function addTypeInjection(rules, type, property, fullName) { - var injections = rules.get(type); + var injections = rules[type]; if (!injections) { injections = []; - rules.set(type, injections); + rules[type] = injections; } injections.push({ property: property, fullName: fullName @@ -1757,132 +1914,21 @@ return true; } function addInjection(rules, factoryName, property, injectionName) { var injections = rules[factoryName] = rules[factoryName] || []; - injections.push({ property: property, fullName: injectionName }); + injections.push({ + property: property, + fullName: injectionName + }); } __exports__["default"] = Container; }); -define("container/inheriting_dict", - ["exports"], - function(__exports__) { - "use strict"; - // A safe and simple inheriting object. - function InheritingDict(parent) { - this.parent = parent; - this.dict = {}; - } - - InheritingDict.prototype = { - - /** - @property parent - @type InheritingDict - @default null - */ - - parent: null, - - /** - Object used to store the current nodes data. - - @property dict - @type Object - @default Object - */ - dict: null, - - /** - Retrieve the value given a key, if the value is present at the current - level use it, otherwise walk up the parent hierarchy and try again. If - no matching key is found, return undefined. - - @method get - @param {String} key - @return {any} - */ - get: function(key) { - var dict = this.dict; - - if (dict.hasOwnProperty(key)) { - return dict[key]; - } - - if (this.parent) { - return this.parent.get(key); - } - }, - - /** - Set the given value for the given key, at the current level. - - @method set - @param {String} key - @param {Any} value - */ - set: function(key, value) { - this.dict[key] = value; - }, - - /** - Delete the given key - - @method remove - @param {String} key - */ - remove: function(key) { - delete this.dict[key]; - }, - - /** - Check for the existence of given a key, if the key is present at the current - level return true, otherwise walk up the parent hierarchy and try again. If - no matching key is found, return false. - - @method has - @param {String} key - @return {Boolean} - */ - has: function(key) { - var dict = this.dict; - - if (dict.hasOwnProperty(key)) { - return true; - } - - if (this.parent) { - return this.parent.has(key); - } - - return false; - }, - - /** - Iterate and invoke a callback for each local key-value pair. - - @method eachLocal - @param {Function} callback - @param {Object} binding - */ - eachLocal: function(callback, binding) { - var dict = this.dict; - - for (var prop in dict) { - if (dict.hasOwnProperty(prop)) { - callback.call(binding, prop, dict[prop]); - } - } - } - }; - - __exports__["default"] = InheritingDict; - }); define("ember-metal", - ["ember-metal/core","ember-metal/merge","ember-metal/instrumentation","ember-metal/utils","ember-metal/error","ember-metal/enumerable_utils","ember-metal/platform","ember-metal/array","ember-metal/logger","ember-metal/property_get","ember-metal/events","ember-metal/observer_set","ember-metal/property_events","ember-metal/properties","ember-metal/property_set","ember-metal/map","ember-metal/get_properties","ember-metal/set_properties","ember-metal/watch_key","ember-metal/chains","ember-metal/watch_path","ember-metal/watching","ember-metal/expand_properties","ember-metal/computed","ember-metal/computed_macros","ember-metal/observer","ember-metal/mixin","ember-metal/binding","ember-metal/run_loop","ember-metal/libraries","ember-metal/is_none","ember-metal/is_empty","ember-metal/is_blank","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __dependency19__, __dependency20__, __dependency21__, __dependency22__, __dependency23__, __dependency24__, __dependency25__, __dependency26__, __dependency27__, __dependency28__, __dependency29__, __dependency30__, __dependency31__, __dependency32__, __dependency33__, __exports__) { + ["ember-metal/core","ember-metal/merge","ember-metal/instrumentation","ember-metal/utils","ember-metal/error","ember-metal/enumerable_utils","ember-metal/cache","ember-metal/platform","ember-metal/array","ember-metal/logger","ember-metal/property_get","ember-metal/events","ember-metal/observer_set","ember-metal/property_events","ember-metal/properties","ember-metal/property_set","ember-metal/map","ember-metal/get_properties","ember-metal/set_properties","ember-metal/watch_key","ember-metal/chains","ember-metal/watch_path","ember-metal/watching","ember-metal/expand_properties","ember-metal/computed","ember-metal/computed_macros","ember-metal/observer","ember-metal/mixin","ember-metal/binding","ember-metal/run_loop","ember-metal/libraries","ember-metal/is_none","ember-metal/is_empty","ember-metal/is_blank","ember-metal/is_present","ember-metal/keys","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __dependency19__, __dependency20__, __dependency21__, __dependency22__, __dependency23__, __dependency24__, __dependency25__, __dependency26__, __dependency27__, __dependency28__, __dependency29__, __dependency30__, __dependency31__, __dependency32__, __dependency33__, __dependency34__, __dependency35__, __dependency36__, __exports__) { "use strict"; /** Ember Metal @module ember @@ -1896,11 +1942,10 @@ var subscribe = __dependency3__.subscribe; var unsubscribe = __dependency3__.unsubscribe; var reset = __dependency3__.reset; var generateGuid = __dependency4__.generateGuid; var GUID_KEY = __dependency4__.GUID_KEY; - var GUID_PREFIX = __dependency4__.GUID_PREFIX; var guidFor = __dependency4__.guidFor; var META_DESC = __dependency4__.META_DESC; var EMPTY_META = __dependency4__.EMPTY_META; var meta = __dependency4__.meta; var getMeta = __dependency4__.getMeta; @@ -1918,104 +1963,107 @@ var apply = __dependency4__.apply; var applyStr = __dependency4__.applyStr; var uuid = __dependency4__.uuid; var EmberError = __dependency5__["default"]; var EnumerableUtils = __dependency6__["default"]; + var Cache = __dependency7__["default"]; + var create = __dependency8__.create; + var platform = __dependency8__.platform; + var map = __dependency9__.map; + var forEach = __dependency9__.forEach; + var filter = __dependency9__.filter; + var indexOf = __dependency9__.indexOf; + var Logger = __dependency10__["default"]; - var create = __dependency7__.create; - var platform = __dependency7__.platform; - var map = __dependency8__.map; - var forEach = __dependency8__.forEach; - var filter = __dependency8__.filter; - var indexOf = __dependency8__.indexOf; - var Logger = __dependency9__["default"]; + var get = __dependency11__.get; + var getWithDefault = __dependency11__.getWithDefault; + var normalizeTuple = __dependency11__.normalizeTuple; + var _getPath = __dependency11__._getPath; - var get = __dependency10__.get; - var getWithDefault = __dependency10__.getWithDefault; - var normalizeTuple = __dependency10__.normalizeTuple; - var _getPath = __dependency10__._getPath; + var on = __dependency12__.on; + var addListener = __dependency12__.addListener; + var removeListener = __dependency12__.removeListener; + var suspendListener = __dependency12__.suspendListener; + var suspendListeners = __dependency12__.suspendListeners; + var sendEvent = __dependency12__.sendEvent; + var hasListeners = __dependency12__.hasListeners; + var watchedEvents = __dependency12__.watchedEvents; + var listenersFor = __dependency12__.listenersFor; + var listenersDiff = __dependency12__.listenersDiff; + var listenersUnion = __dependency12__.listenersUnion; - var on = __dependency11__.on; - var addListener = __dependency11__.addListener; - var removeListener = __dependency11__.removeListener; - var suspendListener = __dependency11__.suspendListener; - var suspendListeners = __dependency11__.suspendListeners; - var sendEvent = __dependency11__.sendEvent; - var hasListeners = __dependency11__.hasListeners; - var watchedEvents = __dependency11__.watchedEvents; - var listenersFor = __dependency11__.listenersFor; - var listenersDiff = __dependency11__.listenersDiff; - var listenersUnion = __dependency11__.listenersUnion; + var ObserverSet = __dependency13__["default"]; - var ObserverSet = __dependency12__["default"]; + var propertyWillChange = __dependency14__.propertyWillChange; + var propertyDidChange = __dependency14__.propertyDidChange; + var overrideChains = __dependency14__.overrideChains; + var beginPropertyChanges = __dependency14__.beginPropertyChanges; + var endPropertyChanges = __dependency14__.endPropertyChanges; + var changeProperties = __dependency14__.changeProperties; - var propertyWillChange = __dependency13__.propertyWillChange; - var propertyDidChange = __dependency13__.propertyDidChange; - var overrideChains = __dependency13__.overrideChains; - var beginPropertyChanges = __dependency13__.beginPropertyChanges; - var endPropertyChanges = __dependency13__.endPropertyChanges; - var changeProperties = __dependency13__.changeProperties; + var Descriptor = __dependency15__.Descriptor; + var defineProperty = __dependency15__.defineProperty; + var set = __dependency16__.set; + var trySet = __dependency16__.trySet; - var Descriptor = __dependency14__.Descriptor; - var defineProperty = __dependency14__.defineProperty; - var set = __dependency15__.set; - var trySet = __dependency15__.trySet; + var OrderedSet = __dependency17__.OrderedSet; + var Map = __dependency17__.Map; + var MapWithDefault = __dependency17__.MapWithDefault; + var getProperties = __dependency18__["default"]; + var setProperties = __dependency19__["default"]; + var watchKey = __dependency20__.watchKey; + var unwatchKey = __dependency20__.unwatchKey; + var flushPendingChains = __dependency21__.flushPendingChains; + var removeChainWatcher = __dependency21__.removeChainWatcher; + var ChainNode = __dependency21__.ChainNode; + var finishChains = __dependency21__.finishChains; + var watchPath = __dependency22__.watchPath; + var unwatchPath = __dependency22__.unwatchPath; + var watch = __dependency23__.watch; + var isWatching = __dependency23__.isWatching; + var unwatch = __dependency23__.unwatch; + var rewatch = __dependency23__.rewatch; + var destroy = __dependency23__.destroy; + var expandProperties = __dependency24__["default"]; + var ComputedProperty = __dependency25__.ComputedProperty; + var computed = __dependency25__.computed; + var cacheFor = __dependency25__.cacheFor; - var OrderedSet = __dependency16__.OrderedSet; - var Map = __dependency16__.Map; - var MapWithDefault = __dependency16__.MapWithDefault; - var getProperties = __dependency17__["default"]; - var setProperties = __dependency18__["default"]; - var watchKey = __dependency19__.watchKey; - var unwatchKey = __dependency19__.unwatchKey; - var flushPendingChains = __dependency20__.flushPendingChains; - var removeChainWatcher = __dependency20__.removeChainWatcher; - var ChainNode = __dependency20__.ChainNode; - var finishChains = __dependency20__.finishChains; - var watchPath = __dependency21__.watchPath; - var unwatchPath = __dependency21__.unwatchPath; - var watch = __dependency22__.watch; - var isWatching = __dependency22__.isWatching; - var unwatch = __dependency22__.unwatch; - var rewatch = __dependency22__.rewatch; - var destroy = __dependency22__.destroy; - var expandProperties = __dependency23__["default"]; - var ComputedProperty = __dependency24__.ComputedProperty; - var computed = __dependency24__.computed; - var cacheFor = __dependency24__.cacheFor; - // side effect of defining the computed.* macros - var addObserver = __dependency26__.addObserver; - var observersFor = __dependency26__.observersFor; - var removeObserver = __dependency26__.removeObserver; - var addBeforeObserver = __dependency26__.addBeforeObserver; - var _suspendBeforeObserver = __dependency26__._suspendBeforeObserver; - var _suspendObserver = __dependency26__._suspendObserver; - var _suspendBeforeObservers = __dependency26__._suspendBeforeObservers; - var _suspendObservers = __dependency26__._suspendObservers; - var beforeObserversFor = __dependency26__.beforeObserversFor; - var removeBeforeObserver = __dependency26__.removeBeforeObserver; - var IS_BINDING = __dependency27__.IS_BINDING; - var mixin = __dependency27__.mixin; - var Mixin = __dependency27__.Mixin; - var required = __dependency27__.required; - var aliasMethod = __dependency27__.aliasMethod; - var observer = __dependency27__.observer; - var immediateObserver = __dependency27__.immediateObserver; - var beforeObserver = __dependency27__.beforeObserver; - var Binding = __dependency28__.Binding; - var isGlobalPath = __dependency28__.isGlobalPath; - var bind = __dependency28__.bind; - var oneWay = __dependency28__.oneWay; - var run = __dependency29__["default"]; - var libraries = __dependency30__["default"]; - var isNone = __dependency31__.isNone; - var none = __dependency31__.none; - var isEmpty = __dependency32__.isEmpty; - var empty = __dependency32__.empty; - var isBlank = __dependency33__["default"]; + var addObserver = __dependency27__.addObserver; + var observersFor = __dependency27__.observersFor; + var removeObserver = __dependency27__.removeObserver; + var addBeforeObserver = __dependency27__.addBeforeObserver; + var _suspendBeforeObserver = __dependency27__._suspendBeforeObserver; + var _suspendObserver = __dependency27__._suspendObserver; + var _suspendBeforeObservers = __dependency27__._suspendBeforeObservers; + var _suspendObservers = __dependency27__._suspendObservers; + var beforeObserversFor = __dependency27__.beforeObserversFor; + var removeBeforeObserver = __dependency27__.removeBeforeObserver; + var IS_BINDING = __dependency28__.IS_BINDING; + var mixin = __dependency28__.mixin; + var Mixin = __dependency28__.Mixin; + var required = __dependency28__.required; + var aliasMethod = __dependency28__.aliasMethod; + var observer = __dependency28__.observer; + var immediateObserver = __dependency28__.immediateObserver; + var beforeObserver = __dependency28__.beforeObserver; + var Binding = __dependency29__.Binding; + var isGlobalPath = __dependency29__.isGlobalPath; + var bind = __dependency29__.bind; + var oneWay = __dependency29__.oneWay; + var run = __dependency30__["default"]; + var libraries = __dependency31__["default"]; + var isNone = __dependency32__.isNone; + var none = __dependency32__.none; + var isEmpty = __dependency33__.isEmpty; + var empty = __dependency33__.empty; + var isBlank = __dependency34__["default"]; + var isPresent = __dependency35__["default"]; + var keys = __dependency36__["default"]; + // END IMPORTS // BEGIN EXPORTS var EmberInstrumentation = Ember.Instrumentation = {}; EmberInstrumentation.instrument = instrument; @@ -2024,14 +2072,16 @@ EmberInstrumentation.reset = reset; Ember.instrument = instrument; Ember.subscribe = subscribe; + Ember._Cache = Cache; + Ember.generateGuid = generateGuid; Ember.GUID_KEY = GUID_KEY; - Ember.GUID_PREFIX = GUID_PREFIX; Ember.create = create; + Ember.keys = keys; Ember.platform = platform; var EmberArrayPolyfills = Ember.ArrayPolyfills = {}; EmberArrayPolyfills.map = map; @@ -2162,10 +2212,14 @@ Ember.isEmpty = isEmpty; Ember.empty = empty; Ember.isBlank = isBlank; + + Ember.isPresent = isPresent; + + Ember.merge = merge; /** A function may be assigned to `Ember.onerror` to be called when Ember internals encounter an error. This is useful for specialized error handling @@ -2292,100 +2346,110 @@ var isNativeFunc = function(func) { // This should probably work in all browsers likely to have ES5 array methods return func && Function.prototype.toString.call(func).indexOf('[native code]') > -1; }; + var defineNativeShim = function(nativeFunc, shim) { + if (isNativeFunc(nativeFunc)) { + return nativeFunc; + } + return shim; + }; + // From: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/map - var map = isNativeFunc(ArrayPrototype.map) ? ArrayPrototype.map : function(fun /*, thisp */) { + var map = defineNativeShim(ArrayPrototype.map, function(fun /*, thisp */) { //"use strict"; - if (this === void 0 || this === null) { + if (this === void 0 || this === null || typeof fun !== "function") { throw new TypeError(); } var t = Object(this); var len = t.length >>> 0; - if (typeof fun !== "function") { - throw new TypeError(); - } - var res = new Array(len); var thisp = arguments[1]; + for (var i = 0; i < len; i++) { if (i in t) { res[i] = fun.call(thisp, t[i], i, t); } } return res; - }; + }); // From: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/foreach - var forEach = isNativeFunc(ArrayPrototype.forEach) ? ArrayPrototype.forEach : function(fun /*, thisp */) { + var forEach = defineNativeShim(ArrayPrototype.forEach, function(fun /*, thisp */) { //"use strict"; - if (this === void 0 || this === null) { + if (this === void 0 || this === null || typeof fun !== "function") { throw new TypeError(); } var t = Object(this); var len = t.length >>> 0; - if (typeof fun !== "function") { - throw new TypeError(); - } - var thisp = arguments[1]; + for (var i = 0; i < len; i++) { if (i in t) { fun.call(thisp, t[i], i, t); } } - }; + }); - var indexOf = isNativeFunc(ArrayPrototype.indexOf) ? ArrayPrototype.indexOf : function (obj, fromIndex) { - if (fromIndex === null || fromIndex === undefined) { fromIndex = 0; } - else if (fromIndex < 0) { fromIndex = Math.max(0, this.length + fromIndex); } + var indexOf = defineNativeShim(ArrayPrototype.indexOf, function (obj, fromIndex) { + if (fromIndex === null || fromIndex === undefined) { + fromIndex = 0; + } + else if (fromIndex < 0) { + fromIndex = Math.max(0, this.length + fromIndex); + } + for (var i = fromIndex, j = this.length; i < j; i++) { - if (this[i] === obj) { return i; } + if (this[i] === obj) { + return i; + } } return -1; - }; + }); - var filter = isNativeFunc(ArrayPrototype.filter) ? ArrayPrototype.filter : function (fn, context) { - var i, - value, - result = [], - length = this.length; + var lastIndexOf = defineNativeShim(ArrayPrototype.lastIndexOf, function(obj, fromIndex) { + var len = this.length; + var idx; + if (fromIndex === undefined) fromIndex = len-1; + else fromIndex = (fromIndex < 0) ? Math.ceil(fromIndex) : Math.floor(fromIndex); + if (fromIndex < 0) fromIndex += len; + + for(idx = fromIndex;idx>=0;idx--) { + if (this[idx] === obj) return idx ; + } + return -1; + }); + + var filter = defineNativeShim(ArrayPrototype.filter, function (fn, context) { + var i, value; + var result = []; + var length = this.length; + for (i = 0; i < length; i++) { if (this.hasOwnProperty(i)) { value = this[i]; if (fn.call(context, value, i, this)) { result.push(value); } } } return result; - }; + }); - if (Ember.SHIM_ES5) { - if (!ArrayPrototype.map) { - ArrayPrototype.map = map; - } - - if (!ArrayPrototype.forEach) { - ArrayPrototype.forEach = forEach; - } - - if (!ArrayPrototype.filter) { - ArrayPrototype.filter = filter; - } - - if (!ArrayPrototype.indexOf) { - ArrayPrototype.indexOf = indexOf; - } + ArrayPrototype.map = ArrayPrototype.map || map; + ArrayPrototype.forEach = ArrayPrototype.forEach || forEach; + ArrayPrototype.filter = ArrayPrototype.filter || filter; + ArrayPrototype.indexOf = ArrayPrototype.indexOf || indexOf; + ArrayPrototype.lastIndexOf = ArrayPrototype.lastIndexOf || lastIndexOf; } /** Array polyfills to support ES5 features in older browsers. @@ -2394,14 +2458,15 @@ */ __exports__.map = map; __exports__.forEach = forEach; __exports__.filter = filter; __exports__.indexOf = indexOf; + __exports__.lastIndexOf = lastIndexOf; }); define("ember-metal/binding", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/map","ember-metal/observer","ember-metal/run_loop","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) { + ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/map","ember-metal/observer","ember-metal/run_loop","ember-metal/path_cache","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; // Ember.Logger, Ember.LOG_BINDINGS, assert var get = __dependency2__.get; var set = __dependency3__.set; @@ -2410,11 +2475,13 @@ var Map = __dependency5__.Map; var addObserver = __dependency6__.addObserver; var removeObserver = __dependency6__.removeObserver; var _suspendObserver = __dependency6__._suspendObserver; var run = __dependency7__["default"]; + var isGlobalPath = __dependency8__.isGlobal; + // ES6TODO: where is Ember.lookup defined? /** @module ember-metal */ @@ -2432,25 +2499,20 @@ @type Boolean @default false */ Ember.LOG_BINDINGS = false || !!Ember.ENV.LOG_BINDINGS; - var IS_GLOBAL = /^([A-Z$]|([0-9][A-Z$]))/; - /** Returns true if the provided path is global (e.g., `MyApp.fooController.bar`) instead of local (`foo.bar.baz`). @method isGlobalPath @for Ember @private @param {String} path @return Boolean */ - function isGlobalPath(path) { - return IS_GLOBAL.test(path); - } function getWithGlobals(obj, path) { return get(isGlobalPath(path) ? Ember.lookup : obj, path); } @@ -2562,11 +2624,12 @@ @return {Ember.Binding} `this` */ connect: function(obj) { Ember.assert('Must pass a valid object to Ember.Binding.connect()', !!obj); - var fromPath = this._from, toPath = this._to; + var fromPath = this._from; + var toPath = this._to; trySet(obj, toPath, getWithGlobals(obj, fromPath)); // add an observer on the object to be notified when the binding should be updated addObserver(obj, fromPath, this, this.fromDidChange); @@ -2642,11 +2705,12 @@ // get the direction of the binding for the object we are // synchronizing from var directionMap = this._directionMap; var direction = directionMap.get(obj); - var fromPath = this._from, toPath = this._to; + var fromPath = this._from; + var toPath = this._to; directionMap.remove(obj); // if we're synchronizing from the remote object... if (direction === 'fwd') { @@ -2690,22 +2754,24 @@ @method from @static */ from: function() { - var C = this, binding = new C(); + var C = this; + var binding = new C(); return binding.from.apply(binding, arguments); }, /* See `Ember.Binding.to`. @method to @static */ to: function() { - var C = this, binding = new C(); + var C = this; + var binding = new C(); return binding.to.apply(binding, arguments); }, /** Creates a new Binding instance and makes it apply in a single direction. @@ -2722,11 +2788,12 @@ binding `oneWay`. You can instead pass `false` to disable `oneWay`, making the binding two way again. @return {Ember.Binding} `this` */ oneWay: function(from, flag) { - var C = this, binding = new C(null, from); + var C = this; + var binding = new C(null, from); return binding.oneWay(flag); } }); /** @@ -2893,27 +2960,86 @@ } __exports__.oneWay = oneWay;__exports__.Binding = Binding; __exports__.isGlobalPath = isGlobalPath; }); +define("ember-metal/cache", + ["ember-metal/dictionary","exports"], + function(__dependency1__, __exports__) { + "use strict"; + var dictionary = __dependency1__["default"]; + __exports__["default"] = Cache; + + function Cache(limit, func) { + this.store = dictionary(null); + this.size = 0; + this.misses = 0; + this.hits = 0; + this.limit = limit; + this.func = func; + } + + var FALSE = function() { }; + var ZERO = function() { }; + var UNDEFINED = function() { }; + var NULL = function() { }; + + Cache.prototype = { + set: function(key, value) { + if (this.limit > this.size) { + this.size ++; + if (value === undefined) { + this.store[key] = UNDEFINED; + } else { + this.store[key] = value; + } + } + + return value; + }, + + get: function(key) { + var value = this.store[key]; + + if (value === undefined) { + this.misses ++; + value = this.set(key, this.func(key)); + } else if (value === UNDEFINED) { + this.hits ++; + value = UNDEFINED; + } else { + this.hits ++; + // nothing to translate + } + + return value; + }, + + purge: function() { + this.store = dictionary(null); + this.size = 0; + this.hits = 0; + this.misses = 0; + } + }; + }); define("ember-metal/chains", ["ember-metal/core","ember-metal/property_get","ember-metal/utils","ember-metal/array","ember-metal/watch_key","exports"], function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; // warn, assert, etc; var get = __dependency2__.get; var normalizeTuple = __dependency2__.normalizeTuple; var meta = __dependency3__.meta; - var META_KEY = __dependency3__.META_KEY; var forEach = __dependency4__.forEach; var watchKey = __dependency5__.watchKey; var unwatchKey = __dependency5__.unwatchKey; - var metaFor = meta, - warn = Ember.warn, - FIRST_KEY = /^([^\.]+)/; + var metaFor = meta; + var warn = Ember.warn; + var FIRST_KEY = /^([^\.]+)/; function firstKey(path) { return path.match(FIRST_KEY)[0]; } @@ -2934,11 +3060,12 @@ } __exports__.flushPendingChains = flushPendingChains;function addChainWatcher(obj, keyName, node) { if (!obj || ('object' !== typeof obj)) { return; } // nothing to do - var m = metaFor(obj), nodes = m.chainWatchers; + var m = metaFor(obj); + var nodes = m.chainWatchers; if (!m.hasOwnProperty('chainWatchers')) { nodes = m.chainWatchers = {}; } @@ -2948,11 +3075,11 @@ } function removeChainWatcher(obj, keyName, node) { if (!obj || 'object' !== typeof obj) { return; } // nothing to do - var m = obj[META_KEY]; + var m = obj['__ember_meta__']; if (m && !m.hasOwnProperty('chainWatchers')) { return; } // nothing to do var nodes = m && m.chainWatchers; if (nodes && nodes[keyName]) { @@ -3002,11 +3129,11 @@ var ChainNodePrototype = ChainNode.prototype; function lazyGet(obj, key) { if (!obj) return undefined; - var meta = obj[META_KEY]; + var meta = obj['__ember_meta__']; // check if object meant only to be a prototype if (meta && meta.proto === obj) return undefined; if (key === "@each") return get(obj, key); @@ -3039,12 +3166,14 @@ } }; // copies a top level object only ChainNodePrototype.copy = function(obj) { - var ret = new ChainNode(null, null, obj), - paths = this._paths, path; + 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. ret.add(path); } return ret; @@ -3110,11 +3239,12 @@ }; ChainNodePrototype.count = 0; ChainNodePrototype.chain = function(key, path, src) { - var chains = this._chains, node; + var chains = this._chains; + var node; if (!chains) { chains = this._chains = {}; } node = chains[key]; if (!node) { node = chains[key] = new ChainNode(this, key, src); } node.count++; // count chains... @@ -3126,11 +3256,12 @@ node.chain(key, path); // NOTE: no src means it will observe changes... } }; ChainNodePrototype.unchain = function(key, path) { - var chains = this._chains, node = chains[key]; + 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); @@ -3222,11 +3353,11 @@ 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[META_KEY], chains = m && m.chains; + var m = obj['__ember_meta__'], chains = m && m.chains; if (chains) { if (chains.value() !== obj) { metaFor(obj).chains = chains = chains.copy(obj); } else { chains.didChange(null); @@ -3243,11 +3374,10 @@ "use strict"; var Ember = __dependency1__["default"]; var get = __dependency2__.get; var set = __dependency3__.set; var meta = __dependency4__.meta; - var META_KEY = __dependency4__.META_KEY; var inspect = __dependency4__.inspect; var expandProperties = __dependency5__["default"]; var EmberError = __dependency6__["default"]; var Descriptor = __dependency7__.Descriptor; var defineProperty = __dependency7__.defineProperty; @@ -3261,12 +3391,12 @@ */ Ember.warn("The CP_DEFAULT_CACHEABLE flag has been removed and computed properties are always cached by default. Use `volatile` if you don't want caching.", Ember.ENV.CP_DEFAULT_CACHEABLE !== false); - var metaFor = meta, - a_slice = [].slice; + var metaFor = meta; + var a_slice = [].slice; function UNDEFINED() { } // .......................................................... // COMPUTED PROPERTY @@ -3601,17 +3731,17 @@ @param {Object} newValue The new value being assigned. @param {String} oldValue The old value being replaced. @return {Object} The return value of the function backing the CP. */ ComputedPropertyPrototype.set = function(obj, keyName, value) { - var cacheable = this._cacheable, - func = this.func, - meta = metaFor(obj, cacheable), - oldSuspended = this._suspended, - hadCachedValue = false, - cache = meta.cache, - funcArgLength, cachedValue, ret; + var cacheable = this._cacheable; + var func = this.func; + var meta = metaFor(obj, cacheable); + var oldSuspended = this._suspended; + var hadCachedValue = false; + var cache = meta.cache; + var funcArgLength, cachedValue, ret; if (this._readOnly) { throw new EmberError('Cannot set read-only property "' + keyName + '" on object: ' + inspect(obj)); } @@ -3736,13 +3866,13 @@ @param {String} key the name of the property whose cached value you want to return @return {Object} the cached value */ function cacheFor(obj, key) { - var meta = obj[META_KEY], - cache = meta && meta.cache, - ret = cache && cache[key]; + var meta = obj['__ember_meta__']; + var cache = meta && meta.cache; + var ret = cache && cache[key]; if (ret === UNDEFINED) { return undefined; } return ret; } @@ -4277,11 +4407,11 @@ @method computed.collect @for Ember @param {String} dependentKey* @return {Ember.ComputedProperty} computed property which maps - values of all passed properties in to an array. + values of all passed in properties to an array. */ registerComputedWithProperties('collect', function(properties) { var res = []; for (var key in properties) { if (properties.hasOwnProperty(key)) { @@ -4357,23 +4487,21 @@ */ computed.oneWay = function(dependentKey) { return alias(dependentKey).oneWay(); }; - - /** - This is a more semantically meaningful alias of `computed.oneWay`, - whose name is somewhat ambiguous as to which direction the data flows. + /** + This is a more semantically meaningful alias of `computed.oneWay`, + whose name is somewhat ambiguous as to which direction the data flows. - @method computed.reads - @for Ember - @param {String} dependentKey - @return {Ember.ComputedProperty} computed property which creates a - one way computed property to the original value for property. - */ - computed.reads = computed.oneWay; - + @method computed.reads + @for Ember + @param {String} dependentKey + @return {Ember.ComputedProperty} computed property which creates a + one way computed property to the original value for property. + */ + computed.reads = computed.oneWay; /** Where `computed.oneWay` provides oneWay bindings, `computed.readOnly` provides a readOnly one way binding. Very often when using `computed.oneWay` one does not also want changes to propogate back up, as they will replace the value. @@ -4433,14 +4561,17 @@ @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`. + @deprecated Use `Ember.computed.oneWay` or custom CP with default instead. */ // ES6TODO: computed should have its own export path so you can do import {defaultTo} from computed computed.defaultTo = function(defaultPath) { return computed(function(key, newValue, cachedValue) { + Ember.deprecate('Usage of Ember.computed.defaultTo is deprecated, use `Ember.computed.oneWay` instead.'); + if (arguments.length === 1) { return get(this, defaultPath); } return newValue != null ? newValue : get(this, defaultPath); }); @@ -4498,11 +4629,11 @@ The core Runtime framework is based on the jQuery API with a number of performance optimizations. @class Ember @static - @version 1.7.1 + @version 1.8.0-beta.1 */ 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. @@ -4525,14 +4656,14 @@ /** @property VERSION @type String - @default '1.7.1' + @default '1.8.0-beta.1' @static */ - Ember.VERSION = '1.7.1'; + Ember.VERSION = '1.8.0-beta.1'; /** Standard environmental variables. You can define these in a global `EmberENV` variable before loading Ember to control various configuration settings. @@ -4769,12 +4900,29 @@ keys[keyName] = (keys[keyName] || 0) - 1; // Unwatch the depKey unwatch(obj, depKey, meta); } } + __exports__.removeDependentKeys = removeDependentKeys; }); +define("ember-metal/dictionary", + ["exports"], + function(__exports__) { + "use strict"; + // the delete is meant to hint at runtimes that this object should remain in + // dictionary mode. This is clearly a runtime specific hack, but currently it + // appears worthwile in some usecases. Please note, these deletes do increase + // the cost of creation dramatically over a plain Object.create. And as this + // only makes sense for long-lived dictionaries that aren't instantiated often. + __exports__["default"] = function makeDictionary(parent) { + var dict = Object.create(parent); + dict['_dict'] = null; + delete dict['_dict']; + return dict; + } + }); define("ember-metal/enumerable_utils", ["ember-metal/array","exports"], function(__dependency1__, __exports__) { "use strict"; var _filter = __dependency1__.filter; @@ -4906,13 +5054,17 @@ var index = indexOf(array, item); if (index !== -1) { array.splice(index, 1); } } __exports__.removeObject = removeObject;function _replace(array, idx, amt, objects) { - var args = [].concat(objects), chunk, ret = [], - // https://code.google.com/p/chromium/issues/detail?id=56588 - size = 60000, start = idx, ends = amt, count; + var args = [].concat(objects); + var ret = []; + // https://code.google.com/p/chromium/issues/detail?id=56588 + var size = 60000; + var start = idx; + var ends = amt; + var count, chunk; while (args.length) { count = ends > size ? size : ends; if (count <= 0) { count = 0; } @@ -5063,22 +5215,23 @@ /** @module ember-metal */ var Ember = __dependency1__["default"]; var meta = __dependency2__.meta; - var META_KEY = __dependency2__.META_KEY; var tryFinally = __dependency2__.tryFinally; var apply = __dependency2__.apply; var applyStr = __dependency2__.applyStr; var create = __dependency3__.create; - var a_slice = [].slice, - metaFor = meta, - /* listener flags */ - ONCE = 1, SUSPENDED = 2; + var a_slice = [].slice; + var metaFor = meta; + /* listener flags */ + var ONCE = 1; + var SUSPENDED = 2; + /* The event system uses a series of nested hashes to store listeners on an object. When a listener is registered, or when an event arrives, these hashes are consulted to determine which target and action pair to invoke. @@ -5107,12 +5260,12 @@ } return index; } function actionsFor(obj, eventName) { - var meta = metaFor(obj, true), - actions; + var meta = metaFor(obj, true); + var actions; if (!meta.listeners) { meta.listeners = {}; } if (!meta.hasOwnProperty('listeners')) { // setup inherited copy of the listeners object @@ -5130,37 +5283,37 @@ return actions; } function listenersUnion(obj, eventName, otherActions) { - var meta = obj[META_KEY], - actions = meta && meta.listeners && meta.listeners[eventName]; + var meta = obj['__ember_meta__']; + var actions = meta && meta.listeners && meta.listeners[eventName]; if (!actions) { return; } for (var i = actions.length - 3; i >= 0; i -= 3) { - var target = actions[i], - method = actions[i+1], - flags = actions[i+2], - actionIndex = indexOf(otherActions, target, method); + var target = actions[i]; + var method = actions[i+1]; + var flags = actions[i+2]; + var actionIndex = indexOf(otherActions, target, method); if (actionIndex === -1) { otherActions.push(target, method, flags); } } } __exports__.listenersUnion = listenersUnion;function listenersDiff(obj, eventName, otherActions) { - var meta = obj[META_KEY], - actions = meta && meta.listeners && meta.listeners[eventName], - diffActions = []; + var meta = obj['__ember_meta__']; + var actions = meta && meta.listeners && meta.listeners[eventName]; + var diffActions = []; if (!actions) { return; } for (var i = actions.length - 3; i >= 0; i -= 3) { - var target = actions[i], - method = actions[i+1], - flags = actions[i+2], - actionIndex = indexOf(otherActions, target, method); + var target = actions[i]; + var method = actions[i+1]; + var flags = actions[i+2]; + var actionIndex = indexOf(otherActions, target, method); if (actionIndex !== -1) { continue; } otherActions.push(target, method, flags); diffActions.push(target, method, flags); @@ -5186,13 +5339,13 @@ if (!method && 'function' === typeof target) { method = target; target = null; } - var actions = actionsFor(obj, eventName), - actionIndex = indexOf(actions, target, method), - flags = 0; + var actions = actionsFor(obj, eventName); + var actionIndex = indexOf(actions, target, method); + var flags = 0; if (once) flags |= ONCE; if (actionIndex !== -1) { return; } @@ -5222,12 +5375,12 @@ method = target; target = null; } function _removeListener(target, method) { - var actions = actionsFor(obj, eventName), - actionIndex = indexOf(actions, target, method); + var actions = actionsFor(obj, eventName); + var actionIndex = indexOf(actions, target, method); // action doesn't exist, give up silently if (actionIndex === -1) { return; } actions.splice(actionIndex, 3); @@ -5238,12 +5391,12 @@ } if (method) { _removeListener(target, method); } else { - var meta = obj[META_KEY], - actions = meta && meta.listeners && meta.listeners[eventName]; + var meta = obj['__ember_meta__']; + var actions = meta && meta.listeners && meta.listeners[eventName]; if (!actions) { return; } for (var i = actions.length - 3; i >= 0; i -= 3) { _removeListener(actions[i], actions[i+1]); } @@ -5272,12 +5425,12 @@ if (!method && 'function' === typeof target) { method = target; target = null; } - var actions = actionsFor(obj, eventName), - actionIndex = indexOf(actions, target, method); + var actions = actionsFor(obj, eventName); + var actionIndex = indexOf(actions, target, method); if (actionIndex !== -1) { actions[actionIndex+2] |= SUSPENDED; // mark the action as suspended } @@ -5304,13 +5457,13 @@ if (!method && 'function' === typeof target) { method = target; target = null; } - var suspendedActions = [], - actionsList = [], - eventName, actions, i, l; + var suspendedActions = []; + var actionsList = []; + var eventName, actions, i, l; for (i=0, l=eventNames.length; i<l; i++) { eventName = eventNames[i]; actions = actionsFor(obj, eventName); var actionIndex = indexOf(actions, target, method); @@ -5341,11 +5494,11 @@ @method watchedEvents @for Ember @param obj */ function watchedEvents(obj) { - var listeners = obj[META_KEY].listeners, ret = []; + var listeners = obj['__ember_meta__'].listeners, ret = []; if (listeners) { for(var eventName in listeners) { if (listeners[eventName]) { ret.push(eventName); } } @@ -5372,11 +5525,11 @@ if (obj !== Ember && 'function' === typeof obj.sendEvent) { obj.sendEvent(eventName, params); } if (!actions) { - var meta = obj[META_KEY]; + var meta = obj['__ember_meta__']; actions = meta && meta.listeners && meta.listeners[eventName]; } if (!actions) { return; } @@ -5409,12 +5562,12 @@ @for Ember @param obj @param {String} eventName */ function hasListeners(obj, eventName) { - var meta = obj[META_KEY], - actions = meta && meta.listeners && meta.listeners[eventName]; + var meta = obj['__ember_meta__']; + var actions = meta && meta.listeners && meta.listeners[eventName]; return !!(actions && actions.length); } __exports__.hasListeners = hasListeners;/** @@ -5424,18 +5577,18 @@ @param obj @param {String} eventName */ function listenersFor(obj, eventName) { var ret = []; - var meta = obj[META_KEY], - actions = meta && meta.listeners && meta.listeners[eventName]; + var meta = obj['__ember_meta__']; + var actions = meta && meta.listeners && meta.listeners[eventName]; if (!actions) { return ret; } for (var i = 0, l = actions.length; i < l; i += 3) { - var target = actions[i], - method = actions[i+1]; + var target = actions[i]; + var method = actions[i+1]; ret.push([target, method]); } return ret; } @@ -5462,62 +5615,72 @@ @param {String} eventNames* @param {Function} func @return func */ function on(){ - var func = a_slice.call(arguments, -1)[0], - events = a_slice.call(arguments, 0, -1); + var func = a_slice.call(arguments, -1)[0]; + var events = a_slice.call(arguments, 0, -1); func.__ember_listens__ = events; return func; } __exports__.on = on;__exports__.removeListener = removeListener; }); define("ember-metal/expand_properties", - ["ember-metal/error","ember-metal/enumerable_utils","exports"], - function(__dependency1__, __dependency2__, __exports__) { + ["ember-metal/core","ember-metal/error","ember-metal/enumerable_utils","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __exports__) { "use strict"; - var EmberError = __dependency1__["default"]; - var forEach = __dependency2__.forEach; + var Ember = __dependency1__["default"]; + var EmberError = __dependency2__["default"]; + var forEach = __dependency3__.forEach; /** @module ember-metal */ var BRACE_EXPANSION = /^((?:[^\.]*\.)*)\{(.*)\}$/; + var SPLIT_REGEX = /\{|\}/; /** Expands `pattern`, invoking `callback` for each expansion. The only pattern supported is brace-expansion, anything else will be passed - once to `callback` directly. Brace expansion can only appear at the end of a - pattern, for an example see the last call below. + once to `callback` directly. Example + ```js function echo(arg){ console.log(arg); } - Ember.expandProperties('foo.bar', echo); //=> 'foo.bar' - Ember.expandProperties('{foo,bar}', echo); //=> 'foo', 'bar' - Ember.expandProperties('foo.{bar,baz}', echo); //=> 'foo.bar', 'foo.baz' - Ember.expandProperties('{foo,bar}.baz', echo); //=> '{foo,bar}.baz' + Ember.expandProperties('foo.bar', echo); //=> 'foo.bar' + Ember.expandProperties('{foo,bar}', echo); //=> 'foo', 'bar' + Ember.expandProperties('foo.{bar,baz}', echo); //=> 'foo.bar', 'foo.baz' + Ember.expandProperties('{foo,bar}.baz', echo); //=> '{foo,bar}.baz' + Ember.expandProperties('foo.{bar,baz}.@each', echo) //=> 'foo.bar.@each', 'foo.baz.@each' + Ember.expandProperties('{foo,bar}.{spam,eggs}', echo) //=> 'foo.spam', 'foo.eggs', 'bar.spam', 'bar.eggs' + Ember.expandProperties('{foo}.bar.{baz}') //=> 'foo.bar.baz' ``` @method @private - @param {string} pattern The property pattern to expand. - @param {function} callback The callback to invoke. It is invoked once per + @param {String} pattern The property pattern to expand. + @param {Function} callback The callback to invoke. It is invoked once per expansion, and is passed the expansion. */ __exports__["default"] = function expandProperties(pattern, callback) { - var match, prefix, list; - if (pattern.indexOf(' ') > -1) { - throw new EmberError('Brace expanded properties cannot contain spaces, ' + + throw new EmberError('Brace expanded properties cannot contain spaces, ' + 'e.g. `user.{firstName, lastName}` should be `user.{firstName,lastName}`'); } + + return newExpandProperties(pattern, callback); + } + + function oldExpandProperties(pattern, callback) { + var match, prefix, list; + if (match = BRACE_EXPANSION.exec(pattern)) { prefix = match[1]; list = match[2]; forEach(list.split(','), function (suffix) { @@ -5525,10 +5688,43 @@ }); } else { callback(pattern); } } + + function newExpandProperties(pattern, callback) { + if ('string' === Ember.typeOf(pattern)) { + var parts = pattern.split(SPLIT_REGEX); + var properties = [parts]; + + forEach(parts, function(part, index) { + if (part.indexOf(',') >= 0) { + properties = duplicateAndReplace(properties, part.split(','), index); + } + }); + + forEach(properties, function(property) { + callback(property.join('')); + }); + } else { + callback(pattern); + } + } + + function duplicateAndReplace(properties, currentParts, index) { + var all = []; + + forEach(properties, function(property) { + forEach(currentParts, function(part) { + var current = property.slice(0); + current[index] = part; + all.push(current); + }); + }); + + return all; + } }); define("ember-metal/get_properties", ["ember-metal/property_get","ember-metal/utils","exports"], function(__dependency1__, __dependency2__, __exports__) { "use strict"; @@ -5555,13 +5751,13 @@ @param obj @param {String...|Array} list of keys to get @return {Hash} */ __exports__["default"] = function getProperties(obj) { - var ret = {}, - propertyNames = arguments, - i = 1; + var ret = {}; + var propertyNames = arguments; + var i = 1; if (arguments.length === 2 && typeOf(arguments[1]) === 'array') { i = 0; propertyNames = arguments[1]; } @@ -5622,14 +5818,16 @@ @class Instrumentation @namespace Ember @static */ - var subscribers = [], cache = {}; + var subscribers = []; + __exports__.subscribers = subscribers;var cache = {}; var populateListeners = function(name) { - var listeners = [], subscriber; + var listeners = []; + var subscriber; for (var i=0, l=subscribers.length; i<l; i++) { subscriber = subscribers[i]; if (subscriber.regex.test(name)) { listeners.push(subscriber.object); @@ -5656,60 +5854,74 @@ @param {String} [name] Namespaced event name. @param {Object} payload @param {Function} callback Function that you're instrumenting. @param {Object} binding Context that instrument function is called with. */ - function instrument(name, payload, callback, binding) { - var listeners = cache[name], timeName, ret; - - // ES6TODO: Docs. What is this? - if (Ember.STRUCTURED_PROFILE) { - timeName = name + ": " + payload.object; - console.time(timeName); + function instrument(name, _payload, callback, binding) { + if (subscribers.length === 0) { + return; } + var payload = _payload || {}; + var finalizer = _instrumentStart(name, function () { + return payload; + }); + if (finalizer) { + var tryable = function _instrumenTryable() { + return callback.call(binding); + }; + var catchable = function _instrumentCatchable(e) { + payload.exception = e; + }; + return tryCatchFinally(tryable, catchable, finalizer); + } + } + __exports__.instrument = instrument;// private for now + function _instrumentStart(name, _payload) { + var listeners = cache[name]; + if (!listeners) { listeners = populateListeners(name); } if (listeners.length === 0) { - ret = callback.call(binding); - if (Ember.STRUCTURED_PROFILE) { console.timeEnd(timeName); } - return ret; + return; } - var beforeValues = [], listener, i, l; + var payload = _payload(); - function tryable() { - for (i=0, l=listeners.length; i<l; i++) { - listener = listeners[i]; - beforeValues[i] = listener.before(name, time(), payload); - } - - return callback.call(binding); + var STRUCTURED_PROFILE = Ember.STRUCTURED_PROFILE; + var timeName; + if (STRUCTURED_PROFILE) { + timeName = name + ": " + payload.object; + console.time(timeName); } - function catchable(e) { - payload = payload || {}; - payload.exception = e; + var l = listeners.length; + var beforeValues = new Array(l); + var i, listener; + var timestamp = time(); + for (i=0; i<l; i++) { + listener = listeners[i]; + beforeValues[i] = listener.before(name, timestamp, payload); } - function finalizer() { + return function _instrumentEnd() { + var i, l, listener; + var timestamp = time(); for (i=0, l=listeners.length; i<l; i++) { listener = listeners[i]; - listener.after(name, time(), payload, beforeValues[i]); + listener.after(name, timestamp, payload, beforeValues[i]); } - if (Ember.STRUCTURED_PROFILE) { + if (STRUCTURED_PROFILE) { console.timeEnd(timeName); } - } - - return tryCatchFinally(tryable, catchable, finalizer); + }; } - __exports__.instrument = instrument;/** + __exports__._instrumentStart = _instrumentStart;/** Subscribes to a particular event or instrumented block of code. @method subscribe @namespace Ember.Instrumentation @@ -5771,11 +5983,11 @@ @method reset @namespace Ember.Instrumentation */ function reset() { - subscribers = []; + subscribers.length = 0; cache = {}; } __exports__.reset = reset; }); @@ -5888,10 +6100,120 @@ var none = Ember.deprecateFunc("Ember.none is deprecated. Please use Ember.isNone instead.", isNone); __exports__.none = none; __exports__["default"] = isNone; __exports__.isNone = isNone; }); +define("ember-metal/is_present", + ["ember-metal/is_blank","exports"], + function(__dependency1__, __exports__) { + "use strict"; + var isBlank = __dependency1__["default"]; + var isPresent; + + + /** + A value is present if it not `isBlank`. + + ```javascript + Ember.isPresent(); // false + Ember.isPresent(null); // false + Ember.isPresent(undefined); // false + Ember.isPresent(''); // false + Ember.isPresent([]); // false + Ember.isPresent('\n\t'); // false + Ember.isPresent(' '); // false + Ember.isPresent({}); // true + Ember.isPresent('\n\t Hello'); // true + Ember.isPresent('Hello world'); // true + Ember.isPresent([1,2,3]); // true + ``` + + @method isPresent + @for Ember + @param {Object} obj Value to test + @return {Boolean} + @since 1.7.0 + */ + isPresent = function isPresent(obj) { + return !isBlank(obj); + }; + + + __exports__["default"] = isPresent; + }); +define("ember-metal/keys", + ["ember-metal/enumerable_utils","ember-metal/platform","exports"], + function(__dependency1__, __dependency2__, __exports__) { + "use strict"; + var EnumerableUtils = __dependency1__["default"]; + var create = __dependency2__.create; + + /** + Returns all of the keys defined on an object or hash. This is useful + when inspecting objects for debugging. On browsers that support it, this + uses the native `Object.keys` implementation. + + @method keys + @for Ember + @param {Object} obj + @return {Array} Array containing keys of obj + */ + var keys = Object.keys; + + if (!keys || create.isSimulated) { + var prototypeProperties = [ + 'constructor', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'valueOf', + 'toLocaleString', + 'toString' + ]; + var pushPropertyName = function(obj, array, key) { + // Prevents browsers that don't respect non-enumerability from + // copying internal Ember properties + if (key.substring(0, 2) === '__') { + return; + } + + if (key === '_super') { + return; + } + + if (EnumerableUtils.indexOf(array, key) >= 0) { + return; + } + + if (!Object.prototype.hasOwnProperty.call(obj, key)) { + return; + } + + array.push(key); + }; + + keys = function keys(obj) { + var ret = []; + var key; + + for (key in obj) { + pushPropertyName(obj, ret, key); + } + + // IE8 doesn't enumerate property that named the same as prototype properties. + for (var i = 0, l = prototypeProperties.length; i < l; i++) { + key = prototypeProperties[i]; + + pushPropertyName(obj, ret, key); + } + + return ret; + }; + } + + __exports__["default"] = keys; + }); define("ember-metal/libraries", ["ember-metal/enumerable_utils","exports"], function(__dependency1__, __exports__) { "use strict"; // Provides a way to register library versions with ember. @@ -6121,19 +6443,20 @@ function copy(obj) { var output = {}; for (var prop in obj) { - if (obj.hasOwnProperty(prop)) { output[prop] = obj[prop]; } + // hasOwnPropery is not needed because obj is Object.create(null); + output[prop] = obj[prop]; } return output; } function copyMap(original, newObject) { - var keys = original.keys.copy(), - values = copy(original.values); + var keys = original.keys.copy(); + var values = copy(original.values); newObject.keys = keys; newObject.values = values; newObject.length = original.length; @@ -6161,43 +6484,42 @@ */ OrderedSet.create = function() { return new OrderedSet(); }; - OrderedSet.prototype = { /** @method clear */ clear: function() { - this.presenceSet = {}; + this.presenceSet = Object.create(null); this.list = []; }, /** @method add @param obj */ add: function(obj) { - var guid = guidFor(obj), - presenceSet = this.presenceSet, - list = this.list; + var guid = guidFor(obj); + var presenceSet = this.presenceSet; + var list = this.list; - if (guid in presenceSet) { return; } + if (presenceSet[guid]) { return; } presenceSet[guid] = true; list.push(obj); }, /** @method remove @param obj */ remove: function(obj) { - var guid = guidFor(obj), - presenceSet = this.presenceSet, - list = this.list; + var guid = guidFor(obj); + var presenceSet = this.presenceSet; + var list = this.list; delete presenceSet[guid]; var index = indexOf.call(list, obj); if (index > -1) { @@ -6217,14 +6539,14 @@ @method has @param obj @return {Boolean} */ has: function(obj) { - var guid = guidFor(obj), - presenceSet = this.presenceSet; + var guid = guidFor(obj); + var presenceSet = this.presenceSet; - return guid in presenceSet; + return presenceSet[guid]; }, /** @method forEach @param {Function} fn @@ -6281,11 +6603,11 @@ @private @constructor */ function Map() { this.keys = OrderedSet.create(); - this.values = {}; + this.values = Object.create(null); } Ember.Map = Map; /** @@ -6312,12 +6634,12 @@ @method get @param {*} key @return {*} the value associated with the key, or `undefined` */ get: function(key) { - var values = this.values, - guid = guidFor(key); + var values = this.values; + var guid = guidFor(key); return values[guid]; }, /** @@ -6327,13 +6649,13 @@ @method set @param {*} key @param {*} value */ set: function(key, value) { - var keys = this.keys, - values = this.values, - guid = guidFor(key); + var keys = this.keys; + var values = this.values; + var guid = guidFor(key); keys.add(key); values[guid] = value; set(this, 'length', keys.list.length); }, @@ -6346,15 +6668,15 @@ @return {Boolean} true if an item was removed, false otherwise */ remove: function(key) { // don't use ES6 "delete" because it will be annoying // to use in browsers that are not ES6 friendly; - var keys = this.keys, - values = this.values, - guid = guidFor(key); + var keys = this.keys; + var values = this.values; + var guid = guidFor(key); - if (values.hasOwnProperty(guid)) { + if (values[guid]) { keys.remove(key); delete values[guid]; set(this, 'length', keys.list.length); return true; } else { @@ -6368,14 +6690,14 @@ @method has @param {*} key @return {Boolean} true if the item was present, false otherwise */ has: function(key) { - var values = this.values, - guid = guidFor(key); + var values = this.values; + var guid = guidFor(key); - return values.hasOwnProperty(guid); + return !!values[guid]; }, /** Iterate over all the keys and values. Calls the function once for each key, passing in the key and value, in that order. @@ -6386,12 +6708,12 @@ @param {Function} callback @param {*} self if passed, the `this` value inside the callback. By default, `this` is the map. */ forEach: function(callback, self) { - var keys = this.keys, - values = this.values; + var keys = this.keys; + var values = this.values; keys.forEach(function(key) { var guid = guidFor(key); callback.call(self, key, values[guid]); }); @@ -6414,11 +6736,11 @@ @constructor @param [options] @param {*} [options.defaultValue] */ function MapWithDefault(options) { - Map.call(this); + this._super$constructor(); this.defaultValue = options.defaultValue; } /** @method create @@ -6435,10 +6757,13 @@ return new Map(); } }; MapWithDefault.prototype = create(Map.prototype); + MapWithDefault.prototype.constructor = MapWithDefault; + MapWithDefault.prototype._super$constructor = Map; + MapWithDefault.prototype._super$get = Map.prototype.get; /** Retrieve the value associated with a given key. @method get @@ -6447,11 +6772,11 @@ */ MapWithDefault.prototype.get = function(key) { var hasValue = this.has(key); if (hasValue) { - return Map.prototype.get.call(this, key); + return this._super$get(key); } else { var defaultValue = this.defaultValue(key); this.set(key, defaultValue); return defaultValue; } @@ -6514,11 +6839,10 @@ var indexOf = __dependency3__.indexOf; var forEach = __dependency3__.forEach; var create = __dependency4__.create; var guidFor = __dependency5__.guidFor; var meta = __dependency5__.meta; - var META_KEY = __dependency5__.META_KEY; var wrap = __dependency5__.wrap; var makeArray = __dependency5__.makeArray; var apply = __dependency5__.apply; var expandProperties = __dependency6__["default"]; var Descriptor = __dependency7__.Descriptor; @@ -6530,30 +6854,36 @@ var addBeforeObserver = __dependency10__.addBeforeObserver; var removeBeforeObserver = __dependency10__.removeBeforeObserver; var addListener = __dependency11__.addListener; var removeListener = __dependency11__.removeListener; - var REQUIRED, - a_map = map, - a_indexOf = indexOf, - a_forEach = forEach, - a_slice = [].slice, - o_create = create, - metaFor = meta; + var REQUIRED; + var a_map = map; + var a_indexOf = indexOf; + var a_forEach = forEach; + var a_slice = [].slice; + var o_create = create; + var metaFor = meta; function superFunction(){ - var ret, func = this.__nextSuper; + var func = this.__nextSuper; + var ret; if (func) { + var args = new Array(arguments.length); + for (var i = 0, l = args.length; i < l; i++) { + args[i] = arguments[i]; + } this.__nextSuper = null; - ret = apply(this, func, arguments); + ret = apply(this, func, args); this.__nextSuper = func; } return ret; } function mixinsMeta(obj) { - var m = metaFor(obj, true), ret = m.mixins; + var m = metaFor(obj, true); + var ret = m.mixins; if (!ret) { ret = m.mixins = {}; } else if (!m.hasOwnProperty('mixins')) { ret = m.mixins = o_create(ret); } @@ -6620,11 +6950,11 @@ // If we didn't find the original descriptor in a parent mixin, find // it on the original object. superProperty = superProperty || meta.descs[key]; - if (!superProperty || !(superProperty instanceof ComputedProperty)) { + if (superProperty === undefined || !(superProperty instanceof ComputedProperty)) { return property; } // Since multiple mixins may inherit from the same parent, we need // to clone the computed property so that other mixins do not receive @@ -6647,11 +6977,11 @@ // If we didn't find the original value in a parent mixin, find it in // the original object superMethod = superMethod || obj[key]; // Only wrap the new method if the original method was a function - if ('function' !== typeof superMethod) { + if (superMethod === undefined || 'function' !== typeof superMethod) { return method; } return wrap(method, superMethod); } @@ -6673,12 +7003,12 @@ function applyMergedProperties(obj, key, value, values) { var baseValue = values[key] || obj[key]; if (!baseValue) { return value; } - var newBase = merge({}, baseValue), - hasFunction = false; + var newBase = merge({}, baseValue); + var hasFunction = false; for (var prop in value) { if (!value.hasOwnProperty(prop)) { continue; } var propValue = value[prop]; @@ -6777,11 +7107,12 @@ } } function connectBindings(obj, m) { // TODO Mixin.apply(instance) should disconnect binding if exists - var bindings = m.bindings, key, binding, to; + var bindings = m.bindings; + var key, binding, to; if (bindings) { for (key in bindings) { binding = bindings[key]; if (binding) { to = key.slice(0, -7); // strip Binding off end @@ -6804,11 +7135,12 @@ connectBindings(obj, m || metaFor(obj)); return obj; } function followAlias(obj, desc, m, descs, values) { - var altKey = desc.methodName, value; + var altKey = desc.methodName; + var value; if (descs[altKey] || values[altKey]) { value = values[altKey]; desc = descs[altKey]; } else if (m.descs[altKey]) { desc = m.descs[altKey]; @@ -6846,12 +7178,15 @@ updateObserversAndListeners(obj, key, observerOrListener, '__ember_listens__', addListener); } } function applyMixin(obj, mixins, partial) { - var descs = {}, values = {}, m = metaFor(obj), - key, value, desc, keys = []; + var descs = {}; + var values = {}; + var m = metaFor(obj); + var keys = []; + var key, value, desc; obj._super = superFunction; // Go through all mixins and hashes passed in, and: // @@ -7006,11 +7341,13 @@ this.mixins = [mixin]; } else if (!this.mixins) { this.mixins = []; } - var len = arguments.length, mixins = this.mixins, idx; + var len = arguments.length; + var mixins = this.mixins; + var idx; for(idx=0; idx < len; idx++) { mixin = arguments[idx]; Ember.assert('Expected hash or Mixin instance, got ' + Object.prototype.toString.call(mixin), typeof mixin === 'object' && mixin !== null && Object.prototype.toString.call(mixin) !== '[object Array]'); @@ -7045,11 +7382,12 @@ if (seen[guid]) { return false; } seen[guid] = true; if (curMixin === targetMixin) { return true; } - var mixins = curMixin.mixins, loc = mixins ? mixins.length : 0; + var mixins = curMixin.mixins; + var loc = mixins ? mixins.length : 0; while (--loc >= 0) { if (_detect(mixins[loc], targetMixin, seen)) { return true; } } return false; } @@ -7060,12 +7398,12 @@ @return {Boolean} */ MixinPrototype.detect = function(obj) { if (!obj) { return false; } if (obj instanceof Mixin) { return _detect(obj, this, {}); } - var m = obj[META_KEY], - mixins = m && m.mixins; + var m = obj['__ember_meta__']; + var mixins = m && m.mixins; if (mixins) { return !!mixins[guidFor(this)]; } return false; }; @@ -7089,23 +7427,26 @@ a_forEach.call(mixin.mixins, function(x) { _keys(ret, x, seen); }); } } MixinPrototype.keys = function() { - var keys = {}, seen = {}, ret = []; + var keys = {}; + var seen = {}; + var ret = []; _keys(keys, this, seen); for(var key in keys) { if (keys.hasOwnProperty(key)) { ret.push(key); } } return ret; }; // returns the mixins currently applied to the specified object // TODO: Make Ember.mixin Mixin.mixins = function(obj) { - var m = obj[META_KEY], - mixins = m && m.mixins, ret = []; + var m = obj['__ember_meta__']; + var mixins = m && m.mixins; + var ret = []; if (!mixins) { return ret; } for (var key in mixins) { var mixin = mixins[key]; @@ -7146,11 +7487,11 @@ }, moniker: Ember.aliasMethod('name') }); var goodGuy = App.Person.create(); - + goodGuy.name(); // 'Tomhuda Katzdale' goodGuy.moniker(); // 'Tomhuda Katzdale' ``` @method aliasMethod @@ -7472,15 +7813,15 @@ this.clear(); } ObserverSet.prototype.add = function(sender, keyName, eventName) { - var observerSet = this.observerSet, - observers = this.observers, - senderGuid = guidFor(sender), - keySet = observerSet[senderGuid], - index; + var observerSet = this.observerSet; + var observers = this.observers; + var senderGuid = guidFor(sender); + var keySet = observerSet[senderGuid]; + var index; if (!keySet) { observerSet[senderGuid] = keySet = {}; } index = keySet[keyName]; @@ -7495,11 +7836,12 @@ } return observers[index].listeners; }; ObserverSet.prototype.flush = function() { - var observers = this.observers, i, len, observer, sender; + var observers = this.observers; + var i, len, observer, sender; this.clear(); for (i=0, len=observers.length; i < len; ++i) { observer = observers[i]; sender = observer.sender; if (sender.isDestroying || sender.isDestroyed) { continue; } @@ -7510,10 +7852,50 @@ ObserverSet.prototype.clear = function() { this.observerSet = {}; this.observers = []; }; }); +define("ember-metal/path_cache", + ["ember-metal/cache","exports"], + function(__dependency1__, __exports__) { + "use strict"; + var Cache = __dependency1__["default"]; + + var IS_GLOBAL = /^([A-Z$]|([0-9][A-Z$]))/; + var IS_GLOBAL_PATH = /^([A-Z$]|([0-9][A-Z$])).*[\.]/; + var HAS_THIS = 'this.'; + + var isGlobalCache = new Cache(1000, function(key) { return IS_GLOBAL.test(key); }); + var isGlobalPathCache = new Cache(1000, function(key) { return IS_GLOBAL_PATH.test(key); }); + var hasThisCache = new Cache(1000, function(key) { return key.indexOf(HAS_THIS) !== -1; }); + var isPathCache = new Cache(1000, function(key) { return key.indexOf('.') !== -1; }); + + var caches = { + isGlobalCache: isGlobalCache, + isGlobalPathCache: isGlobalPathCache, + hasThisCache: hasThisCache, + isPathCache: isPathCache + }; + __exports__.caches = caches; + function isGlobal(path) { + return isGlobalCache.get(path); + } + + __exports__.isGlobal = isGlobal;function isGlobalPath(path) { + return isGlobalPathCache.get(path); + } + + __exports__.isGlobalPath = isGlobalPath;function hasThis(path) { + return hasThisCache.get(path); + } + + __exports__.hasThis = hasThis;function isPath(path) { + return isPathCache.get(path); + } + + __exports__.isPath = isPath; + }); define("ember-metal/platform", ["ember-metal/core","exports"], function(__dependency1__, __exports__) { "use strict"; /*globals Node */ @@ -7532,48 +7914,10 @@ @static */ // TODO remove this var platform = {}; - /** - Identical to `Object.create()`. Implements if not available natively. - - @method create - @for Ember - */ - var create = Object.create; - - // IE8 has Object.create but it couldn't treat property descriptors. - if (create) { - if (create({a: 1}, {a: {value: 2}}).a !== 2) { - create = null; - } - } - - // STUB_OBJECT_CREATE allows us to override other libraries that stub - // Object.create different than we would prefer - if (!create || Ember.ENV.STUB_OBJECT_CREATE) { - var K = function() {}; - - create = function(obj, props) { - K.prototype = obj; - obj = new K(); - if (props) { - K.prototype = obj; - for (var prop in props) { - K.prototype[prop] = props[prop].value; - } - obj = new K(); - } - K.prototype = null; - - return obj; - }; - - create.isSimulated = true; - } - var defineProperty = Object.defineProperty; var canRedefineProperties, canDefinePropertyOnDOM; // Catch IE8 where Object.defineProperty exists but only works on DOM elements if (defineProperty) { @@ -7638,11 +7982,112 @@ } }; } } + // ES5 15.2.3.7 + // http://es5.github.com/#x15.2.3.7 + if (!Object.defineProperties) { + Object.defineProperties = function defineProperties(object, properties) { + for (var property in properties) { + if (properties.hasOwnProperty(property) && property !== "__proto__") { + defineProperty(object, property, properties[property]); + } + } + return object; + }; + } + /** + Identical to `Object.create()`. Implements if not available natively. + + @method create + @for Ember + */ + var create; + // ES5 15.2.3.5 + // http://es5.github.com/#x15.2.3.5 + if (!(Object.create && !Object.create(null).hasOwnProperty)) { + /* jshint scripturl:true, proto:true */ + // Contributed by Brandon Benvie, October, 2012 + var createEmpty; + var supportsProto = !({'__proto__':null} instanceof Object); + // the following produces false positives + // in Opera Mini => not a reliable check + // Object.prototype.__proto__ === null + if (supportsProto || typeof document === 'undefined') { + createEmpty = function () { + return { "__proto__": null }; + }; + } else { + // In old IE __proto__ can't be used to manually set `null`, nor does + // any other method exist to make an object that inherits from nothing, + // aside from Object.prototype itself. Instead, create a new global + // object and *steal* its Object.prototype and strip it bare. This is + // used as the prototype to create nullary objects. + createEmpty = function () { + var iframe = document.createElement('iframe'); + var parent = document.body || document.documentElement; + iframe.style.display = 'none'; + parent.appendChild(iframe); + iframe.src = 'javascript:'; + var empty = iframe.contentWindow.Object.prototype; + parent.removeChild(iframe); + iframe = null; + delete empty.constructor; + delete empty.hasOwnProperty; + delete empty.propertyIsEnumerable; + delete empty.isPrototypeOf; + delete empty.toLocaleString; + delete empty.toString; + delete empty.valueOf; + + function Empty() {} + Empty.prototype = empty; + // short-circuit future calls + createEmpty = function () { + return new Empty(); + }; + return new Empty(); + }; + } + + create = Object.create = function create(prototype, properties) { + + var object; + function Type() {} // An empty constructor. + + if (prototype === null) { + object = createEmpty(); + } else { + if (typeof prototype !== "object" && typeof prototype !== "function") { + // In the native implementation `parent` can be `null` + // OR *any* `instanceof Object` (Object|Function|Array|RegExp|etc) + // Use `typeof` tho, b/c in old IE, DOM elements are not `instanceof Object` + // like they are in modern browsers. Using `Object.create` on DOM elements + // is...err...probably inappropriate, but the native version allows for it. + throw new TypeError("Object prototype may only be an Object or null"); // same msg as Chrome + } + + Type.prototype = prototype; + + object = new Type(); + } + + if (properties !== undefined) { + Object.defineProperties(object, properties); + } + + return object; + }; + create.isSimulated = true; + } else { + create = Object.create; + } + + + /** @class platform @namespace Ember */ /** @@ -7666,11 +8111,11 @@ platform.hasPropertyAccessors = true; if (!platform.defineProperty) { platform.hasPropertyAccessors = false; - platform.defineProperty = function(obj, keyName, desc) { + defineProperty = platform.defineProperty = function(obj, keyName, desc) { if (!desc.get) { obj[keyName] = desc.value; } }; platform.defineProperty.isSimulated = true; } @@ -7689,19 +8134,18 @@ /** @module ember-metal */ var Ember = __dependency1__["default"]; - var META_KEY = __dependency2__.META_KEY; var meta = __dependency2__.meta; var platform = __dependency3__.platform; var overrideChains = __dependency4__.overrideChains; var get = __dependency5__.get; var set = __dependency6__.set; - var metaFor = meta, - objectDefineProperty = platform.defineProperty; + var metaFor = meta; + var objectDefineProperty = platform.defineProperty; var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER; // .......................................................... // DESCRIPTOR @@ -7728,11 +8172,11 @@ Ember.assert("You must use Ember.set() to access this property (of " + this + ")", false); }; var DEFAULT_GETTER_FUNCTION = Ember.DEFAULT_GETTER_FUNCTION = function DEFAULT_GETTER_FUNCTION(name) { return function() { - var meta = this[META_KEY]; + var meta = this['__ember_meta__']; return meta && meta.values[name]; }; }; /** @@ -7784,12 +8228,14 @@ var descs, existingDesc, watching, value; if (!meta) meta = metaFor(obj); descs = meta.descs; existingDesc = meta.descs[keyName]; - watching = meta.watching[keyName] > 0; + var watchEntry = meta.watching[keyName]; + watching = watchEntry !== undefined && watchEntry > 0; + if (existingDesc instanceof Descriptor) { existingDesc.teardown(obj, keyName); } if (desc instanceof Descriptor) { @@ -7861,23 +8307,22 @@ if (platform.hasPropertyAccessors) { defineProperty(object, deprecatedKey, { configurable: true, enumerable: false, - set: function(value) { deprecate(); set(this, newKey, value); }, - get: function() { deprecate(); return get(this, newKey); } + set: function(value) { deprecate(); set(object, newKey, value); }, + get: function() { deprecate(); return get(object, newKey); } }); } } __exports__.deprecateProperty = deprecateProperty; }); define("ember-metal/property_events", ["ember-metal/utils","ember-metal/events","ember-metal/observer_set","exports"], function(__dependency1__, __dependency2__, __dependency3__, __exports__) { "use strict"; - var META_KEY = __dependency1__.META_KEY; var guidFor = __dependency1__.guidFor; var tryFinally = __dependency1__.tryFinally; var sendEvent = __dependency2__.sendEvent; var listenersUnion = __dependency2__.listenersUnion; var listenersDiff = __dependency2__.listenersDiff; @@ -7905,14 +8350,14 @@ @param {Object} obj The object with the property that will change @param {String} keyName The property key (or path) that will change. @return {void} */ function propertyWillChange(obj, keyName) { - var m = obj[META_KEY], - watching = (m && m.watching[keyName] > 0) || keyName === 'length', - proto = m && m.proto, - desc = m && m.descs[keyName]; + 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); } dependentKeysWillChange(obj, keyName, m); @@ -7934,59 +8379,78 @@ @param {Object} obj The object with the property that will change @param {String} keyName The property key (or path) that will change. @return {void} */ function propertyDidChange(obj, keyName) { - var m = obj[META_KEY], - watching = (m && m.watching[keyName] > 0) || keyName === 'length', - proto = m && m.proto, - desc = m && m.descs[keyName]; + 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; } // shouldn't this mean that we're watching this key? if (desc && desc.didChange) { desc.didChange(obj, keyName); } if (!watching && keyName !== 'length') { return; } - dependentKeysDidChange(obj, keyName, m); + if (m && m.deps && m.deps[keyName]) { + dependentKeysDidChange(obj, keyName, m); + } + chainsDidChange(obj, keyName, m, false); notifyObservers(obj, keyName); } var WILL_SEEN, DID_SEEN; - // called whenever a property is about to change to clear the cache of any dependent keys (and notify those properties of changes, etc...) function dependentKeysWillChange(obj, depKey, meta) { if (obj.isDestroying) { return; } - var seen = WILL_SEEN, top = !seen; - if (top) { seen = WILL_SEEN = {}; } - iterDeps(propertyWillChange, obj, depKey, seen, meta); - if (top) { WILL_SEEN = null; } + var deps; + if (meta && meta.deps && (deps = meta.deps[depKey])) { + var seen = WILL_SEEN; + var top = !seen; + if (top) { seen = WILL_SEEN = {}; } + iterDeps(propertyWillChange, obj, deps, depKey, seen, meta); + if (top) { WILL_SEEN = null; } + } } // called whenever a property has just changed to update dependent keys function dependentKeysDidChange(obj, depKey, meta) { if (obj.isDestroying) { return; } - var seen = DID_SEEN, top = !seen; - if (top) { seen = DID_SEEN = {}; } - iterDeps(propertyDidChange, obj, depKey, seen, meta); - if (top) { DID_SEEN = null; } + var deps; + if (meta && meta.deps && (deps = meta.deps[depKey])) { + var seen = DID_SEEN; + var top = !seen; + if (top) { seen = DID_SEEN = {}; } + iterDeps(propertyDidChange, obj, deps, depKey, seen, meta); + if (top) { DID_SEEN = null; } + } } - function iterDeps(method, obj, depKey, seen, meta) { + function keysOf(obj) { + var keys = []; + 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); - if (!seen[guid]) seen[guid] = {}; - if (seen[guid][depKey]) return; - seen[guid][depKey] = true; + var current = seen[guid]; + if (!current) current = seen[guid] = {}; + if (current[depKey]) return; + current[depKey] = true; - var deps = meta.deps; - deps = deps && deps[depKey]; if (deps) { - for(var key in deps) { - var desc = meta.descs[key]; + 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; method(obj, key); } } } @@ -7995,13 +8459,13 @@ if (!(m.hasOwnProperty('chainWatchers') && m.chainWatchers[keyName])) { return; } - var nodes = m.chainWatchers[keyName], - events = [], - i, l; + var nodes = m.chainWatchers[keyName]; + var events = []; + var i, l; for(i = 0, l = nodes.length; i < l; i++) { nodes[i].willChange(events); } @@ -8014,13 +8478,13 @@ if (!(m && m.hasOwnProperty('chainWatchers') && m.chainWatchers[keyName])) { return; } - var nodes = m.chainWatchers[keyName], - events = suppressEvents ? null : [], - i, l; + var nodes = m.chainWatchers[keyName]; + var events = suppressEvents ? null : []; + var i, l; for(i = 0, l = nodes.length; i < l; i++) { nodes[i].didChange(events); } @@ -8079,11 +8543,12 @@ } function notifyBeforeObservers(obj, keyName) { if (obj.isDestroying) { return; } - var eventName = keyName + ':before', listeners, diff; + var eventName = keyName + ':before'; + var listeners, diff; if (deferred) { listeners = beforeObserverSet.add(obj, keyName, eventName); diff = listenersDiff(obj, eventName, listeners); sendEvent(obj, eventName, [obj, keyName], diff); } else { @@ -8092,11 +8557,12 @@ } function notifyObservers(obj, keyName) { if (obj.isDestroying) { return; } - var eventName = keyName + ':change', listeners; + var eventName = keyName + ':change'; + var listeners; if (deferred) { listeners = observerSet.add(obj, keyName, eventName); listenersUnion(obj, eventName, listeners); } else { sendEvent(obj, eventName, [obj, keyName]); @@ -8109,27 +8575,24 @@ __exports__.beginPropertyChanges = beginPropertyChanges; __exports__.endPropertyChanges = endPropertyChanges; __exports__.changeProperties = changeProperties; }); define("ember-metal/property_get", - ["ember-metal/core","ember-metal/utils","ember-metal/error","exports"], + ["ember-metal/core","ember-metal/error","ember-metal/path_cache","exports"], function(__dependency1__, __dependency2__, __dependency3__, __exports__) { "use strict"; /** @module ember-metal */ var Ember = __dependency1__["default"]; - var META_KEY = __dependency2__.META_KEY; - var EmberError = __dependency3__["default"]; + var EmberError = __dependency2__["default"]; + var isGlobalPath = __dependency3__.isGlobalPath; + var isPath = __dependency3__.isPath; + var pathHasThis = __dependency3__.hasThis; - var get; - var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER; - - var IS_GLOBAL_PATH = /^([A-Z$]|([0-9][A-Z$])).*[\.]/; - var HAS_THIS = 'this.'; var FIRST_KEY = /^([^\.]+)/; // .......................................................... // GET AND SET // @@ -8165,23 +8628,32 @@ // Helpers that operate with 'this' within an #each if (keyName === '') { return obj; } - if (!keyName && 'string'===typeof obj) { + 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) { return _getPath(obj, keyName); } + if (obj === null) { + var value = _getPath(obj, keyName); + Ember.deprecate( + "Ember.get fetched '"+keyName+"' from the global context. This behavior will change in the future (issue #3852)", + !value || (obj && obj !== Ember.lookup) || isPath(keyName) || isGlobalPath(keyName+".") // Add a . to ensure simple paths are matched. + ); + return value; + } - var meta = obj[META_KEY], desc = meta && meta.descs[keyName], ret; + var meta = obj['__ember_meta__']; + var desc = meta && meta.descs[keyName]; + var ret; - if (desc === undefined && keyName.indexOf('.') !== -1) { + if (desc === undefined && isPath(keyName)) { return _getPath(obj, keyName); } if (desc) { return desc.get(obj, keyName); @@ -8220,17 +8692,22 @@ @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. */ function normalizeTuple(target, path) { - var hasThis = path.indexOf(HAS_THIS) === 0, - isGlobal = !hasThis && IS_GLOBAL_PATH.test(path), - key; + var hasThis = pathHasThis(path); + var isGlobal = !hasThis && isGlobalPath(path); + var key; if (!target || isGlobal) target = Ember.lookup; if (hasThis) path = path.slice(5); + Ember.deprecate( + "normalizeTuple will return '"+path+"' as a non-global. This behavior will change in the future (issue #3852)", + target === Ember.lookup || !target || hasThis || isGlobal || !isGlobalPath(path+'.') + ); + if (target === Ember.lookup) { key = path.match(FIRST_KEY)[0]; target = get(target, key); path = path.slice(key.length+1); } @@ -8245,14 +8722,16 @@ var hasThis, parts, tuple, idx, len; // If there is no root and path is a key name, return that // property from the global object. // E.g. get('Ember') -> Ember - if (root === null && path.indexOf('.') === -1) { return get(Ember.lookup, path); } + if (root === null && !isPath(path)) { + return get(Ember.lookup, path); + } // detect complicated paths and normalize them - hasThis = path.indexOf(HAS_THIS) === 0; + hasThis = pathHasThis(path); if (!root || hasThis) { tuple = normalizeTuple(root, path); root = tuple[0]; path = tuple[1]; @@ -8279,21 +8758,22 @@ __exports__.get = get; __exports__.normalizeTuple = normalizeTuple; __exports__._getPath = _getPath; }); define("ember-metal/property_set", - ["ember-metal/core","ember-metal/property_get","ember-metal/utils","ember-metal/property_events","ember-metal/properties","ember-metal/error","exports"], + ["ember-metal/core","ember-metal/property_get","ember-metal/property_events","ember-metal/properties","ember-metal/error","ember-metal/path_cache","exports"], function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; var getPath = __dependency2__._getPath; - var META_KEY = __dependency3__.META_KEY; - var propertyWillChange = __dependency4__.propertyWillChange; - var propertyDidChange = __dependency4__.propertyDidChange; - var defineProperty = __dependency5__.defineProperty; - var EmberError = __dependency6__["default"]; + var propertyWillChange = __dependency3__.propertyWillChange; + var propertyDidChange = __dependency3__.propertyDidChange; + var defineProperty = __dependency4__.defineProperty; + var EmberError = __dependency5__["default"]; + var isPath = __dependency6__.isPath; + var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER; var IS_GLOBAL = /^([A-Z$]|([0-9][A-Z$]))/; /** Sets the value of a property on an object, respecting computed properties @@ -8320,14 +8800,15 @@ if (!obj) { return setPath(obj, keyName, value, tolerant); } - var meta = obj[META_KEY], desc = meta && meta.descs[keyName], - isUnknown, currentValue; + var meta = obj['__ember_meta__']; + var desc = meta && meta.descs[keyName]; + var isUnknown, currentValue; - if (desc === undefined && keyName.indexOf('.') !== -1) { + if (desc === undefined && isPath(keyName)) { return setPath(obj, keyName, value, tolerant); } Ember.assert("You need to provide an object and key to `set`.", !!obj && keyName !== undefined); Ember.assert('calling set on destroyed object', !obj.isDestroyed); @@ -8427,30 +8908,32 @@ } __exports__.trySet = trySet;__exports__.set = set; }); define("ember-metal/run_loop", - ["ember-metal/core","ember-metal/utils","ember-metal/array","ember-metal/property_events","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) { + ["ember-metal/core","ember-metal/utils","ember-metal/array","ember-metal/property_events","backburner","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; var apply = __dependency2__.apply; + var GUID_KEY = __dependency2__.GUID_KEY; var indexOf = __dependency3__.indexOf; var beginPropertyChanges = __dependency4__.beginPropertyChanges; var endPropertyChanges = __dependency4__.endPropertyChanges; + var Backburner = __dependency5__["default"]; function onBegin(current) { run.currentRunLoop = current; } function onEnd(current, next) { run.currentRunLoop = next; } // ES6TODO: should Backburner become es6? - var Backburner = requireModule('backburner').Backburner; var backburner = new Backburner(['sync', 'actions', 'destroy'], { + GUID_KEY: GUID_KEY, sync: { before: beginPropertyChanges, after: endPropertyChanges }, defaultQueue: 'actions', @@ -9092,19 +9575,20 @@ }); return self; } }); define("ember-metal/utils", - ["ember-metal/core","ember-metal/platform","ember-metal/array","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __exports__) { + ["ember-metal/core","ember-metal/platform","ember-metal/array","ember-metal/keys","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; var platform = __dependency2__.platform; var create = __dependency2__.create; var forEach = __dependency3__.forEach; + var keys = __dependency4__["default"]; /** @module ember-metal */ /** @@ -9145,10 +9629,55 @@ var numberCache = []; var stringCache = {}; var MANDATORY_SETTER = Ember.ENV.MANDATORY_SETTER; /** + Strongly hint runtimes to intern the provided string. + + When do I need to use this function? + + For the most part, never. Pre-mature optimization is bad, and often the + runtime does exactly what you need it to, and more often the trade-off isn't + worth it. + + Why? + + Runtimes store strings in at least 2 different representations: + Ropes and Symbols (interned strings). The Rope provides a memory efficient + data-structure for strings created from concatenation or some other string + manipulation like splitting. + + Unfortunately checking equality of different ropes can be quite costly as + runtimes must resort to clever string comparison algorithims. These + algorithims typically cost in proportion to the length of the string. + Luckily, this is where the Symbols (interned strings) shine. As Symbols are + unique by their string content, equality checks can be done by pointer + comparision. + + How do I know if my string is a rope or symbol? + + Typically (warning general sweeping statement, but truthy in runtimes at + present) static strings created as part of the JS source are interned. + Strings often used for comparisions can be interned at runtime if some + criteria are met. One of these criteria can be the size of the entire rope. + For example, in chrome 38 a rope longer then 12 characters will not + intern, nor will segments of that rope. + + Some numbers: http://jsperf.com/eval-vs-keys/8 + + Known Trickâ„¢ + + @private + @return {String} interned version of the provided string + */ + function intern(string) { + var obj = Object.create(null); + obj[string] = true; + return keys(obj)[0]; + } + + /** A unique key used to assign guids and other private metadata to objects. If you inspect an object in your browser debugger you will often see these. They can be safely ignored. On browsers that support it, these properties are added with enumeration @@ -9158,11 +9687,11 @@ @property GUID_KEY @for Ember @type String @final */ - var GUID_KEY = '__ember' + (+ new Date()); + var GUID_KEY = intern('__ember' + (+ new Date())); var GUID_DESC = { writable: false, configurable: false, enumerable: false, @@ -9240,11 +9769,11 @@ default: if (obj[GUID_KEY]) return obj[GUID_KEY]; if (obj === Object) return '(Object)'; if (obj === Array) return '(Array)'; - ret = 'ember' + uuid(); + ret = GUID_PREFIX + uuid(); if (obj[GUID_KEY] === null) { obj[GUID_KEY] = ret; } else { GUID_DESC.value = ret; @@ -9263,21 +9792,10 @@ configurable: false, enumerable: false, value: null }; - /** - The key used to store meta information on object for property observing. - - @property META_KEY - @for Ember - @private - @final - @type String - */ - var META_KEY = '__ember_meta__'; - var isDefinePropertySimulated = platform.defineProperty.isSimulated; function Meta(obj) { this.descs = {}; this.watching = {}; @@ -9337,38 +9855,38 @@ the meta hash, allowing the method to avoid making an unnecessary copy. @return {Object} the meta hash for an object */ function meta(obj, writable) { - var ret = obj[META_KEY]; + var ret = obj['__ember_meta__']; if (writable===false) return ret || EMPTY_META; if (!ret) { - if (!isDefinePropertySimulated) o_defineProperty(obj, META_KEY, META_DESC); + if (!isDefinePropertySimulated) o_defineProperty(obj, '__ember_meta__', META_DESC); ret = new Meta(obj); if (MANDATORY_SETTER) { ret.values = {}; } - obj[META_KEY] = ret; + obj['__ember_meta__'] = ret; // make sure we don't accidentally try to create constructor like desc ret.descs.constructor = null; } else if (ret.source !== obj) { - if (!isDefinePropertySimulated) o_defineProperty(obj, META_KEY, META_DESC); + if (!isDefinePropertySimulated) o_defineProperty(obj, '__ember_meta__', META_DESC); ret = o_create(ret); ret.descs = o_create(ret.descs); ret.watching = o_create(ret.watching); ret.cache = {}; ret.cacheMeta = {}; ret.source = obj; if (MANDATORY_SETTER) { ret.values = o_create(ret.values); } - obj[META_KEY] = ret; + obj['__ember_meta__'] = ret; } return ret; } function getMeta(obj, property) { @@ -9415,11 +9933,12 @@ (or meta property) if one does not already exist or if it's shared with its constructor */ function metaPath(obj, path, writable) { Ember.deprecate("Ember.metaPath is deprecated and will be removed from future releases."); - var _meta = meta(obj, writable), keyName, value; + var _meta = meta(obj, writable); + var keyName, value; for (var i=0, l=path.length; i<l; i++) { keyName = path[i]; value = _meta[keyName]; @@ -9450,13 +9969,18 @@ @param {Function} superFunc The super function. @return {Function} wrapped function. */ function wrap(func, superFunc) { function superWrapper() { - var ret, sup = this && this.__nextSuper; + var ret; + var sup = this && this.__nextSuper; + var args = new Array(arguments.length); + for (var i = 0, l = args.length; i < l; i++) { + args[i] = arguments[i]; + } if(this) { this.__nextSuper = superFunc; } - ret = apply(this, func, arguments); + ret = apply(this, func, args); if(this) { this.__nextSuper = sup; } return ret; } superWrapper.wrappedFunction = func; @@ -9855,11 +10379,12 @@ } if (type !== 'object') { return obj + ''; } - var v, ret = []; + var v; + var ret = []; for(var key in obj) { if (obj.hasOwnProperty(key)) { v = obj[key]; if (v === 'toString') { continue; } // ignore useless items if (typeOf(v) === 'function') { v = "function() { ... }"; } @@ -9897,14 +10422,12 @@ default: return t[m].apply(t, a); } } __exports__.applyStr = applyStr;__exports__.GUID_KEY = GUID_KEY; - __exports__.GUID_PREFIX = GUID_PREFIX; __exports__.META_DESC = META_DESC; __exports__.EMPTY_META = EMPTY_META; - __exports__.META_KEY = META_KEY; __exports__.meta = meta; __exports__.typeOf = typeOf; __exports__.tryCatchFinally = tryCatchFinally; __exports__.isArray = isArray; __exports__.canInvoke = canInvoke; @@ -10003,11 +10526,12 @@ // get the chains for the current object. If the current object has // chains inherited from the proto they will be cloned and reconfigured for // the current object. function chainsFor(obj, meta) { - var m = meta || metaFor(obj), ret = m.chains; + var m = meta || metaFor(obj); + var ret = m.chains; if (!ret) { ret = m.chains = new ChainNode(null, null, obj); } else if (ret.value() !== obj) { ret = m.chains = ret.copy(obj); } @@ -10016,22 +10540,24 @@ function watchPath(obj, keyPath, meta) { // can't watch length on Array - it is special... if (keyPath === 'length' && typeOf(obj) === 'array') { return; } - var m = meta || metaFor(obj), watching = m.watching; + var m = meta || metaFor(obj); + var watching = m.watching; if (!watching[keyPath]) { // activate watching first time watching[keyPath] = 1; chainsFor(obj, m).add(keyPath); } else { watching[keyPath] = (watching[keyPath] || 0) + 1; } } __exports__.watchPath = watchPath;function unwatchPath(obj, keyPath, meta) { - var m = meta || metaFor(obj), watching = m.watching; + var m = meta || metaFor(obj); + var watching = m.watching; if (watching[keyPath] === 1) { watching[keyPath] = 0; chainsFor(obj, m).remove(keyPath); } else if (watching[keyPath] > 1) { @@ -10040,19 +10566,18 @@ } __exports__.unwatchPath = unwatchPath; }); define("ember-metal/watching", - ["ember-metal/utils","ember-metal/chains","ember-metal/watch_key","ember-metal/watch_path","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) { + ["ember-metal/utils","ember-metal/chains","ember-metal/watch_key","ember-metal/watch_path","ember-metal/path_cache","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) { "use strict"; /** @module ember-metal */ var meta = __dependency1__.meta; - var META_KEY = __dependency1__.META_KEY; var GUID_KEY = __dependency1__.GUID_KEY; var typeOf = __dependency1__.typeOf; var generateGuid = __dependency1__.generateGuid; var removeChainWatcher = __dependency2__.removeChainWatcher; var flushPendingChains = __dependency2__.flushPendingChains; @@ -10060,16 +10585,12 @@ var unwatchKey = __dependency3__.unwatchKey; var watchPath = __dependency4__.watchPath; var unwatchPath = __dependency4__.unwatchPath; var metaFor = meta; // utils.js + var isPath = __dependency5__.isPath; - // returns true if the passed path is just a keyName - function isKeyName(path) { - return path.indexOf('.') === -1; - } - /** Starts watching a property on an object. Whenever the property changes, invokes `Ember.propertyWillChange` and `Ember.propertyDidChange`. This is the primitive used by observers and dependent keys; usually you will never call this method directly but instead use higher level methods like @@ -10083,31 +10604,31 @@ */ function watch(obj, _keyPath, m) { // can't watch length on Array - it is special... if (_keyPath === 'length' && typeOf(obj) === 'array') { return; } - if (isKeyName(_keyPath)) { + if (!isPath(_keyPath)) { watchKey(obj, _keyPath, m); } else { watchPath(obj, _keyPath, m); } } __exports__.watch = watch; function isWatching(obj, key) { - var meta = obj[META_KEY]; + var meta = obj['__ember_meta__']; return (meta && meta.watching[key]) > 0; } __exports__.isWatching = isWatching;watch.flushPending = flushPendingChains; function unwatch(obj, _keyPath, m) { // can't watch length on Array - it is special... if (_keyPath === 'length' && typeOf(obj) === 'array') { return; } - if (isKeyName(_keyPath)) { + if (!isPath(_keyPath)) { unwatchKey(obj, _keyPath, m); } else { unwatchPath(obj, _keyPath, m); } } @@ -10121,11 +10642,11 @@ @method rewatch @for Ember @param obj */ function rewatch(obj) { - var m = obj[META_KEY], chains = m && m.chains; + var m = obj['__ember_meta__'], chains = m && m.chains; // make sure the object has its own guid. if (GUID_KEY in obj && !obj.hasOwnProperty(GUID_KEY)) { generateGuid(obj); } @@ -10146,13 +10667,13 @@ @for Ember @param {Object} obj the object to destroy @return {void} */ function destroy(obj) { - var meta = obj[META_KEY], node, nodes, key, nodeObject; + var meta = obj['__ember_meta__'], node, nodes, key, nodeObject; if (meta) { - obj[META_KEY] = null; + obj['__ember_meta__'] = null; // remove chainWatchers to remove circular references that would prevent GC node = meta.chains; if (node) { NODE_STACK.push(node); // process tree @@ -10180,11 +10701,11 @@ } __exports__.destroy = destroy; }); define("ember-runtime", - ["ember-metal","ember-runtime/core","ember-runtime/keys","ember-runtime/compare","ember-runtime/copy","ember-runtime/system/namespace","ember-runtime/system/object","ember-runtime/system/tracked_array","ember-runtime/system/subarray","ember-runtime/system/container","ember-runtime/system/application","ember-runtime/system/array_proxy","ember-runtime/system/object_proxy","ember-runtime/system/core_object","ember-runtime/system/each_proxy","ember-runtime/system/native_array","ember-runtime/system/set","ember-runtime/system/string","ember-runtime/system/deferred","ember-runtime/system/lazy_load","ember-runtime/mixins/array","ember-runtime/mixins/comparable","ember-runtime/mixins/copyable","ember-runtime/mixins/enumerable","ember-runtime/mixins/freezable","ember-runtime/mixins/observable","ember-runtime/mixins/action_handler","ember-runtime/mixins/deferred","ember-runtime/mixins/mutable_enumerable","ember-runtime/mixins/mutable_array","ember-runtime/mixins/target_action_support","ember-runtime/mixins/evented","ember-runtime/mixins/promise_proxy","ember-runtime/mixins/sortable","ember-runtime/computed/array_computed","ember-runtime/computed/reduce_computed","ember-runtime/computed/reduce_computed_macros","ember-runtime/controllers/array_controller","ember-runtime/controllers/object_controller","ember-runtime/controllers/controller","ember-runtime/mixins/controller","ember-runtime/ext/rsvp","ember-runtime/ext/string","ember-runtime/ext/function","exports"], + ["ember-metal","ember-runtime/core","ember-runtime/compare","ember-runtime/copy","ember-runtime/system/namespace","ember-runtime/system/object","ember-runtime/system/tracked_array","ember-runtime/system/subarray","ember-runtime/system/container","ember-runtime/system/application","ember-runtime/system/array_proxy","ember-runtime/system/object_proxy","ember-runtime/system/core_object","ember-runtime/system/each_proxy","ember-runtime/system/native_array","ember-runtime/system/set","ember-runtime/system/string","ember-runtime/system/deferred","ember-runtime/system/lazy_load","ember-runtime/mixins/array","ember-runtime/mixins/comparable","ember-runtime/mixins/copyable","ember-runtime/mixins/enumerable","ember-runtime/mixins/freezable","ember-runtime/mixins/-proxy","ember-runtime/mixins/observable","ember-runtime/mixins/action_handler","ember-runtime/mixins/deferred","ember-runtime/mixins/mutable_enumerable","ember-runtime/mixins/mutable_array","ember-runtime/mixins/target_action_support","ember-runtime/mixins/evented","ember-runtime/mixins/promise_proxy","ember-runtime/mixins/sortable","ember-runtime/computed/array_computed","ember-runtime/computed/reduce_computed","ember-runtime/computed/reduce_computed_macros","ember-runtime/controllers/array_controller","ember-runtime/controllers/object_controller","ember-runtime/controllers/controller","ember-runtime/mixins/controller","ember-runtime/ext/rsvp","ember-runtime/ext/string","ember-runtime/ext/function","exports"], function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __dependency19__, __dependency20__, __dependency21__, __dependency22__, __dependency23__, __dependency24__, __dependency25__, __dependency26__, __dependency27__, __dependency28__, __dependency29__, __dependency30__, __dependency31__, __dependency32__, __dependency33__, __dependency34__, __dependency35__, __dependency36__, __dependency37__, __dependency38__, __dependency39__, __dependency40__, __dependency41__, __dependency42__, __dependency43__, __dependency44__, __exports__) { "use strict"; /** Ember Runtime @@ -10194,39 +10715,39 @@ */ // BEGIN IMPORTS var Ember = __dependency1__["default"]; var isEqual = __dependency2__.isEqual; - var keys = __dependency3__["default"]; - var compare = __dependency4__["default"]; - var copy = __dependency5__["default"]; + var compare = __dependency3__["default"]; + var copy = __dependency4__["default"]; - var Namespace = __dependency6__["default"]; - var EmberObject = __dependency7__["default"]; - var TrackedArray = __dependency8__["default"]; - var SubArray = __dependency9__["default"]; - var Container = __dependency10__["default"]; - var Application = __dependency11__["default"]; - var ArrayProxy = __dependency12__["default"]; - var ObjectProxy = __dependency13__["default"]; - var CoreObject = __dependency14__["default"]; - var EachArray = __dependency15__.EachArray; - var EachProxy = __dependency15__.EachProxy; + var Namespace = __dependency5__["default"]; + var EmberObject = __dependency6__["default"]; + var TrackedArray = __dependency7__["default"]; + var SubArray = __dependency8__["default"]; + var Container = __dependency9__["default"]; + var Application = __dependency10__["default"]; + var ArrayProxy = __dependency11__["default"]; + var ObjectProxy = __dependency12__["default"]; + var CoreObject = __dependency13__["default"]; + var EachArray = __dependency14__.EachArray; + var EachProxy = __dependency14__.EachProxy; - var NativeArray = __dependency16__["default"]; - var Set = __dependency17__["default"]; - var EmberStringUtils = __dependency18__["default"]; - var Deferred = __dependency19__["default"]; - var onLoad = __dependency20__.onLoad; - var runLoadHooks = __dependency20__.runLoadHooks; + var NativeArray = __dependency15__["default"]; + var Set = __dependency16__["default"]; + var EmberStringUtils = __dependency17__["default"]; + var Deferred = __dependency18__["default"]; + var onLoad = __dependency19__.onLoad; + var runLoadHooks = __dependency19__.runLoadHooks; - var EmberArray = __dependency21__["default"]; - var Comparable = __dependency22__["default"]; - var Copyable = __dependency23__["default"]; - var Enumerable = __dependency24__["default"]; - var Freezable = __dependency25__.Freezable; - var FROZEN_ERROR = __dependency25__.FROZEN_ERROR; + var EmberArray = __dependency20__["default"]; + var Comparable = __dependency21__["default"]; + var Copyable = __dependency22__["default"]; + var Enumerable = __dependency23__["default"]; + var Freezable = __dependency24__.Freezable; + var FROZEN_ERROR = __dependency24__.FROZEN_ERROR; + var _ProxyMixin = __dependency25__["default"]; var Observable = __dependency26__["default"]; var ActionHandler = __dependency27__["default"]; var DeferredMixin = __dependency28__["default"]; var MutableEnumerable = __dependency29__["default"]; @@ -10269,11 +10790,10 @@ // BEGIN EXPORTS Ember.compare = compare; Ember.copy = copy; Ember.isEqual = isEqual; - Ember.keys = keys; Ember.Array = EmberArray; Ember.Comparable = Comparable; Ember.Copyable = Copyable; @@ -10342,39 +10862,46 @@ Ember.ArrayController = ArrayController; Ember.ObjectController = ObjectController; Ember.Controller = Controller; Ember.ControllerMixin = ControllerMixin; + Ember._ProxyMixin = _ProxyMixin; + Ember.RSVP = RSVP; // END EXPORTS __exports__["default"] = Ember; }); define("ember-runtime/compare", - ["ember-metal/core","ember-metal/utils","ember-runtime/mixins/comparable","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __exports__) { + ["ember-metal/utils","ember-runtime/mixins/comparable","exports"], + function(__dependency1__, __dependency2__, __exports__) { "use strict"; - var Ember = __dependency1__["default"]; - // for Ember.ORDER_DEFINITION - var typeOf = __dependency2__.typeOf; - var Comparable = __dependency3__["default"]; + var typeOf = __dependency1__.typeOf; + var Comparable = __dependency2__["default"]; - // Used by Ember.compare - Ember.ORDER_DEFINITION = Ember.ENV.ORDER_DEFINITION || [ - 'undefined', - 'null', - 'boolean', - 'number', - 'string', - 'array', - 'object', - 'instance', - 'function', - 'class', - 'date' - ]; + var TYPE_ORDER = { + 'undefined': 0, + 'null': 1, + 'boolean': 2, + 'number': 3, + 'string': 4, + 'array': 5, + 'object': 6, + 'instance': 7, + 'function': 8, + 'class': 9, + 'date': 10 + }; + // + // the spaceship operator + // + function spaceship(a, b) { + var diff = a - b; + return (diff > 0) - (diff < 0); + } + /** This will compare two javascript values of possibly different types. It will tell you which one is greater than the other by returning: - -1 if the first is smaller than the second, @@ -10395,91 +10922,65 @@ @param {Object} v First value to compare @param {Object} w Second value to compare @return {Number} -1 if v < w, 0 if v = w and 1 if v > w. */ __exports__["default"] = function compare(v, w) { - if (v === w) { return 0; } + if (v === w) { + return 0; + } var type1 = typeOf(v); var type2 = typeOf(w); if (Comparable) { - if (type1==='instance' && Comparable.detect(v.constructor)) { + if (type1 ==='instance' && Comparable.detect(v.constructor)) { return v.constructor.compare(v, w); } if (type2 === 'instance' && Comparable.detect(w.constructor)) { - return 1-w.constructor.compare(w, v); + return 1 - w.constructor.compare(w, v); } } - // If we haven't yet generated a reverse-mapping of Ember.ORDER_DEFINITION, - // do so now. - var mapping = Ember.ORDER_DEFINITION_MAPPING; - if (!mapping) { - var order = Ember.ORDER_DEFINITION; - mapping = Ember.ORDER_DEFINITION_MAPPING = {}; - var idx, len; - for (idx = 0, len = order.length; idx < len; ++idx) { - mapping[order[idx]] = idx; - } - - // We no longer need Ember.ORDER_DEFINITION. - delete Ember.ORDER_DEFINITION; + var res = spaceship(TYPE_ORDER[type1], TYPE_ORDER[type2]); + if (res !== 0) { + return res; } - var type1Index = mapping[type1]; - var type2Index = mapping[type2]; - - if (type1Index < type2Index) { return -1; } - if (type1Index > type2Index) { return 1; } - // types are equal - so we have to check values now switch (type1) { case 'boolean': case 'number': - if (v < w) { return -1; } - if (v > w) { return 1; } - return 0; + return spaceship(v,w); case 'string': - var comp = v.localeCompare(w); - if (comp < 0) { return -1; } - if (comp > 0) { return 1; } - return 0; + return spaceship(v.localeCompare(w), 0); case 'array': var vLen = v.length; var wLen = w.length; - var l = Math.min(vLen, wLen); - var r = 0; - var i = 0; - while (r === 0 && i < l) { - r = compare(v[i],w[i]); - i++; + var len = Math.min(vLen, wLen); + + for (var i = 0; i < len; i++) { + var r = compare(v[i], w[i]); + if (r !== 0) { + return r; + } } - if (r !== 0) { return r; } // all elements are equal now // shorter array should be ordered first - if (vLen < wLen) { return -1; } - if (vLen > wLen) { return 1; } - // arrays are equal now - return 0; + return spaceship(vLen, wLen); case 'instance': if (Comparable && Comparable.detect(v)) { return v.compare(v, w); } return 0; case 'date': - var vNum = v.getTime(); - var wNum = w.getTime(); - if (vNum < wNum) { return -1; } - if (vNum > wNum) { return 1; } - return 0; + return spaceship(v.getTime(), w.getTime()); default: return 0; } } @@ -10522,13 +11023,15 @@ return this; } ArrayComputedProperty.prototype = o_create(ReduceComputedProperty.prototype); + ArrayComputedProperty.prototype.initialValue = function () { return Ember.A(); }; + ArrayComputedProperty.prototype.resetValue = function (array) { array.clear(); return array; }; @@ -10657,12 +11160,12 @@ if (arguments.length > 1) { args = a_slice.call(arguments, 0, -1); options = a_slice.call(arguments, -1)[0]; } - if (typeof options !== "object") { - throw new EmberError("Array Computed Property declared without an options hash"); + if (typeof options !== 'object') { + throw new EmberError('Array Computed Property declared without an options hash'); } var cp = new ArrayComputedProperty(options); if (args) { @@ -10674,12 +11177,12 @@ __exports__.arrayComputed = arrayComputed; __exports__.ArrayComputedProperty = ArrayComputedProperty; }); define("ember-runtime/computed/reduce_computed", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/error","ember-metal/property_events","ember-metal/expand_properties","ember-metal/observer","ember-metal/computed","ember-metal/platform","ember-metal/enumerable_utils","ember-runtime/system/tracked_array","ember-runtime/mixins/array","ember-metal/run_loop","ember-runtime/system/set","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __exports__) { + ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/error","ember-metal/property_events","ember-metal/expand_properties","ember-metal/observer","ember-metal/computed","ember-metal/platform","ember-metal/enumerable_utils","ember-runtime/system/tracked_array","ember-runtime/mixins/array","ember-metal/run_loop","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; // Ember.assert var e_get = __dependency2__.get; var set = __dependency3__.set; @@ -10699,11 +11202,10 @@ var o_create = __dependency10__.create; var forEach = __dependency11__.forEach; var TrackedArray = __dependency12__["default"]; var EmberArray = __dependency13__["default"]; var run = __dependency14__["default"]; - var Set = __dependency15__["default"]; var isArray = __dependency4__.isArray; var cacheSet = cacheFor.set; var cacheGet = cacheFor.get; var cacheRemove = cacheFor.remove; @@ -10762,26 +11264,26 @@ // some shared state. this.changedItemCount = 0; } function ItemPropertyObserverContext (dependentArray, index, trackedArray) { - Ember.assert("Internal error: trackedArray is null or undefined", trackedArray); + Ember.assert('Internal error: trackedArray is null or undefined', trackedArray); this.dependentArray = dependentArray; this.index = index; this.item = dependentArray.objectAt(index); this.trackedArray = trackedArray; this.beforeObserver = null; this.observer = null; - this.destroyed = false; } DependentArraysObserver.prototype = { setValue: function (newValue) { this.instanceMeta.setValue(newValue, true); }, + getValue: function () { return this.instanceMeta.getValue(); }, setupObservers: function (dependentArray, dependentKey) { @@ -10816,13 +11318,13 @@ callback.call(binding); this.suspended = oldSuspended; }, setupPropertyObservers: function (dependentKey, itemPropertyKeys) { - var dependentArray = get(this.instanceMeta.context, dependentKey), - length = get(dependentArray, 'length'), - observerContexts = new Array(length); + var dependentArray = get(this.instanceMeta.context, dependentKey); + var length = get(dependentArray, 'length'); + var observerContexts = new Array(length); this.resetTransformations(dependentKey, observerContexts); forEach(dependentArray, function (item, index) { var observerContext = this.createPropertyObserverContext(dependentArray, index, this.trackedArraysByGuid[dependentKey]); @@ -10834,15 +11336,13 @@ }, this); }, this); }, teardownPropertyObservers: function (dependentKey, itemPropertyKeys) { - var dependentArrayObserver = this, - trackedArray = this.trackedArraysByGuid[dependentKey], - beforeObserver, - observer, - item; + var dependentArrayObserver = this; + var trackedArray = this.trackedArraysByGuid[dependentKey]; + var beforeObserver, observer, item; if (!trackedArray) { return; } trackedArray.apply(function (observerContexts, offset, operation) { if (operation === TrackedArray.DELETE) { return; } @@ -10873,10 +11373,11 @@ var dependentArrayObserver = this; observerContext.beforeObserver = function (obj, keyName) { return dependentArrayObserver.itemPropertyWillChange(obj, keyName, observerContext.dependentArray, observerContext); }; + observerContext.observer = function (obj, keyName) { return dependentArrayObserver.itemPropertyDidChange(obj, keyName, observerContext.dependentArray, observerContext); }; }, @@ -10884,10 +11385,11 @@ this.trackedArraysByGuid[dependentKey] = new TrackedArray(observerContexts); }, trackAdd: function (dependentKey, index, newItems) { var trackedArray = this.trackedArraysByGuid[dependentKey]; + if (trackedArray) { trackedArray.addItems(index, newItems); } }, @@ -10949,11 +11451,11 @@ item = dependentArray.objectAt(itemIndex); forEach(itemPropertyKeys, removeObservers, this); changeMeta = new ChangeMeta(dependentArray, item, itemIndex, this.instanceMeta.propertyName, this.cp, normalizedRemoveCount); - this.setValue( removedItem.call( + this.setValue(removedItem.call( this.instanceMeta.context, this.getValue(), item, changeMeta, this.instanceMeta.sugarMeta)); } }, dependentArrayDidChange: function (dependentArray, index, removedCount, addedCount) { @@ -10964,25 +11466,27 @@ var dependentKey = this.dependentKeysByGuid[guid]; var observerContexts = new Array(addedCount); var itemPropertyKeys = this.cp._itemPropertyKeys[dependentKey]; var length = get(dependentArray, 'length'); var normalizedIndex = normalizeIndex(index, length, addedCount); + var endIndex = normalizedIndex + addedCount; var changeMeta, observerContext; - forEach(dependentArray.slice(normalizedIndex, normalizedIndex + addedCount), function (item, sliceIndex) { + forEach(dependentArray.slice(normalizedIndex, endIndex), function (item, sliceIndex) { if (itemPropertyKeys) { - observerContext = - observerContexts[sliceIndex] = - this.createPropertyObserverContext(dependentArray, normalizedIndex + sliceIndex, this.trackedArraysByGuid[dependentKey]); + observerContext = this.createPropertyObserverContext(dependentArray, normalizedIndex + sliceIndex, + this.trackedArraysByGuid[dependentKey]); + observerContexts[sliceIndex] = observerContext; + forEach(itemPropertyKeys, function (propertyKey) { addBeforeObserver(item, propertyKey, this, observerContext.beforeObserver); addObserver(item, propertyKey, this, observerContext.observer); }, this); } changeMeta = new ChangeMeta(dependentArray, item, normalizedIndex + sliceIndex, this.instanceMeta.propertyName, this.cp, addedCount); - this.setValue( addedItem.call( + this.setValue(addedItem.call( this.instanceMeta.context, this.getValue(), item, changeMeta, this.instanceMeta.sugarMeta)); }, this); this.trackAdd(dependentKey, normalizedIndex, observerContexts); }, @@ -10990,29 +11494,30 @@ itemPropertyWillChange: function (obj, keyName, array, observerContext) { var guid = guidFor(obj); if (!this.changedItems[guid]) { this.changedItems[guid] = { - array: array, - observerContext: observerContext, - obj: obj, - previousValues: {} + array: array, + observerContext: observerContext, + obj: obj, + previousValues: {} }; } - ++this.changedItemCount; + ++this.changedItemCount; this.changedItems[guid].previousValues[keyName] = get(obj, keyName); }, - itemPropertyDidChange: function(obj, keyName, array, observerContext) { + itemPropertyDidChange: function (obj, keyName, array, observerContext) { if (--this.changedItemCount === 0) { this.flushChanges(); } }, - flushChanges: function() { - var changedItems = this.changedItems, key, c, changeMeta; + flushChanges: function () { + var changedItems = this.changedItems; + var key, c, changeMeta; for (key in changedItems) { c = changedItems[key]; if (c.observerContext.destroyed) { continue; } @@ -11022,10 +11527,11 @@ this.setValue( this.callbacks.removedItem.call(this.instanceMeta.context, this.getValue(), c.obj, changeMeta, this.instanceMeta.sugarMeta)); this.setValue( this.callbacks.addedItem.call(this.instanceMeta.context, this.getValue(), c.obj, changeMeta, this.instanceMeta.sugarMeta)); } + this.changedItems = {}; } }; function normalizeIndex(index, length, newItemsOffset) { @@ -11054,30 +11560,29 @@ // previous values only available for item property changes this.previousValues = previousValues; } } - function addItems (dependentArray, callbacks, cp, propertyName, meta) { + function addItems(dependentArray, callbacks, cp, propertyName, meta) { forEach(dependentArray, function (item, index) { meta.setValue( callbacks.addedItem.call( this, meta.getValue(), item, new ChangeMeta(dependentArray, item, index, propertyName, cp, dependentArray.length), meta.sugarMeta)); }, this); } function reset(cp, propertyName) { - var callbacks = cp._callbacks(), - meta; + var callbacks = cp._callbacks(); + var hadMeta = cp._hasInstanceMeta(this, propertyName); + var meta = cp._instanceMeta(this, propertyName); - if (cp._hasInstanceMeta(this, propertyName)) { - meta = cp._instanceMeta(this, propertyName); - meta.setValue(cp.resetValue(meta.getValue())); - } else { - meta = cp._instanceMeta(this, propertyName); - } + if (hadMeta) { meta.setValue(cp.resetValue(meta.getValue())); } if (cp.options.initialize) { - cp.options.initialize.call(this, meta.getValue(), { property: cp, propertyName: propertyName }, meta.sugarMeta); + cp.options.initialize.call(this, meta.getValue(), { + property: cp, + propertyName: propertyName + }, meta.sugarMeta); } } function partiallyRecomputeFor(obj, dependentKey) { if (arrayBracketPattern.test(dependentKey)) { @@ -11090,20 +11595,19 @@ function ReduceComputedPropertyInstanceMeta(context, propertyName, initialValue) { this.context = context; this.propertyName = propertyName; this.cache = metaFor(context).cache; - this.dependentArrays = {}; this.sugarMeta = {}; - this.initialValue = initialValue; } ReduceComputedPropertyInstanceMeta.prototype = { getValue: function () { var value = cacheGet(this.cache, this.propertyName); + if (value !== undefined) { return value; } else { return this.initialValue; } @@ -11142,15 +11646,15 @@ @constructor */ __exports__.ReduceComputedProperty = ReduceComputedProperty; // TODO: default export + function ReduceComputedProperty(options) { var cp = this; this.options = options; - this._dependentKeys = null; // A map of dependentKey -> [itemProperty, ...] that tracks what properties of // items in the array we must track to update this property. this._itemPropertyKeys = {}; this._previousItemPropertyKeys = {}; @@ -11162,28 +11666,29 @@ // What we really want to do is coalesce by <cp, propertyName>. // We need a form of `scheduleOnce` that accepts an arbitrary token to // coalesce by, in addition to the target and method. run.once(this, recompute, propertyName); }; + var recompute = function(propertyName) { - var dependentKeys = cp._dependentKeys, - meta = cp._instanceMeta(this, propertyName), - callbacks = cp._callbacks(); + var dependentKeys = cp._dependentKeys; + var meta = cp._instanceMeta(this, propertyName); + var callbacks = cp._callbacks(); reset.call(this, cp, propertyName); meta.dependentArraysObserver.suspendArrayObservers(function () { forEach(cp._dependentKeys, function (dependentKey) { Ember.assert( - "dependent array " + dependentKey + " must be an `Ember.Array`. " + - "If you are not extending arrays, you will need to wrap native arrays with `Ember.A`", + 'dependent array ' + dependentKey + ' must be an `Ember.Array`. ' + + 'If you are not extending arrays, you will need to wrap native arrays with `Ember.A`', !(isArray(get(this, dependentKey)) && !EmberArray.detect(get(this, dependentKey)))); if (!partiallyRecomputeFor(this, dependentKey)) { return; } - var dependentArray = get(this, dependentKey), - previousDependentArray = meta.dependentArrays[dependentKey]; + var dependentArray = get(this, dependentKey); + var previousDependentArray = meta.dependentArrays[dependentKey]; if (dependentArray === previousDependentArray) { // The array may be the same, but our item property keys may have // changed, so we set them up again. We can't easily tell if they've // changed: the array may be the same object, but with different @@ -11208,19 +11713,20 @@ forEach(cp._dependentKeys, function(dependentKey) { if (!partiallyRecomputeFor(this, dependentKey)) { return; } var dependentArray = get(this, dependentKey); + if (dependentArray) { addItems.call(this, dependentArray, callbacks, cp, propertyName, meta); } }, this); }; this.func = function (propertyName) { - Ember.assert("Computed reduce values require at least one dependent key", cp._dependentKeys); + Ember.assert('Computed reduce values require at least one dependent key', cp._dependentKeys); recompute.call(this, propertyName); return cp._instanceMeta(this, propertyName).getValue(); }; @@ -11233,25 +11739,27 @@ } ReduceComputedProperty.prototype._callbacks = function () { if (!this.callbacks) { var options = this.options; + this.callbacks = { removedItem: options.removedItem || defaultCallback, addedItem: options.addedItem || defaultCallback }; } + return this.callbacks; }; ReduceComputedProperty.prototype._hasInstanceMeta = function (context, propertyName) { return !!metaFor(context).cacheMeta[propertyName]; }; ReduceComputedProperty.prototype._instanceMeta = function (context, propertyName) { - var cacheMeta = metaFor(context).cacheMeta, - meta = cacheMeta[propertyName]; + var cacheMeta = metaFor(context).cacheMeta; + var meta = cacheMeta[propertyName]; if (!meta) { meta = cacheMeta[propertyName] = new ReduceComputedPropertyInstanceMeta(context, propertyName, this.initialValue()); meta.dependentArraysObserver = new DependentArraysObserver(this._callbacks(), this, meta, context, propertyName, meta.sugarMeta); } @@ -11283,37 +11791,39 @@ this._itemPropertyKeys[dependentArrayKey] = []; } }; ReduceComputedProperty.prototype.property = function () { - var cp = this, - args = a_slice.call(arguments), - propertyArgs = new Set(), - match, - dependentArrayKey, - itemPropertyKey; + var cp = this; + var args = a_slice.call(arguments); + var propertyArgs = {}; + var match, dependentArrayKey, itemPropertyKey; forEach(args, function (dependentKey) { if (doubleEachPropertyPattern.test(dependentKey)) { - throw new EmberError("Nested @each properties not supported: " + dependentKey); + throw new EmberError('Nested @each properties not supported: ' + dependentKey); } else if (match = eachPropertyPattern.exec(dependentKey)) { dependentArrayKey = match[1]; - var itemPropertyKeyPattern = match[2], - addItemPropertyKey = function (itemPropertyKey) { - cp.itemPropertyKey(dependentArrayKey, itemPropertyKey); - }; + var itemPropertyKeyPattern = match[2]; + var addItemPropertyKey = function (itemPropertyKey) { + cp.itemPropertyKey(dependentArrayKey, itemPropertyKey); + }; expandProperties(itemPropertyKeyPattern, addItemPropertyKey); - propertyArgs.add(dependentArrayKey); + propertyArgs[guidFor(dependentArrayKey)] = dependentArrayKey; } else { - propertyArgs.add(dependentKey); + propertyArgs[guidFor(dependentKey)] = dependentKey; } }); - return ComputedProperty.prototype.property.apply(this, propertyArgs.toArray()); + var propertyArgsToArray = []; + for (var guid in propertyArgs) { + propertyArgsToArray.push(propertyArgs[guid]); + } + return ComputedProperty.prototype.property.apply(this, propertyArgsToArray); }; /** Creates a computed property which operates on dependent arrays and is updated with "one at a time" semantics. When items are added or @@ -11445,12 +11955,12 @@ // `reversedName` isn't defined on Person, but we have access to it via // the item controller App.PersonController. If we'd used // `content.@each.reversedName` above, we would be getting the objects // directly and not have access to `reversedName`. // - var reversedNameA = get(personA, 'reversedName'), - reversedNameB = get(personB, 'reversedName'); + var reversedNameA = get(personA, 'reversedName'); + var reversedNameB = get(personB, 'reversedName'); return Ember.compare(reversedNameA, reversedNameB); }) }); @@ -11505,16 +12015,16 @@ if (arguments.length > 1) { args = a_slice.call(arguments, 0, -1); options = a_slice.call(arguments, -1)[0]; } - if (typeof options !== "object") { - throw new EmberError("Reduce Computed Property declared without an options hash"); + if (typeof options !== 'object') { + throw new EmberError('Reduce Computed Property declared without an options hash'); } if (!('initialValue' in options)) { - throw new EmberError("Reduce Computed Property declared without an initial value"); + throw new EmberError('Reduce Computed Property declared without an initial value'); } var cp = new ReduceComputedProperty(options); if (args) { @@ -11525,11 +12035,11 @@ } __exports__.reduceComputed = reduceComputed; }); define("ember-runtime/computed/reduce_computed_macros", - ["ember-metal/core","ember-metal/merge","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/error","ember-metal/enumerable_utils","ember-metal/run_loop","ember-metal/observer","ember-runtime/computed/array_computed","ember-runtime/computed/reduce_computed","ember-runtime/system/object_proxy","ember-runtime/system/subarray","ember-runtime/keys","ember-runtime/compare","exports"], + ["ember-metal/core","ember-metal/merge","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/error","ember-metal/enumerable_utils","ember-metal/run_loop","ember-metal/observer","ember-runtime/computed/array_computed","ember-runtime/computed/reduce_computed","ember-runtime/system/object_proxy","ember-runtime/system/subarray","ember-metal/keys","ember-runtime/compare","exports"], function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __exports__) { "use strict"; /** @module ember @submodule ember-runtime @@ -11611,11 +12121,11 @@ @method computed.max @for Ember @param {String} dependentKey @return {Ember.ComputedProperty} computes the largest value in the dependentKey's array */ - function max (dependentKey) { + function max(dependentKey) { return reduceComputed(dependentKey, { initialValue: -Infinity, addedItem: function (accumulatedValue, item, changeMeta, instanceMeta) { return Math.max(accumulatedValue, item); @@ -11681,20 +12191,21 @@ __exports__.min = min;/** Returns an array mapped via the callback The callback method you provide should have the following signature. `item` is the current item in the iteration. + `index` is the integer index of the current item in the iteration. ```javascript - function(item); + function(item, index); ``` Example ```javascript var Hamster = Ember.Object.extend({ - excitingChores: Ember.computed.map('chores', function(chore) { + excitingChores: Ember.computed.map('chores', function(chore, index) { return chore.toUpperCase() + '!'; }) }); var hamster = Hamster.create({ @@ -11711,11 +12222,11 @@ @return {Ember.ComputedProperty} an array mapped via the callback */ function map(dependentKey, callback) { var options = { addedItem: function(array, item, changeMeta, instanceMeta) { - var mapped = callback.call(this, item); + var mapped = callback.call(this, item, changeMeta.index); array.insertAt(changeMeta.index, mapped); return array; }, removedItem: function(array, item, changeMeta, instanceMeta) { array.removeAt(changeMeta.index, 1); @@ -11772,28 +12283,29 @@ /** Filters the array by the callback. The callback method you provide should have the following signature. `item` is the current item in the iteration. + `index` is the integer index of the current item in the iteration. ```javascript - function(item); + function(item, index); ``` ```javascript var Hamster = Ember.Object.extend({ - remainingChores: Ember.computed.filter('chores', function(chore) { + remainingChores: Ember.computed.filter('chores', function(chore, index) { return !chore.done; }) }); - var hamster = Hamster.create({ + var hamster = Hamster.create({ chores: [ { name: 'cook', done: true }, { name: 'clean', done: true }, { name: 'write more unit tests', done: false } - ] + ] }); hamster.get('remainingChores'); // [{name: 'write more unit tests', done: false}] ``` @@ -11807,13 +12319,13 @@ var options = { initialize: function (array, changeMeta, instanceMeta) { instanceMeta.filteredArrayIndexes = new SubArray(); }, - addedItem: function(array, item, changeMeta, instanceMeta) { - var match = !!callback.call(this, item), - filterIndex = instanceMeta.filteredArrayIndexes.addItem(changeMeta.index, match); + addedItem: function (array, item, changeMeta, instanceMeta) { + var match = !!callback.call(this, item, changeMeta.index); + var filterIndex = instanceMeta.filteredArrayIndexes.addItem(changeMeta.index, match); if (match) { array.insertAt(filterIndex, item); } @@ -11915,36 +12427,40 @@ @return {Ember.ComputedProperty} computes a new array with all the unique elements from the dependent array */ function uniq() { var args = a_slice.call(arguments); + args.push({ initialize: function(array, changeMeta, instanceMeta) { instanceMeta.itemCounts = {}; }, addedItem: function(array, item, changeMeta, instanceMeta) { var guid = guidFor(item); if (!instanceMeta.itemCounts[guid]) { instanceMeta.itemCounts[guid] = 1; + array.pushObject(item); } else { ++instanceMeta.itemCounts[guid]; } - array.addObject(item); return array; }, + removedItem: function(array, item, _, instanceMeta) { - var guid = guidFor(item), - itemCounts = instanceMeta.itemCounts; + var guid = guidFor(item); + var itemCounts = instanceMeta.itemCounts; if (--itemCounts[guid] === 0) { array.removeObject(item); } + return array; } }); + return arrayComputed.apply(null, args); } __exports__.uniq = uniq;/** Alias for [Ember.computed.uniq](/api/#method_computed_uniq). @@ -11979,10 +12495,11 @@ @return {Ember.ComputedProperty} computes a new array with all the duplicated elements from the dependent arrays */ function intersect() { var args = a_slice.call(arguments); + args.push({ initialize: function (array, changeMeta, instanceMeta) { instanceMeta.itemCounts = {}; }, @@ -11990,20 +12507,26 @@ var itemGuid = guidFor(item); var dependentGuid = guidFor(changeMeta.arrayChanged); var numberOfDependentArrays = changeMeta.property._dependentKeys.length; var itemCounts = instanceMeta.itemCounts; - if (!itemCounts[itemGuid]) { itemCounts[itemGuid] = {}; } - if (itemCounts[itemGuid][dependentGuid] === undefined) { itemCounts[itemGuid][dependentGuid] = 0; } + if (!itemCounts[itemGuid]) { + itemCounts[itemGuid] = {}; + } + if (itemCounts[itemGuid][dependentGuid] === undefined) { + itemCounts[itemGuid][dependentGuid] = 0; + } + if (++itemCounts[itemGuid][dependentGuid] === 1 && numberOfDependentArrays === keys(itemCounts[itemGuid]).length) { - array.addObject(item); } + return array; }, + removedItem: function(array, item, changeMeta, instanceMeta) { var itemGuid = guidFor(item); var dependentGuid = guidFor(changeMeta.arrayChanged); var numberOfDependentArrays = changeMeta.property._dependentKeys.length; var numberOfArraysItemAppearsIn; @@ -12018,15 +12541,18 @@ numberOfArraysItemAppearsIn = keys(itemCounts[itemGuid]).length; if (numberOfArraysItemAppearsIn === 0) { delete itemCounts[itemGuid]; } + array.removeObject(item); } + return array; } }); + return arrayComputed.apply(null, args); } __exports__.intersect = intersect;/** A computed property which returns a new array with all the @@ -12059,49 +12585,57 @@ items from the first dependent array that are not in the second dependent array */ function setDiff(setAProperty, setBProperty) { if (arguments.length !== 2) { - throw new EmberError("setDiff requires exactly two dependent arrays."); + throw new EmberError('setDiff requires exactly two dependent arrays.'); } + return arrayComputed(setAProperty, setBProperty, { addedItem: function (array, item, changeMeta, instanceMeta) { - var setA = get(this, setAProperty), - setB = get(this, setBProperty); + var setA = get(this, setAProperty); + var setB = get(this, setBProperty); if (changeMeta.arrayChanged === setA) { if (!setB.contains(item)) { array.addObject(item); } } else { array.removeObject(item); } + return array; }, removedItem: function (array, item, changeMeta, instanceMeta) { - var setA = get(this, setAProperty), - setB = get(this, setBProperty); + var setA = get(this, setAProperty); + var setB = get(this, setBProperty); if (changeMeta.arrayChanged === setB) { if (setA.contains(item)) { array.addObject(item); } } else { array.removeObject(item); } + return array; } }); } __exports__.setDiff = setDiff;function binarySearch(array, item, low, high) { var mid, midItem, res, guidMid, guidItem; - if (arguments.length < 4) { high = get(array, 'length'); } - if (arguments.length < 3) { low = 0; } + if (arguments.length < 4) { + high = get(array, 'length'); + } + if (arguments.length < 3) { + low = 0; + } + if (low === high) { return low; } mid = low + Math.floor((high - low) / 2); @@ -12113,10 +12647,11 @@ if (guidMid === guidItem) { return mid; } res = this.order(midItem, item); + if (res === 0) { res = guidMid < guidItem ? -1 : 1; } @@ -12130,10 +12665,11 @@ function _guidFor(item) { if (SearchProxy.detectInstance(item)) { return guidFor(get(item, 'content')); } + return guidFor(item); } } @@ -12202,31 +12738,32 @@ array of sort properties (add `:desc` to the arrays sort properties to sort descending) or a function to use when sorting @return {Ember.ComputedProperty} computes a new sorted array based on the sort property array or callback function */ function sort(itemsKey, sortDefinition) { - Ember.assert("Ember.computed.sort requires two arguments: an array key to sort and either a sort properties key or sort function", arguments.length === 2); + Ember.assert('Ember.computed.sort requires two arguments: an array key to sort and ' + + 'either a sort properties key or sort function', arguments.length === 2); var initFn, sortPropertiesKey; if (typeof sortDefinition === 'function') { initFn = function (array, changeMeta, instanceMeta) { instanceMeta.order = sortDefinition; instanceMeta.binarySearch = binarySearch; }; } else { sortPropertiesKey = sortDefinition; + initFn = function (array, changeMeta, instanceMeta) { function setupSortProperties() { - var sortPropertyDefinitions = get(this, sortPropertiesKey), - sortProperty, - sortProperties = instanceMeta.sortProperties = [], - sortPropertyAscending = instanceMeta.sortPropertyAscending = {}, - idx, - asc; + var sortPropertyDefinitions = get(this, sortPropertiesKey); + var sortProperties = instanceMeta.sortProperties = []; + var sortPropertyAscending = instanceMeta.sortPropertyAscending = {}; + var sortProperty, idx, asc; - Ember.assert("Cannot sort: '" + sortPropertiesKey + "' is not an array.", isArray(sortPropertyDefinitions)); + Ember.assert('Cannot sort: \'' + sortPropertiesKey + '\' is not an array.', + isArray(sortPropertyDefinitions)); changeMeta.property.clearItemPropertyKeys(itemsKey); forEach(sortPropertyDefinitions, function (sortPropertyDefinition) { if ((idx = sortPropertyDefinition.indexOf(':')) !== -1) { @@ -12253,17 +12790,15 @@ setupSortProperties.call(this); changeMeta.property.recomputeOnce.call(this, propertyName); } addObserver(this, sortPropertiesKey, updateSortPropertiesOnce); - setupSortProperties.call(this); - instanceMeta.order = function (itemA, itemB) { - var isProxy = itemB instanceof SearchProxy, - sortProperty, result, asc; + var isProxy = itemB instanceof SearchProxy; + var sortProperty, result, asc; for (var i = 0; i < this.sortProperties.length; ++i) { sortProperty = this.sortProperties[i]; result = compare(get(itemA, sortProperty), isProxy ? itemB[sortProperty] : get(itemB, sortProperty)); @@ -12284,10 +12819,11 @@ initialize: initFn, addedItem: function (array, item, changeMeta, instanceMeta) { var index = instanceMeta.binarySearch(array, item); array.insertAt(index, item); + return array; }, removedItem: function (array, item, changeMeta, instanceMeta) { var proxyProperties, index, searchItem; @@ -12300,10 +12836,11 @@ searchItem = item; } index = instanceMeta.binarySearch(array, searchItem); array.removeAt(index); + return array; } }); } @@ -12368,23 +12905,22 @@ controller (probably an `ObjectController`) that will wrap each individual item. For example: ```handlebars - {{#each post in controller}} - <li>{{post.title}} ({{post.titleLength}} characters)</li> - {{/each}} + {{#each post in controller}} + <li>{{post.title}} ({{post.titleLength}} characters)</li> + {{/each}} ``` ```javascript App.PostsController = Ember.ArrayController.extend({ itemController: 'post' }); App.PostController = Ember.ObjectController.extend({ // the `title` property will be proxied to the underlying post. - titleLength: function() { return this.get('title').length; }.property('title') }); ``` @@ -12418,14 +12954,26 @@ */ __exports__["default"] = ArrayProxy.extend(ControllerMixin, SortableMixin, { /** - The controller used to wrap items, if any. + The controller used to wrap items, if any. If the value is a string, it will + be used to lookup the container for the controller. As an alternative, you + can also provide a controller class as the value. + For example: + + ```javascript + App.MyArrayController = Ember.ArrayController.extend({ + itemController: Ember.ObjectController.extend({ + //Item Controller Implementation + }) + }); + ``` + @property itemController - @type String + @type String | Ember.Controller @default null */ itemController: null, /** @@ -12462,10 +13010,11 @@ var object = arrangedContent && arrangedContent.objectAt(idx); var controllerClass; if (idx >= 0 && idx < length) { controllerClass = this.lookupItemController(object); + if (controllerClass) { return this.controllerAt(idx, object, controllerClass); } } @@ -12522,41 +13071,42 @@ * @type Boolean */ _isVirtual: false, controllerAt: function(idx, object, controllerClass) { - var fullName, subController, parentController; - var container = get(this, 'container'); var subControllers = this._subControllers; + var fullName, subController, subControllerFactory, parentController, options; if (subControllers.length > idx) { subController = subControllers[idx]; if (subController) { return subController; } } - fullName = 'controller:' + controllerClass; - - if (!container.has(fullName)) { - throw new EmberError('Could not resolve itemController: "' + controllerClass + '"'); - } - if (this._isVirtual) { parentController = get(this, 'parentController'); } else { parentController = this; } - subController = container.lookupFactory(fullName).create({ - target: parentController, - parentController: parentController, - model: object - }); + + fullName = 'controller:' + controllerClass; + if (!container.has(fullName)) { + throw new EmberError('Could not resolve itemController: "' + controllerClass + '"'); + } + + subController = container.lookupFactory(fullName).create({ + target: parentController, + parentController: parentController, + model: object + }); + + subControllers[idx] = subController; return subController; }, @@ -12567,10 +13117,11 @@ var subControllers = this._subControllers; if (subControllers.length) { for (var i = 0, length = subControllers.length; length > i; i++) { controller = subControllers[i]; + if (controller) { controller.destroy(); } } @@ -12630,50 +13181,64 @@ @uses Ember.ControllerMixin **/ __exports__["default"] = ObjectProxy.extend(ControllerMixin); }); define("ember-runtime/copy", - ["ember-metal/enumerable_utils","ember-metal/utils","ember-runtime/system/object","ember-runtime/mixins/copyable","ember-metal/platform","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) { + ["ember-metal/enumerable_utils","ember-metal/utils","ember-runtime/system/object","ember-runtime/mixins/copyable","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) { "use strict"; var indexOf = __dependency1__.indexOf; var typeOf = __dependency2__.typeOf; var EmberObject = __dependency3__["default"]; var Copyable = __dependency4__["default"]; - var create = __dependency5__.create; function _copy(obj, deep, seen, copies) { var ret, loc, key; // primitive data types are immutable, just return them. - if ('object' !== typeof obj || obj===null) return obj; + if (typeof obj !== 'object' || obj === null) { + return obj; + } // avoid cyclical loops - if (deep && (loc=indexOf(seen, obj))>=0) return copies[loc]; + if (deep && (loc = indexOf(seen, obj)) >= 0) { + return copies[loc]; + } - Ember.assert('Cannot clone an Ember.Object that does not implement Ember.Copyable', !(obj instanceof EmberObject) || (Copyable && Copyable.detect(obj))); + Ember.assert('Cannot clone an Ember.Object that does not implement Ember.Copyable', + !(obj instanceof EmberObject) || (Copyable && Copyable.detect(obj))); // IMPORTANT: this specific test will detect a native array only. Any other // object will need to implement Copyable. if (typeOf(obj) === 'array') { ret = obj.slice(); + if (deep) { loc = ret.length; - while(--loc>=0) ret[loc] = _copy(ret[loc], deep, seen, copies); + + while (--loc >= 0) { + ret[loc] = _copy(ret[loc], deep, seen, copies); + } } } else if (Copyable && Copyable.detect(obj)) { ret = obj.copy(deep, seen, copies); } else if (obj instanceof Date) { ret = new Date(obj.getTime()); } else { ret = {}; - for(key in obj) { - if (!obj.hasOwnProperty(key)) continue; + for (key in obj) { + // support Null prototype + if (!Object.prototype.hasOwnProperty.call(obj, key)) { + continue; + } + // Prevents browsers that don't respect non-enumerability from // copying internal Ember properties - if (key.substring(0,2) === '__') continue; + if (key.substring(0, 2) === '__') { + continue; + } ret[key] = deep ? _copy(obj[key], deep, seen, copies) : obj[key]; } } @@ -12699,12 +13264,18 @@ @param {Boolean} deep If true, a deep copy of the object is made @return {Object} The cloned object */ __exports__["default"] = function copy(obj, deep) { // fast paths - if ('object' !== typeof obj || obj === null) return obj; // can't copy primitives - if (Copyable && Copyable.detect(obj)) return obj.copy(deep); + if ('object' !== typeof obj || obj === null) { + return obj; // can't copy primitives + } + + if (Copyable && Copyable.detect(obj)) { + return obj.copy(deep); + } + return _copy(obj, deep, deep ? [] : null, deep ? [] : null); } }); define("ember-runtime/core", ["exports"], @@ -12732,31 +13303,36 @@ @param {Object} a first object to compare @param {Object} b second object to compare @return {Boolean} */ var isEqual = function isEqual(a, b) { - if (a && 'function'===typeof a.isEqual) return a.isEqual(b); + if (a && typeof a.isEqual === 'function') { + return a.isEqual(b); + } + if (a instanceof Date && b instanceof Date) { return a.getTime() === b.getTime(); } + return a === b; }; __exports__.isEqual = isEqual; }); define("ember-runtime/ext/function", - ["ember-metal/core","ember-metal/expand_properties","ember-metal/computed"], - function(__dependency1__, __dependency2__, __dependency3__) { + ["ember-metal/core","ember-metal/expand_properties","ember-metal/computed","ember-metal/mixin"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__) { "use strict"; /** @module ember @submodule ember-runtime */ var Ember = __dependency1__["default"]; // Ember.EXTEND_PROTOTYPES, Ember.assert var expandProperties = __dependency2__["default"]; var computed = __dependency3__.computed; + var observer = __dependency4__.observer; var a_slice = Array.prototype.slice; var FunctionPrototype = Function.prototype; if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Function) { @@ -12773,21 +13349,19 @@ firstName: '', lastName: '', fullName: function() { return this.get('firstName') + ' ' + this.get('lastName'); - - // Call this flag to mark the function as a property - }.property() + }.property() // Call this flag to mark the function as a property }); var president = MyApp.President.create({ - firstName: "Barack", - lastName: "Obama" + firstName: 'Barack', + lastName: 'Obama' }); - president.get('fullName'); // "Barack Obama" + president.get('fullName'); // 'Barack Obama' ``` Treating a function like a property is useful because they can work with bindings, just like any other property. @@ -12819,11 +13393,11 @@ See [Ember.ComputedProperty](/api/classes/Ember.ComputedProperty.html), [Ember.computed](/api/#method_computed). @method property @for Function */ - FunctionPrototype.property = function() { + FunctionPrototype.property = function () { var ret = computed(this); // ComputedProperty.prototype.property expands properties; no need for us to // do so here. return ret.property.apply(ret, arguments); }; @@ -12852,20 +13426,16 @@ @method observes @for Function */ FunctionPrototype.observes = function() { - var addWatchedProperty = function (obs) { watched.push(obs); }; - var watched = []; - - for (var i=0; i<arguments.length; ++i) { - expandProperties(arguments[i], addWatchedProperty); + var length = arguments.length; + var args = new Array(length); + for (var x = 0; x < length; x++) { + args[x] = arguments[x]; } - - this.__ember_observes__ = watched; - - return this; + return observer.apply(this, args.concat(this)); }; /** The `observesImmediately` extension of Javascript's Function prototype is available when `Ember.EXTEND_PROTOTYPES` or @@ -12889,14 +13459,15 @@ See `Ember.immediateObserver`. @method observesImmediately @for Function */ - FunctionPrototype.observesImmediately = function() { - for (var i=0, l=arguments.length; i<l; i++) { + FunctionPrototype.observesImmediately = function () { + for (var i = 0, l = arguments.length; i < l; i++) { var arg = arguments[i]; - Ember.assert("Immediate observers must observe internal properties only, not properties on other objects.", arg.indexOf('.') === -1); + Ember.assert('Immediate observers must observe internal properties only, ' + + 'not properties on other objects.', arg.indexOf('.') === -1); } // observes handles property expansion return this.observes.apply(this, arguments); }; @@ -12921,15 +13492,17 @@ See `Ember.beforeObserver`. @method observesBefore @for Function */ - FunctionPrototype.observesBefore = function() { - var addWatchedProperty = function (obs) { watched.push(obs); }; + FunctionPrototype.observesBefore = function () { var watched = []; + var addWatchedProperty = function (obs) { + watched.push(obs); + }; - for (var i=0; i<arguments.length; ++i) { + for (var i = 0, l = arguments.length; i < l; ++i) { expandProperties(arguments[i], addWatchedProperty); } this.__ember_observesBefore__ = watched; @@ -12955,30 +13528,61 @@ See `Ember.on`. @method on @for Function */ - FunctionPrototype.on = function() { + FunctionPrototype.on = function () { var events = a_slice.call(arguments); this.__ember_listens__ = events; + return this; }; } }); define("ember-runtime/ext/rsvp", - ["ember-metal/core","ember-metal/logger","exports"], - function(__dependency1__, __dependency2__, __exports__) { + ["ember-metal/core","ember-metal/logger","ember-metal/run_loop","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __exports__) { "use strict"; /* globals RSVP:true */ var Ember = __dependency1__["default"]; var Logger = __dependency2__["default"]; + var run = __dependency3__["default"]; - var RSVP = requireModule("rsvp"); - var Test, testModuleName = 'ember-testing/test'; + var RSVP = requireModule('rsvp'); + var testModuleName = 'ember-testing/test'; + var Test; - RSVP.onerrorDefault = function(error) { + var asyncStart = function() { + if (Ember.Test && Ember.Test.adapter) { + Ember.Test.adapter.asyncStart(); + } + }; + + var asyncEnd = function() { + if (Ember.Test && Ember.Test.adapter) { + Ember.Test.adapter.asyncEnd(); + } + }; + + RSVP.configure('async', function(callback, promise) { + var async = !run.currentRunLoop; + + if (Ember.testing && async) { asyncStart(); } + + run.backburner.schedule('actions', function(){ + if (Ember.testing && async) { asyncEnd(); } + callback(promise); + }); + }); + + RSVP.Promise.prototype.fail = function(callback, label){ + Ember.deprecate('RSVP.Promise.fail has been renamed as RSVP.Promise.catch'); + return this['catch'](callback, label); + }; + + RSVP.onerrorDefault = function (error) { if (error instanceof Error) { if (Ember.testing) { // ES6TODO: remove when possible if (!Test && Ember.__loader.registry[testModuleName]) { Test = requireModule(testModuleName)['default']; @@ -13031,152 +13635,192 @@ See [Ember.String.fmt](/api/classes/Ember.String.html#method_fmt). @method fmt @for String */ - StringPrototype.fmt = function() { + StringPrototype.fmt = function () { return fmt(this, arguments); }; /** See [Ember.String.w](/api/classes/Ember.String.html#method_w). @method w @for String */ - StringPrototype.w = function() { + StringPrototype.w = function () { return w(this); }; /** See [Ember.String.loc](/api/classes/Ember.String.html#method_loc). @method loc @for String */ - StringPrototype.loc = function() { + StringPrototype.loc = function () { return loc(this, arguments); }; /** See [Ember.String.camelize](/api/classes/Ember.String.html#method_camelize). @method camelize @for String */ - StringPrototype.camelize = function() { + StringPrototype.camelize = function () { return camelize(this); }; /** See [Ember.String.decamelize](/api/classes/Ember.String.html#method_decamelize). @method decamelize @for String */ - StringPrototype.decamelize = function() { + StringPrototype.decamelize = function () { return decamelize(this); }; /** See [Ember.String.dasherize](/api/classes/Ember.String.html#method_dasherize). @method dasherize @for String */ - StringPrototype.dasherize = function() { + StringPrototype.dasherize = function () { return dasherize(this); }; /** See [Ember.String.underscore](/api/classes/Ember.String.html#method_underscore). @method underscore @for String */ - StringPrototype.underscore = function() { + StringPrototype.underscore = function () { return underscore(this); }; /** See [Ember.String.classify](/api/classes/Ember.String.html#method_classify). @method classify @for String */ - StringPrototype.classify = function() { + StringPrototype.classify = function () { return classify(this); }; /** See [Ember.String.capitalize](/api/classes/Ember.String.html#method_capitalize). @method capitalize @for String */ - StringPrototype.capitalize = function() { + StringPrototype.capitalize = function () { return capitalize(this); }; } }); -define("ember-runtime/keys", - ["ember-metal/enumerable_utils","ember-metal/platform","exports"], - function(__dependency1__, __dependency2__, __exports__) { +define("ember-runtime/mixins/-proxy", + ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/observer","ember-metal/property_events","ember-metal/computed","ember-metal/properties","ember-metal/mixin","ember-runtime/system/string","ember-runtime/system/object","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __exports__) { "use strict"; - var EnumerableUtils = __dependency1__["default"]; - var create = __dependency2__.create; + /** + @module ember + @submodule ember-runtime + */ + var Ember = __dependency1__["default"]; + // Ember.assert + var get = __dependency2__.get; + var set = __dependency3__.set; + var meta = __dependency4__.meta; + var addObserver = __dependency5__.addObserver; + var removeObserver = __dependency5__.removeObserver; + var addBeforeObserver = __dependency5__.addBeforeObserver; + var removeBeforeObserver = __dependency5__.removeBeforeObserver; + var propertyWillChange = __dependency6__.propertyWillChange; + var propertyDidChange = __dependency6__.propertyDidChange; + var computed = __dependency7__.computed; + var defineProperty = __dependency8__.defineProperty; + var Mixin = __dependency9__.Mixin; + var observer = __dependency9__.observer; + var fmt = __dependency10__.fmt; + var EmberObject = __dependency11__["default"]; + + function contentPropertyWillChange(content, contentKey) { + var key = contentKey.slice(8); // remove "content." + if (key in this) { return; } // if shadowed in proxy + propertyWillChange(this, key); + } + + function contentPropertyDidChange(content, contentKey) { + var key = contentKey.slice(8); // remove "content." + if (key in this) { return; } // if shadowed in proxy + propertyDidChange(this, key); + } + /** - Returns all of the keys defined on an object or hash. This is useful - when inspecting objects for debugging. On browsers that support it, this - uses the native `Object.keys` implementation. + `Ember.ProxyMixin` forwards all properties not defined by the proxy itself + to a proxied `content` object. See Ember.ObjectProxy for more details. - @method keys - @for Ember - @param {Object} obj - @return {Array} Array containing keys of obj + @class ProxyMixin + @namespace Ember */ - var keys = Object.keys; - if (!keys || create.isSimulated) { - var prototypeProperties = [ - 'constructor', - 'hasOwnProperty', - 'isPrototypeOf', - 'propertyIsEnumerable', - 'valueOf', - 'toLocaleString', - 'toString' - ], - pushPropertyName = function(obj, array, key) { - // Prevents browsers that don't respect non-enumerability from - // copying internal Ember properties - if (key.substring(0,2) === '__') return; - if (key === '_super') return; - if (EnumerableUtils.indexOf(array, key) >= 0) return; - if (!Object.prototype.hasOwnProperty.call(obj, key)) return; + __exports__["default"] = Mixin.create({ + /** + The object whose properties will be forwarded. - array.push(key); - }; + @property content + @type Ember.Object + @default null + */ + content: null, + _contentDidChange: observer('content', function() { + Ember.assert("Can't set Proxy's content to itself", get(this, 'content') !== this); + }), - keys = function keys(obj) { - var ret = [], key; - for (key in obj) { - pushPropertyName(obj, ret, key); - } + isTruthy: computed.bool('content'), - // IE8 doesn't enumerate property that named the same as prototype properties. - for (var i = 0, l = prototypeProperties.length; i < l; i++) { - key = prototypeProperties[i]; + _debugContainerKey: null, - pushPropertyName(obj, ret, key); + willWatchProperty: function (key) { + var contentKey = 'content.' + key; + addBeforeObserver(this, contentKey, null, contentPropertyWillChange); + addObserver(this, contentKey, null, contentPropertyDidChange); + }, + + didUnwatchProperty: function (key) { + var contentKey = 'content.' + key; + removeBeforeObserver(this, contentKey, null, contentPropertyWillChange); + removeObserver(this, contentKey, null, contentPropertyDidChange); + }, + + unknownProperty: function (key) { + var content = get(this, 'content'); + if (content) { + return get(content, key); } + }, - return ret; - }; - } + setUnknownProperty: function (key, value) { + var m = meta(this); + if (m.proto === this) { + // if marked as prototype then just defineProperty + // rather than delegate + defineProperty(this, key, null, value); + return value; + } - __exports__["default"] = keys; + var content = get(this, 'content'); + Ember.assert(fmt("Cannot delegate set('%@', %@) to the 'content' property of object proxy %@: its 'content' is undefined.", [key, value, this]), content); + return set(content, key, value); + } + + }); }); define("ember-runtime/mixins/action_handler", ["ember-metal/merge","ember-metal/mixin","ember-metal/property_get","ember-metal/utils","exports"], function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) { "use strict"; @@ -13384,25 +14028,19 @@ @method send @param {String} actionName The action to trigger @param {*} context a context to send with the action */ send: function(actionName) { - var args = [].slice.call(arguments, 1), target; + var args = [].slice.call(arguments, 1); + var target; if (this._actions && this._actions[actionName]) { if (this._actions[actionName].apply(this, args) === true) { // handler returned true, so this action will bubble } else { return; } - } else if (!Ember.FEATURES.isEnabled('ember-routing-drop-deprecated-action-style') && this.deprecatedSend && this.deprecatedSendHandles && this.deprecatedSendHandles(actionName)) { - Ember.warn("The current default is deprecated but will prefer to handle actions directly on the controller instead of a similarly named action in the actions hash. To turn off this deprecated feature set: Ember.FEATURES['ember-routing-drop-deprecated-action-style'] = true"); - if (this.deprecatedSend.apply(this, [].slice.call(arguments)) === true) { - // handler return true, so this action will bubble - } else { - return; - } } if (target = get(this, 'target')) { Ember.assert("The `target` for " + this + " (" + target + ") does not have a `send` method", typeof target.send === 'function'); target.send.apply(target, arguments); @@ -13443,10 +14081,28 @@ var removeListener = __dependency10__.removeListener; var sendEvent = __dependency10__.sendEvent; var hasListeners = __dependency10__.hasListeners; var isWatching = __dependency11__.isWatching; + function arrayObserversHelper(obj, target, opts, operation, notify) { + var willChange = (opts && opts.willChange) || 'arrayWillChange'; + var didChange = (opts && opts.didChange) || 'arrayDidChange'; + var hasObservers = get(obj, 'hasArrayObservers'); + + if (hasObservers === notify) { + propertyWillChange(obj, 'hasArrayObservers'); + } + + operation(obj, '@array:before', target, willChange); + operation(obj, '@array:change', target, didChange); + + if (hasObservers === notify) { + propertyDidChange(obj, 'hasArrayObservers'); + } + return obj; + } + // .......................................................... // ARRAY // /** This mixin implements Observer-friendly Array-like behavior. It is not a @@ -13515,11 +14171,11 @@ @method objectAt @param {Number} idx The index of the item to return. @return {*} item at index or undefined */ objectAt: function(idx) { - if ((idx < 0) || (idx >= get(this, 'length'))) return undefined; + if (idx < 0 || idx >= get(this, 'length')) return undefined; return get(this, idx); }, /** This returns the objects at the specified indexes, using `objectAt`. @@ -13554,11 +14210,11 @@ @property [] @return this */ '[]': computed(function(key, value) { if (value !== undefined) this.replace(0, get(this, 'length'), value) ; - return this ; + return this; }), firstObject: computed(function() { return this.objectAt(0); }), @@ -13697,20 +14353,13 @@ @param {Object} target The observer object. @param {Hash} opts Optional hash of configuration options including `willChange` and `didChange` option. @return {Ember.Array} receiver */ - addArrayObserver: function(target, opts) { - var willChange = (opts && opts.willChange) || 'arrayWillChange', - didChange = (opts && opts.didChange) || 'arrayDidChange'; - var hasObservers = get(this, 'hasArrayObservers'); - if (!hasObservers) propertyWillChange(this, 'hasArrayObservers'); - addListener(this, '@array:before', target, willChange); - addListener(this, '@array:change', target, didChange); - if (!hasObservers) propertyDidChange(this, 'hasArrayObservers'); - return this; + addArrayObserver: function(target, opts) { + return arrayObserversHelper(this, target, opts, addListener, false); }, /** Removes an array observer from the object if the observer is current registered. Calling this method multiple times with the same object will @@ -13721,19 +14370,11 @@ @param {Hash} opts Optional hash of configuration options including `willChange` and `didChange` option. @return {Ember.Array} receiver */ removeArrayObserver: function(target, opts) { - var willChange = (opts && opts.willChange) || 'arrayWillChange', - didChange = (opts && opts.didChange) || 'arrayDidChange'; - - var hasObservers = get(this, 'hasArrayObservers'); - if (hasObservers) propertyWillChange(this, 'hasArrayObservers'); - removeListener(this, '@array:before', target, willChange); - removeListener(this, '@array:change', target, didChange); - if (hasObservers) propertyDidChange(this, 'hasArrayObservers'); - return this; + return arrayObserversHelper(this, target, opts, removeListener, true); }, /** Becomes true whenever the array currently has observers watching changes on the array. @@ -13823,13 +14464,13 @@ } this.enumerableContentDidChange(removeAmt, adding); sendEvent(this, '@array:change', [this, startIdx, removeAmt, addAmt]); - var length = get(this, 'length'), - cachedFirst = cacheFor(this, 'firstObject'), - cachedLast = cacheFor(this, 'lastObject'); + var length = get(this, 'length'); + var cachedFirst = cacheFor(this, 'firstObject'); + var cachedLast = cacheFor(this, 'lastObject'); if (this.objectAt(0) !== cachedFirst) { propertyWillChange(this, 'firstObject'); propertyDidChange(this, 'firstObject'); } if (this.objectAt(length-1) !== cachedLast) { @@ -13971,23 +14612,12 @@ model: null, /** @private */ - content: computed.alias('model'), + content: computed.alias('model') - deprecatedSendHandles: function(actionName) { - return !!this[actionName]; - }, - - deprecatedSend: function(actionName) { - var args = [].slice.call(arguments, 1); - Ember.assert('' + this + " has the action " + actionName + " but it is not a function", typeof this[actionName] === 'function'); - Ember.deprecate('Action handlers implemented directly on controllers are deprecated in favor of action handlers on an `actions` object ( action: `' + actionName + '` on ' + this + ')', false); - this[actionName].apply(this, args); - return; - } }); }); define("ember-runtime/mixins/controller_content_model_alias_deprecation", ["ember-metal/core","ember-metal/property_get","ember-metal/mixin","exports"], function(__dependency1__, __dependency2__, __dependency3__, __exports__) { @@ -14114,49 +14744,20 @@ } } }); }); define("ember-runtime/mixins/deferred", - ["ember-metal/core","ember-metal/property_get","ember-metal/mixin","ember-metal/computed","ember-metal/run_loop","ember-runtime/ext/rsvp","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) { + ["ember-metal/core","ember-metal/property_get","ember-metal/mixin","ember-metal/computed","ember-runtime/ext/rsvp","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; // Ember.FEATURES, Ember.Test var get = __dependency2__.get; var Mixin = __dependency3__.Mixin; var computed = __dependency4__.computed; - var run = __dependency5__["default"]; - var RSVP = __dependency6__["default"]; + var RSVP = __dependency5__["default"]; - var asyncStart = function() { - if (Ember.Test && Ember.Test.adapter) { - Ember.Test.adapter.asyncStart(); - } - }; - - var asyncEnd = function() { - if (Ember.Test && Ember.Test.adapter) { - Ember.Test.adapter.asyncEnd(); - } - }; - - RSVP.configure('async', function(callback, promise) { - var async = !run.currentRunLoop; - - if (Ember.testing && async) { asyncStart(); } - - run.backburner.schedule('actions', function(){ - if (Ember.testing && async) { asyncEnd(); } - callback(promise); - }); - }); - - RSVP.Promise.prototype.fail = function(callback, label){ - Ember.deprecate('RSVP.Promise.fail has been renamed as RSVP.Promise.catch'); - return this['catch'](callback, label); - }; - /** @module ember @submodule ember-runtime */ @@ -14664,13 +15265,13 @@ @param {String} key the property to test @param {String} [value] optional value to test against. @return {Array} rejected array */ rejectBy: function(key, value) { - var exactValue = function(item) { return get(item, key) === value; }, - hasValue = function(item) { return !!get(item, key); }, - use = (arguments.length === 2 ? exactValue : hasValue); + var exactValue = function(item) { return get(item, key) === value; }; + var hasValue = function(item) { return !!get(item, key); }; + var use = (arguments.length === 2 ? exactValue : hasValue); return this.reject(use); }, /** @@ -14863,15 +15464,15 @@ @param {Function} callback The callback to execute @param {Object} [target] The target object to use @return {Boolean} `true` if the passed function returns `true` for any item */ any: function(callback, target) { - var len = get(this, 'length'), - context = popCtx(), - found = false, - last = null, - next, idx; + var len = get(this, 'length'); + var context = popCtx(); + var found = false; + var last = null; + var next, idx; if (target === undefined) { target = null; } for (idx = 0; idx < len && !found; idx++) { next = this.nextObject(idx, last, context); @@ -15120,14 +15721,14 @@ @param {Object} target @param {Hash} [opts] @return this */ addEnumerableObserver: function(target, opts) { - var willChange = (opts && opts.willChange) || 'enumerableWillChange', - didChange = (opts && opts.didChange) || 'enumerableDidChange'; - + var willChange = (opts && opts.willChange) || 'enumerableWillChange'; + var didChange = (opts && opts.didChange) || 'enumerableDidChange'; var hasObservers = get(this, 'hasEnumerableObservers'); + if (!hasObservers) propertyWillChange(this, 'hasEnumerableObservers'); addListener(this, '@enumerable:before', target, willChange); addListener(this, '@enumerable:change', target, didChange); if (!hasObservers) propertyDidChange(this, 'hasEnumerableObservers'); return this; @@ -15140,12 +15741,12 @@ @param {Object} target @param {Hash} [opts] @return this */ removeEnumerableObserver: function(target, opts) { - var willChange = (opts && opts.willChange) || 'enumerableWillChange', - didChange = (opts && opts.didChange) || 'enumerableDidChange'; + var willChange = (opts && opts.willChange) || 'enumerableWillChange'; + var didChange = (opts && opts.didChange) || 'enumerableDidChange'; var hasObservers = get(this, 'hasEnumerableObservers'); if (hasObservers) propertyWillChange(this, 'hasEnumerableObservers'); removeListener(this, '@enumerable:before', target, willChange); removeListener(this, '@enumerable:change', target, didChange); @@ -15251,13 +15852,13 @@ */ sortBy: function() { var sortKeys = arguments; return this.toArray().sort(function(a, b){ for(var i = 0; i < sortKeys.length; i++) { - var key = sortKeys[i], - propA = get(a, key), - propB = get(b, key); + var key = sortKeys[i]; + var propA = get(a, key); + var propB = get(b, key); // return 1 or -1 else continue to the next sortKey var compareValue = compare(propA, propB); if (compareValue) { return compareValue; } } return 0; @@ -16504,15 +17105,15 @@ return observersFor(this, keyName); } }); }); define("ember-runtime/mixins/promise_proxy", - ["ember-metal/property_get","ember-metal/property_set","ember-metal/computed","ember-metal/mixin","ember-metal/error","exports"], + ["ember-metal/property_get","ember-metal/set_properties","ember-metal/computed","ember-metal/mixin","ember-metal/error","exports"], function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) { "use strict"; var get = __dependency1__.get; - var set = __dependency2__.set; + var setProperties = __dependency2__["default"]; var computed = __dependency3__.computed; var Mixin = __dependency4__.Mixin; var EmberError = __dependency5__["default"]; var not = computed.not; @@ -16522,20 +17123,26 @@ @module ember @submodule ember-runtime */ function tap(proxy, promise) { - set(proxy, 'isFulfilled', false); - set(proxy, 'isRejected', false); + setProperties(proxy, { + isFulfilled: false, + isRejected: false + }); return promise.then(function(value) { - set(proxy, 'isFulfilled', true); - set(proxy, 'content', value); + setProperties(proxy, { + content: value, + isFulfilled: true + }); return value; }, function(reason) { - set(proxy, 'isRejected', true); - set(proxy, 'reason', reason); + setProperties(proxy, { + reason: reason, + isRejected: true + }); throw reason; }, "Ember: PromiseProxy"); } /** @@ -16833,14 +17440,14 @@ @default Ember.compare */ sortFunction: compare, orderBy: function(item1, item2) { - var result = 0, - sortProperties = get(this, 'sortProperties'), - sortAscending = get(this, 'sortAscending'), - sortFunction = get(this, 'sortFunction'); + var result = 0; + var sortProperties = get(this, 'sortProperties'); + var sortAscending = get(this, 'sortAscending'); + var sortFunction = get(this, 'sortFunction'); Ember.assert("you need to define `sortProperties`", !!sortProperties); forEach(sortProperties, function(propertyName) { if (result === 0) { @@ -16853,12 +17460,12 @@ return result; }, destroy: function() { - var content = get(this, 'content'), - sortProperties = get(this, 'sortProperties'); + var content = get(this, 'content'); + var sortProperties = get(this, 'sortProperties'); if (content && sortProperties) { forEach(content, function(item) { forEach(sortProperties, function(sortProperty) { removeObserver(item, sortProperty, this, 'contentItemSortPropertyDidChange'); @@ -16877,14 +17484,14 @@ @property arrangedContent */ arrangedContent: computed('content', 'sortProperties.@each', function(key, value) { - var content = get(this, 'content'), - isSorted = get(this, 'isSorted'), - sortProperties = get(this, 'sortProperties'), - self = this; + var content = get(this, 'content'); + var isSorted = get(this, 'isSorted'); + var sortProperties = get(this, 'sortProperties'); + var self = this; if (content && isSorted) { content = content.slice(); content.sort(function(item1, item2) { return self.orderBy(item1, item2); @@ -16899,12 +17506,12 @@ return content; }), _contentWillChange: beforeObserver('content', function() { - var content = get(this, 'content'), - sortProperties = get(this, 'sortProperties'); + var content = get(this, 'content'); + var sortProperties = get(this, 'sortProperties'); if (content && sortProperties) { forEach(content, function(item) { forEach(sortProperties, function(sortProperty) { removeObserver(item, sortProperty, this, 'contentItemSortPropertyDidChange'); @@ -16953,12 +17560,12 @@ return this._super(array, idx, removedCount, addedCount); }, contentArrayDidChange: function(array, idx, removedCount, addedCount) { - var isSorted = get(this, 'isSorted'), - sortProperties = get(this, 'sortProperties'); + var isSorted = get(this, 'isSorted'); + var sortProperties = get(this, 'sortProperties'); if (isSorted) { var addedObjects = array.slice(idx, idx+addedCount); forEach(addedObjects, function(item) { @@ -16980,16 +17587,16 @@ var idx = this._binarySearch(item, 0, length); arrangedContent.insertAt(idx, item); }, contentItemSortPropertyDidChange: function(item) { - var arrangedContent = get(this, 'arrangedContent'), - oldIndex = arrangedContent.indexOf(item), - leftItem = arrangedContent.objectAt(oldIndex - 1), - rightItem = arrangedContent.objectAt(oldIndex + 1), - leftResult = leftItem && this.orderBy(item, leftItem), - rightResult = rightItem && this.orderBy(item, rightItem); + var arrangedContent = get(this, 'arrangedContent'); + var oldIndex = arrangedContent.indexOf(item); + var leftItem = arrangedContent.objectAt(oldIndex - 1); + var rightItem = arrangedContent.objectAt(oldIndex + 1); + var leftResult = leftItem && this.orderBy(item, leftItem); + var rightResult = rightItem && this.orderBy(item, rightItem); if (leftResult < 0 || rightResult > 0) { arrangedContent.removeObject(item); this.insertItemSorted(item); } @@ -17131,13 +17738,13 @@ @param opts {Hash} (optional, with the optional keys action, target and/or actionContext) @return {Boolean} true if the action was sent successfully and did not return false */ triggerAction: function(opts) { opts = opts || {}; - var action = opts.action || get(this, 'action'), - target = opts.target || get(this, 'targetObject'), - actionContext = opts.actionContext; + var action = opts.action || get(this, 'action'); + var target = opts.target || get(this, 'targetObject'); + var actionContext = opts.actionContext; function args(options, actionName) { var ret = []; if (actionName) { ret.push(actionName); } @@ -17319,11 +17926,32 @@ didChange: 'contentArrayDidChange' }); } }, + /** + Override to implement content array `willChange` observer. + + @method contentArrayWillChange + + @param {Ember.Array} contentArray the content array + @param {Number} start starting index of the change + @param {Number} removeCount count of items removed + @param {Number} addCount count of items added + + */ contentArrayWillChange: K, + /** + Override to implement content array `didChange` observer. + + @method contentArrayDidChange + + @param {Ember.Array} contentArray the content array + @param {Number} start starting index of the change + @param {Number} removeCount count of items removed + @param {Number} addCount count of items added + */ contentArrayDidChange: K, /** Invoked when the content property changes. Notifies observers that the entire array content has changed. @@ -17353,22 +17981,22 @@ }); } }, _arrangedContentWillChange: beforeObserver('arrangedContent', function() { - var arrangedContent = get(this, 'arrangedContent'), - len = arrangedContent ? get(arrangedContent, 'length') : 0; + var arrangedContent = get(this, 'arrangedContent'); + var len = arrangedContent ? get(arrangedContent, 'length') : 0; this.arrangedContentArrayWillChange(this, 0, len, undefined); this.arrangedContentWillChange(this); this._teardownArrangedContent(arrangedContent); }), _arrangedContentDidChange: observer('arrangedContent', function() { - var arrangedContent = get(this, 'arrangedContent'), - len = arrangedContent ? get(arrangedContent, 'length') : 0; + var arrangedContent = get(this, 'arrangedContent'); + var len = arrangedContent ? get(arrangedContent, 'length') : 0; Ember.assert("Can't set ArrayProxy's content to itself", arrangedContent !== this); this._setupArrangedContent(); @@ -17444,13 +18072,14 @@ } }, removeAt: function(start, len) { if ('number' === typeof start) { - var content = get(this, 'content'), - arrangedContent = get(this, 'arrangedContent'), - indices = [], i; + var content = get(this, 'content'); + var arrangedContent = get(this, 'arrangedContent'); + var indices = []; + var i; if ((start < 0) || (start >= get(this, 'length'))) { throw new EmberError(OUT_OF_RANGE_EXCEPTION); } @@ -17543,11 +18172,11 @@ Container.set = set; __exports__["default"] = Container; }); define("ember-runtime/system/core_object", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/platform","ember-metal/watching","ember-metal/chains","ember-metal/events","ember-metal/mixin","ember-metal/enumerable_utils","ember-metal/error","ember-runtime/keys","ember-runtime/mixins/action_handler","ember-metal/properties","ember-metal/binding","ember-metal/computed","ember-metal/run_loop","exports"], + ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/platform","ember-metal/watching","ember-metal/chains","ember-metal/events","ember-metal/mixin","ember-metal/enumerable_utils","ember-metal/error","ember-metal/keys","ember-runtime/mixins/action_handler","ember-metal/properties","ember-metal/binding","ember-metal/computed","ember-metal/run_loop","exports"], function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __exports__) { "use strict"; /** @module ember @submodule ember-runtime @@ -17564,11 +18193,10 @@ var apply = __dependency4__.apply; var o_create = __dependency5__.create; var generateGuid = __dependency4__.generateGuid; var GUID_KEY = __dependency4__.GUID_KEY; var meta = __dependency4__.meta; - var META_KEY = __dependency4__.META_KEY; var makeArray = __dependency4__.makeArray; var rewatch = __dependency6__.rewatch; var finishChains = __dependency7__.finishChains; var sendEvent = __dependency8__.sendEvent; var IS_BINDING = __dependency9__.IS_BINDING; @@ -17612,19 +18240,21 @@ // Note: avoid accessing any properties on the object since it makes the // method a lot faster. This is glue code so we want it to be as fast as // possible. - var wasApplied = false, initMixins, initProperties; + var wasApplied = false; + var initMixins, initProperties; var Class = function() { if (!wasApplied) { Class.proto(); // prepare prototype... } o_defineProperty(this, GUID_KEY, nullDescriptor); o_defineProperty(this, '__nextSuper', undefinedDescriptor); - var m = meta(this), proto = m.proto; + var m = meta(this); + var proto = m.proto; m.proto = this; if (initMixins) { // capture locally so we can clear the closed over variable var mixins = initMixins; initMixins = null; @@ -17746,11 +18376,10 @@ @class CoreObject @namespace Ember */ var CoreObject = makeCtor(); CoreObject.toString = function() { return "Ember.CoreObject"; }; - CoreObject.PrototypeMixin = Mixin.create({ reopen: function() { var length = arguments.length; var args = new Array(length); for (var i = 0; i < length; i++) { @@ -17963,13 +18592,14 @@ @method toString @return {String} string representation */ toString: function toString() { - var hasToStringExtension = typeof this.toStringExtension === 'function', - extension = hasToStringExtension ? ":" + this.toStringExtension() : ''; + var hasToStringExtension = typeof this.toStringExtension === 'function'; + var extension = hasToStringExtension ? ":" + this.toStringExtension() : ''; var ret = '<'+this.constructor.toString()+':'+guidFor(this)+extension+'>'; + this.toString = makeToString(ret); return ret; } }); @@ -18073,12 +18703,13 @@ @static @param {Mixin} [mixins]* One or more Mixin classes @param {Object} [arguments]* Object containing values to use within the new class */ - extend: function() { - var Class = makeCtor(), proto; + extend: function extend() { + var Class = makeCtor(); + var proto; Class.ClassMixin = Mixin.create(this.ClassMixin); Class.PrototypeMixin = Mixin.create(this.PrototypeMixin); Class.ClassMixin.ownerConstructor = Class; Class.PrototypeMixin.ownerConstructor = Class; @@ -18320,12 +18951,12 @@ @method metaForProperty @param key {String} property name */ metaForProperty: function(key) { - var meta = this.proto()[META_KEY], - desc = meta && meta.descs[key]; + var meta = this.proto()['__ember_meta__']; + var desc = meta && meta.descs[key]; Ember.assert("metaForProperty() could not find a computed property with key '"+key+"'.", !!desc && desc instanceof ComputedProperty); return desc._meta || {}; }, @@ -18481,11 +19112,12 @@ }); var IS_OBSERVER = /^.+:(before|change)$/; function addObserverForContentKey(content, keyName, proxy, idx, loc) { - var objects = proxy._objects, guid; + var objects = proxy._objects; + var guid; if (!objects) objects = proxy._objects = {}; while(--loc>=idx) { var item = content.objectAt(loc); if (item) { @@ -18563,11 +19195,12 @@ // .......................................................... // ARRAY CHANGES // Invokes whenever the content array itself changes. arrayWillChange: function(content, idx, removedCnt, addedCnt) { - var keys = this._keys, key, lim; + var keys = this._keys; + var key, lim; lim = removedCnt>0 ? idx+removedCnt : -1; beginPropertyChanges(this); for(key in keys) { @@ -18581,11 +19214,12 @@ propertyWillChange(this._content, '@each'); endPropertyChanges(this); }, arrayDidChange: function(content, idx, removedCnt, addedCnt) { - var keys = this._keys, lim; + var keys = this._keys; + var lim; lim = addedCnt>0 ? idx+addedCnt : -1; changeProperties(function() { for(var key in keys) { if (!keys.hasOwnProperty(key)) { continue; } @@ -18622,23 +19256,25 @@ beginObservingContentKey: function(keyName) { var keys = this._keys; if (!keys) keys = this._keys = {}; if (!keys[keyName]) { keys[keyName] = 1; - var content = this._content, - len = get(content, 'length'); + var content = this._content; + var len = get(content, 'length'); + addObserverForContentKey(content, keyName, this, 0, len); } else { keys[keyName]++; } }, stopObservingContentKey: function(keyName) { var keys = this._keys; if (keys && (keys[keyName]>0) && (--keys[keyName]<=0)) { - var content = this._content, - len = get(content, 'length'); + var content = this._content; + var len = get(content, 'length'); + removeObserverForContentKey(content, keyName, this, 0, len); } }, contentKeyWillChange: function(obj, keyName) { @@ -18782,12 +19418,12 @@ nameClasses: function() { processNamespace([this.toString()], this, {}); }, destroy: function() { - var namespaces = Namespace.NAMESPACES, - toString = this.toString(); + var namespaces = Namespace.NAMESPACES; + var toString = this.toString(); if (toString) { Ember.lookup[toString] = undefined; delete Namespace.NAMESPACES_BY_ID[toString]; } @@ -18862,11 +19498,12 @@ // continue } } function findNamespaces() { - var lookup = Ember.lookup, obj, isNamespace; + var lookup = Ember.lookup; + var obj, isNamespace; if (Namespace.PROCESSED) { return; } for (var prop in lookup) { // Only process entities that start with uppercase A-Z @@ -18919,20 +19556,22 @@ return ret; } function processAllNamespaces() { - var unprocessedNamespaces = !Namespace.PROCESSED, - unprocessedMixins = Ember.anyUnprocessedMixins; + var unprocessedNamespaces = !Namespace.PROCESSED; + var unprocessedMixins = Ember.anyUnprocessedMixins; if (unprocessedNamespaces) { findNamespaces(); Namespace.PROCESSED = true; } if (unprocessedNamespaces || unprocessedMixins) { - var namespaces = Namespace.NAMESPACES, namespace; + var namespaces = Namespace.NAMESPACES; + var namespace; + for (var i=0, l=namespaces.length; i<l; i++) { namespace = namespaces[i]; processNamespace([namespace.toString()], namespace, {}); } @@ -18947,12 +19586,12 @@ Mixin.prototype.toString = classToString; // ES6TODO: altering imported objects. SBB. __exports__["default"] = Namespace; }); define("ember-runtime/system/native_array", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/enumerable_utils","ember-metal/mixin","ember-runtime/mixins/array","ember-runtime/mixins/mutable_array","ember-runtime/mixins/observable","ember-runtime/mixins/copyable","ember-runtime/mixins/freezable","ember-runtime/copy","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __exports__) { + ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/enumerable_utils","ember-metal/mixin","ember-metal/array","ember-runtime/mixins/array","ember-runtime/mixins/mutable_array","ember-runtime/mixins/observable","ember-runtime/mixins/copyable","ember-runtime/mixins/freezable","ember-runtime/copy","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __exports__) { "use strict"; /** @module ember @submodule ember-runtime */ @@ -18963,16 +19602,18 @@ var get = __dependency2__.get; var set = __dependency3__.set; var replace = __dependency4__._replace; var forEach = __dependency4__.forEach; var Mixin = __dependency5__.Mixin; - var EmberArray = __dependency6__["default"]; - var MutableArray = __dependency7__["default"]; - var Observable = __dependency8__["default"]; - var Copyable = __dependency9__["default"]; - var FROZEN_ERROR = __dependency10__.FROZEN_ERROR; - var copy = __dependency11__["default"]; + var indexOf = __dependency6__.indexOf; + var lastIndexOf = __dependency6__.lastIndexOf; + var EmberArray = __dependency7__["default"]; + var MutableArray = __dependency8__["default"]; + var Observable = __dependency9__["default"]; + var Copyable = __dependency10__["default"]; + var FROZEN_ERROR = __dependency11__.FROZEN_ERROR; + var copy = __dependency12__["default"]; // Add Ember.Array to Array.prototype. Remove methods with native // implementations and supply some more optimized versions of generic methods // because they are so common. @@ -19026,44 +19667,20 @@ // If you ask for an unknown property, then try to collect the value // from member items. unknownProperty: function(key, value) { var ret;// = this.reducedProperty(key, value) ; - if ((value !== undefined) && ret === undefined) { + if (value !== undefined && ret === undefined) { ret = this[key] = value; } - return ret ; + return ret; }, - // If browser did not implement indexOf natively, then override with - // specialized version - indexOf: function(object, startAt) { - var idx, len = this.length; + indexOf: indexOf, - if (startAt === undefined) startAt = 0; - else startAt = (startAt < 0) ? Math.ceil(startAt) : Math.floor(startAt); - if (startAt < 0) startAt += len; + lastIndexOf: lastIndexOf, - for(idx=startAt;idx<len;idx++) { - if (this[idx] === object) return idx ; - } - return -1; - }, - - lastIndexOf: function(object, startAt) { - var idx, len = this.length; - - if (startAt === undefined) startAt = len-1; - else startAt = (startAt < 0) ? Math.ceil(startAt) : Math.floor(startAt); - if (startAt < 0) startAt += len; - - for(idx=startAt;idx>=0;idx--) { - if (this[idx] === object) return idx ; - } - return -1; - }, - copy: function(deep) { if (deep) { return this.map(function(item) { return copy(item, true); }); } @@ -19075,11 +19692,11 @@ var ignore = ['length']; forEach(NativeArray.keys(), function(methodName) { if (Array.prototype[methodName]) ignore.push(methodName); }); - if (ignore.length>0) { + if (ignore.length > 0) { NativeArray = NativeArray.without.apply(NativeArray, ignore); } /** Creates an `Ember.NativeArray` from an Array like object. @@ -19176,46 +19793,16 @@ }; __exports__["default"] = EmberObject; }); define("ember-runtime/system/object_proxy", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/observer","ember-metal/property_events","ember-metal/computed","ember-metal/properties","ember-metal/mixin","ember-runtime/system/string","ember-runtime/system/object","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __exports__) { + ["ember-runtime/system/object","ember-runtime/mixins/-proxy","exports"], + function(__dependency1__, __dependency2__, __exports__) { "use strict"; - /** - @module ember - @submodule ember-runtime - */ - var Ember = __dependency1__["default"]; - // Ember.assert - var get = __dependency2__.get; - var set = __dependency3__.set; - var meta = __dependency4__.meta; - var addObserver = __dependency5__.addObserver; - var removeObserver = __dependency5__.removeObserver; - var addBeforeObserver = __dependency5__.addBeforeObserver; - var removeBeforeObserver = __dependency5__.removeBeforeObserver; - var propertyWillChange = __dependency6__.propertyWillChange; - var propertyDidChange = __dependency6__.propertyDidChange; - var computed = __dependency7__.computed; - var defineProperty = __dependency8__.defineProperty; - var observer = __dependency9__.observer; - var fmt = __dependency10__.fmt; - var EmberObject = __dependency11__["default"]; + var EmberObject = __dependency1__["default"]; + var _ProxyMixin = __dependency2__["default"]; - function contentPropertyWillChange(content, contentKey) { - var key = contentKey.slice(8); // remove "content." - if (key in this) { return; } // if shadowed in proxy - propertyWillChange(this, key); - } - - function contentPropertyDidChange(content, contentKey) { - var key = contentKey.slice(8); // remove "content." - if (key in this) { return; } // if shadowed in proxy - propertyDidChange(this, key); - } - /** `Ember.ObjectProxy` forwards all properties not defined by the proxy itself to a proxied `content` object. ```javascript @@ -19278,75 +19865,25 @@ ``` @class ObjectProxy @namespace Ember @extends Ember.Object + @extends Ember._ProxyMixin */ - var ObjectProxy = EmberObject.extend({ - /** - The object whose properties will be forwarded. - @property content - @type Ember.Object - @default null - */ - content: null, - _contentDidChange: observer('content', function() { - Ember.assert("Can't set ObjectProxy's content to itself", get(this, 'content') !== this); - }), - - isTruthy: computed.bool('content'), - - _debugContainerKey: null, - - willWatchProperty: function (key) { - var contentKey = 'content.' + key; - addBeforeObserver(this, contentKey, null, contentPropertyWillChange); - addObserver(this, contentKey, null, contentPropertyDidChange); - }, - - didUnwatchProperty: function (key) { - var contentKey = 'content.' + key; - removeBeforeObserver(this, contentKey, null, contentPropertyWillChange); - removeObserver(this, contentKey, null, contentPropertyDidChange); - }, - - unknownProperty: function (key) { - var content = get(this, 'content'); - if (content) { - return get(content, key); - } - }, - - setUnknownProperty: function (key, value) { - var m = meta(this); - if (m.proto === this) { - // if marked as prototype then just defineProperty - // rather than delegate - defineProperty(this, key, null, value); - return value; - } - - var content = get(this, 'content'); - Ember.assert(fmt("Cannot delegate set('%@', %@) to the 'content' property of object proxy %@: its 'content' is undefined.", [key, value, this]), content); - return set(content, key, value); - } - - }); - - __exports__["default"] = ObjectProxy; + __exports__["default"] = EmberObject.extend(_ProxyMixin); }); define("ember-runtime/system/set", ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/is_none","ember-runtime/system/string","ember-runtime/system/core_object","ember-runtime/mixins/mutable_enumerable","ember-runtime/mixins/enumerable","ember-runtime/mixins/copyable","ember-runtime/mixins/freezable","ember-metal/error","ember-metal/property_events","ember-metal/mixin","ember-metal/computed","exports"], function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __exports__) { "use strict"; /** @module ember @submodule ember-runtime */ var Ember = __dependency1__["default"]; - // Ember.isNone + // Ember.isNone, Ember.A var get = __dependency2__.get; var set = __dependency3__.set; var guidFor = __dependency4__.guidFor; var isNone = __dependency5__.isNone; @@ -19694,10 +20231,11 @@ // .......................................................... // PRIVATE ENUMERABLE SUPPORT // init: function(items) { + Ember.deprecate('Ember.Set is deprecated and will be removed in a future release.'); this._super(); if (items) this.addObjects(items); }, // implement Ember.Enumerable @@ -19718,14 +20256,14 @@ // implements Ember.MutableEnumerable addObject: function(obj) { if (get(this, 'isFrozen')) throw new EmberError(FROZEN_ERROR); if (isNone(obj)) return this; // nothing to do - var guid = guidFor(obj), - idx = this[guid], - len = get(this, 'length'), - added ; + var guid = guidFor(obj); + var idx = this[guid]; + var len = get(this, 'length'); + var added; if (idx>=0 && idx<len && (this[idx] === obj)) return this; // added added = [obj]; @@ -19746,16 +20284,16 @@ // implements Ember.MutableEnumerable removeObject: function(obj) { if (get(this, 'isFrozen')) throw new EmberError(FROZEN_ERROR); if (isNone(obj)) return this; // nothing to do - var guid = guidFor(obj), - idx = this[guid], - len = get(this, 'length'), - isFirst = idx === 0, - isLast = idx === len-1, - last, removed; + var guid = guidFor(obj); + var idx = this[guid]; + var len = get(this, 'length'); + var isFirst = idx === 0; + var isLast = idx === len-1; + var last, removed; if (idx>=0 && idx<len && (this[idx] === obj)) { removed = [obj]; @@ -19805,39 +20343,84 @@ return fmt("Ember.Set<%@>", [array.join(',')]); } }); }); define("ember-runtime/system/string", - ["ember-metal/core","ember-metal/utils","exports"], - function(__dependency1__, __dependency2__, __exports__) { + ["ember-metal/core","ember-metal/utils","ember-metal/cache","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __exports__) { "use strict"; /** @module ember @submodule ember-runtime */ var Ember = __dependency1__["default"]; // Ember.STRINGS, Ember.FEATURES var isArray = __dependency2__.isArray; var emberInspect = __dependency2__.inspect; + var Cache = __dependency3__["default"]; + var STRING_DASHERIZE_REGEXP = (/[ _]/g); - var STRING_DASHERIZE_CACHE = {}; + + var STRING_DASHERIZE_CACHE = new Cache(1000, function(key) { + return decamelize(key).replace(STRING_DASHERIZE_REGEXP, '-'); + }); + + var CAMELIZE_CACHE = new Cache(1000, function(key) { + return key.replace(STRING_CAMELIZE_REGEXP, function(match, separator, chr) { + return chr ? chr.toUpperCase() : ''; + }).replace(/^([A-Z])/, function(match, separator, chr) { + return match.toLowerCase(); + }); + }); + + var CLASSIFY_CACHE = new Cache(1000, function(str) { + var parts = str.split("."); + var out = []; + + for (var i=0, l=parts.length; i<l; i++) { + var camelized = camelize(parts[i]); + out.push(camelized.charAt(0).toUpperCase() + camelized.substr(1)); + } + + return out.join("."); + }); + + var UNDERSCORE_CACHE = new Cache(1000, function(str) { + return str.replace(STRING_UNDERSCORE_REGEXP_1, '$1_$2'). + replace(STRING_UNDERSCORE_REGEXP_2, '_').toLowerCase(); + }); + + var CAPITALIZE_CACHE = new Cache(1000, function(str) { + return str.charAt(0).toUpperCase() + str.substr(1); + }); + + var DECAMELIZE_CACHE = new Cache(1000, function(str) { + return str.replace(STRING_DECAMELIZE_REGEXP, '$1_$2').toLowerCase(); + }); + var STRING_DECAMELIZE_REGEXP = (/([a-z\d])([A-Z])/g); var STRING_CAMELIZE_REGEXP = (/(\-|_|\.|\s)+(.)?/g); var STRING_UNDERSCORE_REGEXP_1 = (/([a-z\d])([A-Z]+)/g); var STRING_UNDERSCORE_REGEXP_2 = (/\-|\s+/g); function fmt(str, formats) { - if (!isArray(formats) || arguments.length > 2) { - formats = Array.prototype.slice.call(arguments, 1); + var cachedFormats = formats; + + if (!isArray(cachedFormats) || arguments.length > 2) { + cachedFormats = new Array(arguments.length - 1); + + for (var i = 1, l = arguments.length; i < l; i++) { + cachedFormats[i - 1] = arguments[i]; + } } // first, replace any ORDERED replacements. var idx = 0; // the current index for non-numerical replacements return str.replace(/%@([0-9]+)?/g, function(s, argIndex) { argIndex = (argIndex) ? parseInt(argIndex, 10) - 1 : idx++; - s = formats[argIndex]; + s = cachedFormats[argIndex]; return (s === null) ? '(null)' : (s === undefined) ? '' : emberInspect(s); }); } function loc(str, formats) { @@ -19852,55 +20435,31 @@ function w(str) { return str.split(/\s+/); } function decamelize(str) { - return str.replace(STRING_DECAMELIZE_REGEXP, '$1_$2').toLowerCase(); + return DECAMELIZE_CACHE.get(str); } function dasherize(str) { - var cache = STRING_DASHERIZE_CACHE, - hit = cache.hasOwnProperty(str), - ret; - - if (hit) { - return cache[str]; - } else { - ret = decamelize(str).replace(STRING_DASHERIZE_REGEXP,'-'); - cache[str] = ret; - } - - return ret; + return STRING_DASHERIZE_CACHE.get(str); } function camelize(str) { - return str.replace(STRING_CAMELIZE_REGEXP, function(match, separator, chr) { - return chr ? chr.toUpperCase() : ''; - }).replace(/^([A-Z])/, function(match, separator, chr) { - return match.toLowerCase(); - }); + return CAMELIZE_CACHE.get(str); } function classify(str) { - var parts = str.split("."), - out = []; - - for (var i=0, l=parts.length; i<l; i++) { - var camelized = camelize(parts[i]); - out.push(camelized.charAt(0).toUpperCase() + camelized.substr(1)); - } - - return out.join("."); + return CLASSIFY_CACHE.get(str); } function underscore(str) { - return str.replace(STRING_UNDERSCORE_REGEXP_1, '$1_$2'). - replace(STRING_UNDERSCORE_REGEXP_2, '_').toLowerCase(); + return UNDERSCORE_CACHE.get(str); } function capitalize(str) { - return str.charAt(0).toUpperCase() + str.substr(1); + return CAPITALIZE_CACHE.get(str); } /** Defines the hash of localized strings for the current language. Used by the `Ember.String.loc()` helper. To localize, add string values to this @@ -20141,19 +20700,19 @@ /** Track that an item was added to the tracked array. @method addItem - @param {number} index The index of the item in the tracked array. - @param {boolean} match `true` iff the item is included in the subarray. + @param {Number} index The index of the item in the tracked array. + @param {Boolean} match `true` iff the item is included in the subarray. @return {number} The index of the item in the subarray. */ addItem: function(index, match) { - var returnValue = -1, - itemType = match ? RETAIN : FILTER, - self = this; + var returnValue = -1; + var itemType = match ? RETAIN : FILTER; + var self = this; this._findOperation(index, function(operation, operationIndex, rangeStart, rangeEnd, seenInSubArray) { var newOperation, splitOperation; if (itemType === operation.type) { @@ -20194,18 +20753,18 @@ /** Track that an item was removed from the tracked array. @method removeItem - @param {number} index The index of the item in the tracked array. + @param {Number} index The index of the item in the tracked array. @return {number} The index of the item in the subarray, or `-1` if the item was not in the subarray. */ removeItem: function(index) { - var returnValue = -1, - self = this; + var returnValue = -1; + var self = this; this._findOperation(index, function (operation, operationIndex, rangeStart, rangeEnd, seenInSubArray) { if (operation.type === RETAIN) { returnValue = seenInSubArray + (index - rangeStart); } @@ -20223,16 +20782,12 @@ return returnValue; }, _findOperation: function (index, foundCallback, notFoundCallback) { - var operationIndex, - len, - operation, - rangeStart, - rangeEnd, - seenInSubArray = 0; + var seenInSubArray = 0; + var operationIndex, len, operation, rangeStart, rangeEnd; // OPTIMIZE: change to balanced tree // find leftmost operation to the right of `index` for (operationIndex = rangeStart = 0, len = this._operations.length; operationIndex < len; rangeStart = rangeEnd + 1, ++operationIndex) { operation = this._operations[operationIndex]; @@ -20248,12 +20803,12 @@ notFoundCallback(seenInSubArray); }, _composeAt: function(index) { - var op = this._operations[index], - otherOp; + var op = this._operations[index]; + var otherOp; if (!op) { // Composing out of bounds is a no-op, as when removing the last operation // in the list. return; @@ -20304,11 +20859,11 @@ lazily compute the indexes of items in an array after they've been shifted by subsequent operations. @class TrackedArray @namespace Ember - @param {array} [items=[]] The array to be tracked. This is used just to get + @param {Array} [items=[]] The array to be tracked. This is used just to get the initial items for the starting state of retain:n. */ function TrackedArray(items) { if (arguments.length < 1) { items = []; } @@ -20336,19 +20891,15 @@ */ addItems: function (index, newItems) { var count = get(newItems, 'length'); if (count < 1) { return; } - var match = this._findArrayOperation(index), - arrayOperation = match.operation, - arrayOperationIndex = match.index, - arrayOperationRangeStart = match.rangeStart, - composeIndex, - splitIndex, - splitItems, - splitArrayOperation, - newArrayOperation; + var match = this._findArrayOperation(index); + var arrayOperation = match.operation; + var arrayOperationIndex = match.index; + var arrayOperationRangeStart = match.rangeStart; + var composeIndex, splitIndex, splitItems, splitArrayOperation, newArrayOperation; newArrayOperation = new ArrayOperation(INSERT, count, newItems); if (arrayOperation) { if (!match.split) { @@ -20376,16 +20927,15 @@ @param count */ removeItems: function (index, count) { if (count < 1) { return; } - var match = this._findArrayOperation(index), - arrayOperation = match.operation, - arrayOperationIndex = match.index, - arrayOperationRangeStart = match.rangeStart, - newArrayOperation, - composeIndex; + var match = this._findArrayOperation(index); + var arrayOperation = match.operation; + var arrayOperationIndex = match.index; + var arrayOperationRangeStart = match.rangeStart; + var newArrayOperation, composeIndex; newArrayOperation = new ArrayOperation(DELETE, count); if (!match.split) { // insert left of arrayOperation this._operations.splice(arrayOperationIndex, 0, newArrayOperation); @@ -20409,15 +20959,15 @@ array of the first item for this operation. * {string} operation The type of the operation. One of `Ember.TrackedArray.{RETAIN, DELETE, INSERT}` @method apply - @param {function} callback + @param {Function} callback */ apply: function (callback) { - var items = [], - offset = 0; + var items = []; + var offset = 0; forEach(this._operations, function (arrayOperation, operationIndex) { callback(arrayOperation.items, offset, arrayOperation.type, operationIndex); if (arrayOperation.type !== DELETE) { @@ -20432,21 +20982,19 @@ /** Return an `ArrayOperationMatch` for the operation that contains the item at `index`. @method _findArrayOperation - @param {number} index the index of the item whose operation information + @param {Number} index the index of the item whose operation information should be returned. @private */ _findArrayOperation: function (index) { - var arrayOperationIndex, - len, - split = false, - arrayOperation, - arrayOperationRangeStart, - arrayOperationRangeEnd; + var split = false; + var arrayOperationIndex, arrayOperation, + arrayOperationRangeStart, arrayOperationRangeEnd, + len; // OPTIMIZE: we could search these faster if we kept a balanced tree. // find leftmost arrayOperation to the right of `index` for (arrayOperationIndex = arrayOperationRangeStart = 0, len = this._operations.length; arrayOperationIndex < len; ++arrayOperationIndex) { arrayOperation = this._operations[arrayOperationIndex]; @@ -20480,15 +21028,15 @@ this._operations.splice(arrayOperationIndex + 1, 0, newArrayOperation, splitArrayOperation); }, // see SubArray for a better implementation. _composeInsert: function (index) { - var newArrayOperation = this._operations[index], - leftArrayOperation = this._operations[index-1], // may be undefined - rightArrayOperation = this._operations[index+1], // may be undefined - leftOp = leftArrayOperation && leftArrayOperation.type, - rightOp = rightArrayOperation && rightArrayOperation.type; + var newArrayOperation = this._operations[index]; + var leftArrayOperation = this._operations[index-1]; // may be undefined + var rightArrayOperation = this._operations[index+1]; // may be undefined + var leftOp = leftArrayOperation && leftArrayOperation.type; + var rightOp = rightArrayOperation && rightArrayOperation.type; if (leftOp === INSERT) { // merge left leftArrayOperation.count += newArrayOperation.count; leftArrayOperation.items = leftArrayOperation.items.concat(newArrayOperation.items); @@ -20509,19 +21057,19 @@ this._operations.splice(index + 1, 1); } }, _composeDelete: function (index) { - var arrayOperation = this._operations[index], - deletesToGo = arrayOperation.count, - leftArrayOperation = this._operations[index-1], // may be undefined - leftOp = leftArrayOperation && leftArrayOperation.type, - nextArrayOperation, - nextOp, - nextCount, - removeNewAndNextOp = false, - removedItems = []; + var arrayOperation = this._operations[index]; + var deletesToGo = arrayOperation.count; + var leftArrayOperation = this._operations[index-1]; // may be undefined + var leftOp = leftArrayOperation && leftArrayOperation.type; + var nextArrayOperation; + var nextOp; + var nextCount; + var removeNewAndNextOp = false; + var removedItems = []; if (leftOp === DELETE) { arrayOperation = leftArrayOperation; index -= 1; } @@ -20590,14 +21138,14 @@ /** Internal data structure to represent an array operation. @method ArrayOperation @private - @param {string} type The type of the operation. One of + @param {String} type The type of the operation. One of `Ember.TrackedArray.{RETAIN, INSERT, DELETE}` - @param {number} count The number of items in this operation. - @param {array} items The items of the operation, if included. RETAIN and + @param {Number} count The number of items in this operation. + @param {Array} items The items of the operation, if included. RETAIN and INSERT include their items, DELETE does not. */ function ArrayOperation (operation, count, items) { this.type = operation; // RETAIN | INSERT | DELETE this.count = count; @@ -20609,13 +21157,13 @@ by item index. @method ArrayOperationMatch @private @param {ArrayOperation} operation - @param {number} index The index of `operation` in the array of operations. - @param {boolean} split Whether or not the item index searched for would + @param {Number} index The index of `operation` in the array of operations. + @param {Boolean} split Whether or not the item index searched for would require a split for a new operation type. - @param {number} rangeStart The index of the first item in the operation, + @param {Number} rangeStart The index of the first item in the operation, with respect to the tracked array. The index of the last item can be computed from `rangeStart` and `operation.count`. */ function ArrayOperationMatch(operation, index, split, rangeStart) { this.operation = operation; \ No newline at end of file