diff --git a/assets/scripts/vendor/ember.js b/assets/scripts/vendor/ember.js index 54e8739e..3ec5c65c 100644 --- a/assets/scripts/vendor/ember.js +++ b/assets/scripts/vendor/ember.js @@ -5,7 +5,7 @@ * 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.8.1 + * @version 1.9.0 */ (function() { @@ -14,6 +14,7 @@ var enifed, requireModule, eriuqer, requirejs, Ember; (function() { Ember = this.Ember = this.Ember || {}; if (typeof Ember === 'undefined') { Ember = {}; }; + function UNDEFINED() { } if (typeof Ember.__loader === 'undefined') { var registry = {}, seen = {}; @@ -23,7 +24,11 @@ var enifed, requireModule, eriuqer, requirejs, Ember; }; requirejs = eriuqer = requireModule = function(name) { - if (seen.hasOwnProperty(name)) { return seen[name]; } + var s = seen[name]; + + if (s !== undefined) { return seen[name]; } + if (s === UNDEFINED) { return undefined; } + seen[name] = {}; if (!registry[name]) { @@ -35,34 +40,37 @@ var enifed, requireModule, eriuqer, requirejs, Ember; var callback = mod.callback; var reified = []; var exports; + var length = deps.length; - for (var i=0, l=deps.length; i 0) { - method.apply(target, args); - } else { - method.call(target); - } - }, - - 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, errorRecordedForStack); - } - }, - flush: function() { var queues = this.queues; var queueNames = this.queueNames; @@ -699,85 +705,23 @@ enifed("backburner/deferred-action-queues", 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; while (queueNameIndex < numberOfQueues) { queueName = queueNames[queueNameIndex]; queue = queues[queueName]; - queueItems = queue._queueBeingFlushed = queue._queue.slice(); - queue._queue = []; - queue.targetQueues = Object.create(null); - 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; + var numberOfQueueItems = queue._queue.length; - if (numberOfQueueItems && before) { - before(); - } - - while (queueIndex < numberOfQueueItems) { - 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) { - // - // ** Attention intrepid developer ** - // - // To find out the stack of this task when it was scheduled onto - // the run loop, add the following to your app.js: - // - // Ember.run.backburner.DEBUG = true; // NOTE: This slows your app, don't leave it on in production. - // - // Once that is in place, when you are at a breakpoint and navigate - // here in the stack explorer, you can look at `errorRecordedForStack.stack`, - // which will be the captured stack when this job was scheduled. - // - invoke(target, method, args, onError, errorRecordedForStack); - } - - queueIndex += 4; - } - - queue._queueBeingFlushed = null; - if (numberOfQueueItems && after) { - after(); - } - - if ((priorQueueNameIndex = indexOfPriorQueueWithActions(this, queueNameIndex)) !== -1) { - queueNameIndex = priorQueueNameIndex; - } else { + if (numberOfQueueItems === 0) { queueNameIndex++; + } else { + queue.flush(false /* async */); + queueNameIndex = 0; } } } }; - function indexOfPriorQueueWithActions(daq, currentQueueIndex) { - var queueName, queue; - - for (var i = 0, l = currentQueueIndex; i <= l; i++) { - queueName = daq.queueNames[i]; - queue = daq.queues[queueName]; - if (queue._queue.length) { return i; } - } - - return -1; - } - __exports__["default"] = DeferredActionQueues; }); enifed("backburner/platform", @@ -795,9 +739,11 @@ enifed("backburner/platform", __exports__.needsIETryCatchFix = needsIETryCatchFix; }); enifed("backburner/queue", - ["exports"], - function(__exports__) { + ["./utils","exports"], + function(__dependency1__, __exports__) { "use strict"; + var isString = __dependency1__.isString; + function Queue(name, options, globalOptions) { this.name = name; this.globalOptions = globalOptions || {}; @@ -895,56 +841,89 @@ enifed("backburner/queue", }; }, - // TODO: remove me, only being used for Ember.run.sync - flush: function() { + 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, errorRecordedForStack) { + try { + if (args && args.length > 0) { + method.apply(target, args); + } else { + method.call(target); + } + } catch(error) { + onError(error, errorRecordedForStack); + } + }, + + flush: function(sync) { var queue = this._queue; + var length = queue.length; + + if (length === 0) { + return; + } + 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; + var onError = globalOptions.onError || (globalOptions.onErrorTarget && + globalOptions.onErrorTarget[globalOptions.onErrorMethod]); + var target, method, args, errorRecordedForStack; + var invoke = onError ? this.invokeWithOnError : this.invoke; this.targetQueues = Object.create(null); + var queueItems = this._queueBeingFlushed = this._queue.slice(); + this._queue = []; - if (l && before) { before(); } - for (i = 0; i < l; i += 4) { - target = queue[i]; - method = queue[i+1]; - args = queue[i+2]; - stack = queue[i+3]; // Debugging assistance + if (before) { + before(); + } - // TODO: error handling - if (args && args.length > 0) { - if (onError) { - try { - method.apply(target, args); - } catch (e) { - onError(e); - } - } else { - method.apply(target, args); - } - } else { - if (onError) { - try { - method.call(target); - } catch(e) { - onError(e); - } - } else { - method.call(target); - } + for (var i = 0; i < length; i += 4) { + target = queueItems[i]; + method = queueItems[i+1]; + args = queueItems[i+2]; + errorRecordedForStack = queueItems[i+3]; // Debugging assistance + + if (isString(method)) { + method = target[method]; + } + + // method could have been nullified / canceled during flush + if (method) { + // + // ** Attention intrepid developer ** + // + // To find out the stack of this task when it was scheduled onto + // the run loop, add the following to your app.js: + // + // Ember.run.backburner.DEBUG = true; // NOTE: This slows your app, don't leave it on in production. + // + // Once that is in place, when you are at a breakpoint and navigate + // here in the stack explorer, you can look at `errorRecordedForStack.stack`, + // which will be the captured stack when this job was scheduled. + // + invoke(target, method, args, onError, errorRecordedForStack); } } - if (l && after) { after(); } - // check if new items have been added - if (queue.length > l) { - this._queue = queue.slice(l); - this.flush(); - } else { - this._queue.length = 0; + if (after) { + after(); + } + + this._queueBeingFlushed = undefined; + + if (sync !== false && + this._queue.length > 0) { + // check if new items have been added + this.flush(true); } }, @@ -980,9 +959,11 @@ enifed("backburner/queue", // if not found in current queue // could be in the queue that is being flushed queue = this._queueBeingFlushed; + if (!queue) { return; } + for (i = 0, l = queue.length; i < l; i += 4) { currentTarget = queue[i]; currentMethod = queue[i+1]; @@ -1222,20 +1203,6 @@ enifed("container/container", return container; }, - /** - Sets a key-value pair on the current container. If a parent container, - has the same key, once set on a child, the parent and child will diverge - as expected. - - @method set - @param {Object} object - @param {String} key - @param {any} value - */ - set: function(object, key, value) { - object[key] = value; - }, - /** Registers a factory for later injection. @@ -1491,11 +1458,13 @@ enifed("container/container", /** @method options - @param {String} type + @param {String} fullName @param {Object} options */ - options: function(type, options) { - this.optionsForType(type, options); + options: function(fullName, options) { + options = options || {}; + var normalizedName = this.normalize(fullName); + this._options[normalizedName] = options; }, /** @@ -1540,7 +1509,10 @@ enifed("container/container", var fullNameType = fullName.split(':')[0]; 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.'); + 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); @@ -1604,9 +1576,13 @@ enifed("container/container", var normalizedName = this.normalize(fullName); if (this.cache[normalizedName]) { - throw new Error("Attempted to register an injection for a type that has already been looked up. ('" + normalizedName + "', '" + property + "', '" + injectionName + "')"); + 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); + + addInjection(initRules(this.injections, normalizedName), property, normalizedInjectionName); }, @@ -1713,7 +1689,7 @@ enifed("container/container", 'been looked up. (\'' + normalizedName + '\', \'' + property + '\', \'' + injectionName + '\')'); } - addInjection(this.factoryInjections, normalizedName, property, normalizedInjectionName); + addInjection(initRules(this.factoryInjections, normalizedName), property, normalizedInjectionName); }, /** @@ -1764,7 +1740,7 @@ enifed("container/container", return true; } - return !!container.resolve(fullName); + return container.resolve(fullName) !== undefined; } function lookup(container, fullName, options) { @@ -1800,22 +1776,32 @@ enifed("container/container", if (!injections) { return hash; } - var injection, injectable; + validateInjections(container, injections); + + var injection; for (var i = 0, length = injections.length; i < length; i++) { injection = injections[i]; - injectable = lookup(container, injection.fullName); - - if (injectable !== undefined) { - hash[injection.property] = injectable; - } else { - throw new Error('Attempting to inject an unknown injection: `' + injection.fullName + '`'); - } + hash[injection.property] = lookup(container, injection.fullName); } return hash; } + function validateInjections(container, injections) { + if (!injections) { return; } + + var fullName; + + for (var i = 0, length = injections.length; i < length; i++) { + fullName = injections[i].fullName; + + if (!container.has(fullName)) { + throw new Error('Attempting to inject an unknown injection: `' + fullName + '`'); + } + } + } + function option(container, fullName, optionName) { var options = container._options[fullName]; @@ -1889,8 +1875,23 @@ enifed("container/container", return factoryInjections; } + function normalizeInjectionsHash(hash) { + var injections = []; + + for (var key in hash) { + if (hash.hasOwnProperty(key)) { + Ember.assert("Expected a proper full name, given '" + hash[key] + "'", validateFullName(hash[key])); + + addInjection(injections, key, hash[key]); + } + } + + return injections; + } + function instantiate(container, fullName) { var factory = factoryFor(container, fullName); + var lazyInjections; if (option(container, fullName, 'instantiate') === false) { return factory; @@ -1902,6 +1903,7 @@ enifed("container/container", 'Most likely an improperly defined class or an invalid module export.'); } + if (typeof factory.extend === 'function') { // assume the factory was extendable and is already injected return factory.create(); @@ -1959,8 +1961,11 @@ enifed("container/container", return true; } - function addInjection(rules, factoryName, property, injectionName) { - var injections = rules[factoryName] = rules[factoryName] || []; + function initRules(rules, factoryName) { + return rules[factoryName] || (rules[factoryName] = []); + } + + function addInjection(injections, property, injectionName) { injections.push({ property: property, fullName: injectionName @@ -1969,9 +1974,208 @@ enifed("container/container", __exports__["default"] = Container; }); +enifed("dag-map", + ["exports"], + function(__exports__) { + "use strict"; + function visit(vertex, fn, visited, path) { + var name = vertex.name; + var vertices = vertex.incoming; + var names = vertex.incomingNames; + var len = names.length; + var i; + + if (!visited) { + visited = {}; + } + if (!path) { + path = []; + } + if (visited.hasOwnProperty(name)) { + return; + } + path.push(name); + visited[name] = true; + for (i = 0; i < len; i++) { + visit(vertices[names[i]], fn, visited, path); + } + fn(vertex, path); + path.pop(); + } + + + /** + * DAG stands for Directed acyclic graph. + * + * It is used to build a graph of dependencies checking that there isn't circular + * dependencies. p.e Registering initializers with a certain precedence order. + * + * @class DAG + * @constructor + */ + function DAG() { + this.names = []; + this.vertices = Object.create(null); + } + + /** + * DAG Vertex + * + * @class Vertex + * @constructor + */ + + function Vertex(name) { + this.name = name; + this.incoming = {}; + this.incomingNames = []; + this.hasOutgoing = false; + this.value = null; + } + + /** + * Adds a vertex entry to the graph unless it is already added. + * + * @private + * @method add + * @param {String} name The name of the vertex to add + */ + DAG.prototype.add = function(name) { + if (!name) { + throw new Error("Can't add Vertex without name"); + } + if (this.vertices[name] !== undefined) { + return this.vertices[name]; + } + var vertex = new Vertex(name); + this.vertices[name] = vertex; + this.names.push(name); + return vertex; + }; + + /** + * Adds a vertex to the graph and sets its value. + * + * @private + * @method map + * @param {String} name The name of the vertex. + * @param value The value to put in the vertex. + */ + DAG.prototype.map = function(name, value) { + this.add(name).value = value; + }; + + /** + * Connects the vertices with the given names, adding them to the graph if + * necessary, only if this does not produce is any circular dependency. + * + * @private + * @method addEdge + * @param {String} fromName The name the vertex where the edge starts. + * @param {String} toName The name the vertex where the edge ends. + */ + DAG.prototype.addEdge = function(fromName, toName) { + if (!fromName || !toName || fromName === toName) { + return; + } + var from = this.add(fromName); + var to = this.add(toName); + if (to.incoming.hasOwnProperty(fromName)) { + return; + } + function checkCycle(vertex, path) { + if (vertex.name === toName) { + throw new Error("cycle detected: " + toName + " <- " + path.join(" <- ")); + } + } + visit(from, checkCycle); + from.hasOutgoing = true; + to.incoming[fromName] = from; + to.incomingNames.push(fromName); + }; + + /** + * Visits all the vertex of the graph calling the given function with each one, + * ensuring that the vertices are visited respecting their precedence. + * + * @method topsort + * @param {Function} fn The function to be invoked on each vertex. + */ + DAG.prototype.topsort = function(fn) { + var visited = {}; + var vertices = this.vertices; + var names = this.names; + var len = names.length; + var i, vertex; + + for (i = 0; i < len; i++) { + vertex = vertices[names[i]]; + if (!vertex.hasOutgoing) { + visit(vertex, fn, visited); + } + } + }; + + /** + * Adds a vertex with the given name and value to the graph and joins it with the + * vertices referenced in _before_ and _after_. If there isn't vertices with those + * names, they are added too. + * + * If either _before_ or _after_ are falsy/empty, the added vertex will not have + * an incoming/outgoing edge. + * + * @method addEdges + * @param {String} name The name of the vertex to be added. + * @param value The value of that vertex. + * @param before An string or array of strings with the names of the vertices before + * which this vertex must be visited. + * @param after An string or array of strings with the names of the vertex after + * which this vertex must be visited. + * + */ + DAG.prototype.addEdges = function(name, value, before, after) { + var i; + this.map(name, value); + if (before) { + if (typeof before === 'string') { + this.addEdge(name, before); + } else { + for (i = 0; i < before.length; i++) { + this.addEdge(name, before[i]); + } + } + } + if (after) { + if (typeof after === 'string') { + this.addEdge(after, name); + } else { + for (i = 0; i < after.length; i++) { + this.addEdge(after[i], name); + } + } + } + }; + + __exports__["default"] = DAG; + }); +enifed("dag-map.umd", + ["./dag-map"], + function(__dependency1__) { + "use strict"; + var DAG = __dependency1__["default"]; + + /* global define:true module:true window: true */ + if (typeof enifed === 'function' && enifed.amd) { + enifed(function() { return DAG; }); + } else if (typeof module !== 'undefined' && module.exports) { + module.exports = DAG; + } else if (typeof this !== 'undefined') { + this['DAG'] = DAG; + } + }); enifed("ember-application", - ["ember-metal/core","ember-runtime/system/lazy_load","ember-application/system/dag","ember-application/system/resolver","ember-application/system/application","ember-application/ext/controller"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__) { + ["ember-metal/core","ember-runtime/system/lazy_load","ember-application/system/resolver","ember-application/system/application","ember-application/ext/controller"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) { "use strict"; var Ember = __dependency1__["default"]; var runLoadHooks = __dependency2__.runLoadHooks; @@ -1984,22 +2188,20 @@ enifed("ember-application", @requires ember-views, ember-routing */ - var DAG = __dependency3__["default"]; - var Resolver = __dependency4__.Resolver; - var DefaultResolver = __dependency4__["default"]; - var Application = __dependency5__["default"]; + var Resolver = __dependency3__.Resolver; + var DefaultResolver = __dependency3__["default"]; + var Application = __dependency4__["default"]; // side effect of extending ControllerMixin Ember.Application = Application; - Ember.DAG = DAG; Ember.Resolver = Resolver; Ember.DefaultResolver = DefaultResolver; runLoadHooks('Ember.Application', Application); }); enifed("ember-application/ext/controller", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/error","ember-metal/utils","ember-metal/computed","ember-runtime/mixins/controller","ember-routing/system/controller_for","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) { + ["ember-metal/core","ember-metal/property_get","ember-metal/error","ember-metal/utils","ember-metal/computed","ember-runtime/mixins/controller","ember-routing/system/controller_for","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) { "use strict"; /** @module ember @@ -2009,13 +2211,12 @@ enifed("ember-application/ext/controller", var Ember = __dependency1__["default"]; // Ember.assert var get = __dependency2__.get; - var set = __dependency3__.set; - var EmberError = __dependency4__["default"]; - var inspect = __dependency5__.inspect; - var computed = __dependency6__.computed; - var ControllerMixin = __dependency7__["default"]; - var meta = __dependency5__.meta; - var controllerFor = __dependency8__["default"]; + var EmberError = __dependency3__["default"]; + var inspect = __dependency4__.inspect; + var computed = __dependency5__.computed; + var ControllerMixin = __dependency6__["default"]; + var meta = __dependency4__.meta; + var controllerFor = __dependency7__["default"]; function verifyNeedsDependencies(controller, container, needs) { var dependency, i, l; @@ -2024,7 +2225,8 @@ enifed("ember-application/ext/controller", for (i=0, l=needs.length; i 1 ? 'they' : 'it') + " could not be found"); + throw new EmberError(inspect(controller) + " needs [ " + missing.join(', ') + + " ] but " + (missing.length > 1 ? 'they' : 'it') + " could not be found"); } } @@ -2057,7 +2260,12 @@ enifed("ember-application/ext/controller", } } - var errorMessage = inspect(controller) + '#needs does not include `' + controllerName + '`. To access the ' + controllerName + ' controller from ' + inspect(controller) + ', ' + inspect(controller) + ' should have a `needs` property that is an array of the controllers it has access to.'; + var errorMessage = inspect(controller) + '#needs does not include `' + + controllerName + '`. To access the ' + + controllerName + ' controller from ' + + inspect(controller) + ', ' + + inspect(controller) + + ' should have a `needs` property that is an array of the controllers it has access to.'; throw new ReferenceError(errorMessage); }, setUnknownProperty: function (key, value) { @@ -2178,34 +2386,34 @@ enifed("ember-application/ext/controller", __exports__["default"] = ControllerMixin; }); enifed("ember-application/system/application", - ["ember-metal","ember-metal/property_get","ember-metal/property_set","ember-runtime/system/lazy_load","ember-application/system/dag","ember-runtime/system/namespace","ember-runtime/mixins/deferred","ember-application/system/resolver","ember-metal/platform","ember-metal/run_loop","ember-metal/utils","container/container","ember-runtime/controllers/controller","ember-metal/enumerable_utils","ember-runtime/controllers/object_controller","ember-runtime/controllers/array_controller","ember-handlebars/controls/select","ember-views/system/event_dispatcher","ember-views/system/jquery","ember-routing/system/route","ember-routing/system/router","ember-routing/location/hash_location","ember-routing/location/history_location","ember-routing/location/auto_location","ember-routing/location/none_location","ember-routing/system/cache","ember-metal/core","ember-handlebars-compiler","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__, __exports__) { + ["dag-map","container/container","ember-metal","ember-metal/property_get","ember-metal/property_set","ember-runtime/system/lazy_load","ember-runtime/system/namespace","ember-runtime/mixins/deferred","ember-application/system/resolver","ember-metal/platform","ember-metal/run_loop","ember-metal/utils","ember-runtime/controllers/controller","ember-metal/enumerable_utils","ember-runtime/controllers/object_controller","ember-runtime/controllers/array_controller","ember-handlebars/controls/select","ember-views/system/event_dispatcher","ember-views/system/jquery","ember-routing/system/route","ember-routing/system/router","ember-routing/location/hash_location","ember-routing/location/history_location","ember-routing/location/auto_location","ember-routing/location/none_location","ember-routing/system/cache","ember-extension-support/container_debug_adapter","ember-metal/core","ember-handlebars-compiler","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__, __exports__) { "use strict"; /** @module ember @submodule ember-application */ + var DAG = __dependency1__["default"]; + var Container = __dependency2__["default"]; - var Ember = __dependency1__["default"]; + + var Ember = __dependency3__["default"]; // Ember.FEATURES, Ember.deprecate, Ember.assert, Ember.libraries, LOG_VERSION, Namespace, BOOTED - var get = __dependency2__.get; - var set = __dependency3__.set; - var runLoadHooks = __dependency4__.runLoadHooks; - var DAG = __dependency5__["default"]; - var Namespace = __dependency6__["default"]; - var DeferredMixin = __dependency7__["default"]; - var DefaultResolver = __dependency8__["default"]; - var create = __dependency9__.create; - var run = __dependency10__["default"]; - var canInvoke = __dependency11__.canInvoke; - var Container = __dependency12__["default"]; + var get = __dependency4__.get; + var set = __dependency5__.set; + var runLoadHooks = __dependency6__.runLoadHooks; + var Namespace = __dependency7__["default"]; + var DeferredMixin = __dependency8__["default"]; + var DefaultResolver = __dependency9__["default"]; + var create = __dependency10__.create; + var run = __dependency11__["default"]; + var canInvoke = __dependency12__.canInvoke; var Controller = __dependency13__["default"]; var EnumerableUtils = __dependency14__["default"]; var ObjectController = __dependency15__["default"]; var ArrayController = __dependency16__["default"]; var SelectView = __dependency17__["default"]; var EventDispatcher = __dependency18__["default"]; - //import ContainerDebugAdapter from "ember-extension-support/container_debug_adapter"; var jQuery = __dependency19__["default"]; var Route = __dependency20__["default"]; var Router = __dependency21__["default"]; @@ -2215,10 +2423,16 @@ enifed("ember-application/system/application", var NoneLocation = __dependency25__["default"]; var BucketCache = __dependency26__["default"]; - var K = __dependency27__.K; - var EmberHandlebars = __dependency28__["default"]; + // this is technically incorrect (per @wycats) + // it should work properly with: + // `import ContainerDebugAdapter from 'ember-extension-support/container_debug_adapter';` but + // es6-module-transpiler 0.4.0 eagerly grabs the module (which is undefined) + + var ContainerDebugAdapter = __dependency27__["default"]; + + var K = __dependency28__.K; + var EmberHandlebars = __dependency29__["default"]; - var ContainerDebugAdapter; function props(obj) { var properties = []; @@ -2290,10 +2504,10 @@ enifed("ember-application/system/application", names by setting the application's `customEvents` property: ```javascript - App = Ember.Application.create({ + var App = Ember.Application.create({ customEvents: { // add support for the paste event - paste: "paste" + paste: 'paste' } }); ``` @@ -2307,7 +2521,7 @@ enifed("ember-application/system/application", should be delegated, set your application's `rootElement` property: ```javascript - window.App = Ember.Application.create({ + var App = Ember.Application.create({ rootElement: '#ember-app' }); ``` @@ -2350,7 +2564,7 @@ enifed("ember-application/system/application", the `LOG_TRANSITIONS_INTERNAL` flag: ```javascript - window.App = Ember.Application.create({ + var App = Ember.Application.create({ LOG_TRANSITIONS: true, // basic logging of successful transitions LOG_TRANSITIONS_INTERNAL: true // detailed logging of all routing steps }); @@ -2419,10 +2633,10 @@ enifed("ember-application/system/application", corresponding view method name as the value. For example: ```javascript - App = Ember.Application.create({ + var App = Ember.Application.create({ customEvents: { // add support for the paste event - paste: "paste" + paste: 'paste' } }); ``` @@ -2438,7 +2652,9 @@ enifed("ember-application/system/application", _readinessDeferrals: 1, init: function() { - if (!this.$) { this.$ = jQuery; } + if (!this.$) { + this.$ = jQuery; + } this.__container__ = this.buildContainer(); this.Router = this.defaultRouter(); @@ -2550,10 +2766,11 @@ enifed("ember-application/system/application", Example: ```javascript - App = Ember.Application.create(); + var App = Ember.Application.create(); + App.deferReadiness(); - - jQuery.getJSON("/auth-token", function(token) { + // Ember.$ is a reference to the jQuery object/function + Ember.$.getJSON('/auth-token', function(token) { App.token = token; App.advanceReadiness(); }); @@ -2599,7 +2816,8 @@ enifed("ember-application/system/application", ```javascript var App = Ember.Application.create(); - App.Orange = Ember.Object.extend(); + + App.Orange = Ember.Object.extend(); App.register('fruit:favorite', App.Orange); ``` @@ -2610,8 +2828,8 @@ enifed("ember-application/system/application", An example of registering a controller with a non-standard name: ```javascript - var App = Ember.Application.create(), - Session = Ember.Controller.extend(); + var App = Ember.Application.create(); + var Session = Ember.Controller.extend(); App.register('controller:session', Session); @@ -2636,10 +2854,10 @@ enifed("ember-application/system/application", App.Email = Ember.Object.extend(); App.session = Ember.Object.create(); - App.register('model:user', App.Person, {singleton: false }); + App.register('model:user', App.Person, { singleton: false }); App.register('fruit:favorite', App.Orange); - App.register('communication:main', App.Email, {singleton: false}); - App.register('session', App.session, {instantiate: false}); + App.register('communication:main', App.Email, { singleton: false }); + App.register('session', App.session, { instantiate: false }); ``` @method register @@ -2663,8 +2881,8 @@ enifed("ember-application/system/application", An example of providing a session object to all controllers: ```javascript - var App = Ember.Application.create(), - Session = Ember.Object.extend({ isAuthenticated: false }); + var App = Ember.Application.create(); + var Session = Ember.Object.extend({ isAuthenticated: false }); // A factory must be registered before it can be injected App.register('session:main', Session); @@ -2691,7 +2909,7 @@ enifed("ember-application/system/application", directly (via `create` or `new`) bypasses the dependency injection system. - Ember-Data instantiates its models in a unique manner, and consequently + **Note:** Ember-Data instantiates its models in a unique manner, and consequently injections onto models (or all models) will not work as expected. Injections on models can be enabled by setting `Ember.MODEL_FACTORY_INJECTIONS` to `true`. @@ -2763,24 +2981,23 @@ enifed("ember-application/system/application", Typical Example: ```javascript - var App; run(function() { App = Ember.Application.create(); }); - module("acceptance test", { + module('acceptance test', { setup: function() { App.reset(); } }); - test("first test", function() { + test('first test', function() { // App is freshly reset }); - test("first test", function() { + test('second test', function() { // App is again freshly reset }); ``` @@ -2792,14 +3009,13 @@ enifed("ember-application/system/application", to the app becoming ready. ```javascript - var App; run(function() { App = Ember.Application.create(); }); - module("acceptance test", { + module('acceptance test', { setup: function() { run(function() { App.reset(); @@ -2808,12 +3024,13 @@ enifed("ember-application/system/application", } }); - test("first test", function() { + test('first test', function() { ok(true, 'something before app is initialized'); run(function() { App.advanceReadiness(); }); + ok(true, 'something after app is initialized'); }); ``` @@ -2849,7 +3066,7 @@ enifed("ember-application/system/application", var container = this.__container__; var graph = new DAG(); var namespace = this; - var name, initializer; + var initializer; for (var i = 0; i < initializers.length; i++) { initializer = initializersByName[initializers[i]]; @@ -2982,8 +3199,9 @@ enifed("ember-application/system/application", ```javascript Ember.Application.initializer({ name: 'namedInitializer', + initialize: function(container, application) { - Ember.debug("Running namedInitializer!"); + Ember.debug('Running namedInitializer!'); } }); ``` @@ -2997,8 +3215,9 @@ enifed("ember-application/system/application", ```javascript Ember.Application.initializer({ name: 'first', + initialize: function(container, application) { - Ember.debug("First initializer!"); + Ember.debug('First initializer!'); } }); @@ -3014,7 +3233,7 @@ enifed("ember-application/system/application", after: 'first', initialize: function(container, application) { - Ember.debug("Second initializer!"); + Ember.debug('Second initializer!'); } }); @@ -3031,7 +3250,7 @@ enifed("ember-application/system/application", before: 'first', initialize: function(container, application) { - Ember.debug("Pre initializer!"); + Ember.debug('Pre initializer!'); } }); @@ -3049,7 +3268,7 @@ enifed("ember-application/system/application", after: ['first', 'second'], initialize: function(container, application) { - Ember.debug("Post initializer!"); + Ember.debug('Post initializer!'); } }); @@ -3066,10 +3285,11 @@ enifed("ember-application/system/application", ```javascript Ember.Application.initializer({ - name: "preload-data", + name: 'preload-data', initialize: function(container, application) { var store = container.lookup('store:main'); + store.pushPayload(preloadedData); } }); @@ -3103,6 +3323,7 @@ enifed("ember-application/system/application", Ember.assert("The initializer '" + initializer.name + "' has already been registered", !this.initializers[initializer.name]); Ember.assert("An initializer cannot be registered without an initialize function", canInvoke(initializer, 'initialize')); + Ember.assert("An initializer cannot be registered without a name property", initializer.name !== undefined); this.initializers[initializer.name] = initializer; }, @@ -3182,8 +3403,6 @@ enifed("ember-application/system/application", container.injection('data-adapter:main', 'containerDebugAdapter', 'container-debug-adapter:main'); // Custom resolver authors may want to register their own ContainerDebugAdapter with this key - // ES6TODO: resolve this via import once ember-application package is ES6'ed - if (!ContainerDebugAdapter) { ContainerDebugAdapter = requireModule('ember-extension-support/container_debug_adapter')['default']; } container.register('container-debug-adapter:main', ContainerDebugAdapter); return container; @@ -3244,192 +3463,6 @@ enifed("ember-application/system/application", __exports__["default"] = Application; }); -enifed("ember-application/system/dag", - ["ember-metal/error","exports"], - function(__dependency1__, __exports__) { - "use strict"; - var EmberError = __dependency1__["default"]; - - function visit(vertex, fn, visited, path) { - var name = vertex.name; - var vertices = vertex.incoming; - var names = vertex.incomingNames; - var len = names.length; - var i; - - if (!visited) { - visited = {}; - } - if (!path) { - path = []; - } - if (visited.hasOwnProperty(name)) { - return; - } - path.push(name); - visited[name] = true; - for (i = 0; i < len; i++) { - visit(vertices[names[i]], fn, visited, path); - } - fn(vertex, path); - path.pop(); - } - - - /** - * DAG stands for Directed acyclic graph. - * - * It is used to build a graph of dependencies checking that there isn't circular - * dependencies. p.e Registering initializers with a certain precedence order. - * - * @class DAG - * @constructor - */ - function DAG() { - this.names = []; - this.vertices = Object.create(null); - } - - /** - * DAG Vertex - * - * @class Vertex - * @constructor - */ - - function Vertex(name) { - this.name = name; - this.incoming = {}; - this.incomingNames = []; - this.hasOutgoing = false; - this.value = null; - } - - /** - * Adds a vertex entry to the graph unless it is already added. - * - * @private - * @method add - * @param {String} name The name of the vertex to add - */ - DAG.prototype.add = function(name) { - if (!name) { - throw new Error("Can't add Vertex without name"); - } - if (this.vertices[name] !== undefined) { - return this.vertices[name]; - } - var vertex = new Vertex(name); - this.vertices[name] = vertex; - this.names.push(name); - return vertex; - }; - - /** - * Adds a vertex to the graph and sets its value. - * - * @private - * @method map - * @param {String} name The name of the vertex. - * @param value The value to put in the vertex. - */ - DAG.prototype.map = function(name, value) { - this.add(name).value = value; - }; - - /** - * Connects the vertices with the given names, adding them to the graph if - * necessary, only if this does not produce is any circular dependency. - * - * @private - * @method addEdge - * @param {String} fromName The name the vertex where the edge starts. - * @param {String} toName The name the vertex where the edge ends. - */ - DAG.prototype.addEdge = function(fromName, toName) { - if (!fromName || !toName || fromName === toName) { - return; - } - var from = this.add(fromName); - var to = this.add(toName); - if (to.incoming.hasOwnProperty(fromName)) { - return; - } - function checkCycle(vertex, path) { - if (vertex.name === toName) { - throw new EmberError("cycle detected: " + toName + " <- " + path.join(" <- ")); - } - } - visit(from, checkCycle); - from.hasOutgoing = true; - to.incoming[fromName] = from; - to.incomingNames.push(fromName); - }; - - /** - * Visits all the vertex of the graph calling the given function with each one, - * ensuring that the vertices are visited respecting their precedence. - * - * @method topsort - * @param {Function} fn The function to be invoked on each vertex. - */ - DAG.prototype.topsort = function(fn) { - var visited = {}; - var vertices = this.vertices; - var names = this.names; - var len = names.length; - var i, vertex; - - for (i = 0; i < len; i++) { - vertex = vertices[names[i]]; - if (!vertex.hasOutgoing) { - visit(vertex, fn, visited); - } - } - }; - - /** - * Adds a vertex with the given name and value to the graph and joins it with the - * vertices referenced in _before_ and _after_. If there isn't vertices with those - * names, they are added too. - * - * If either _before_ or _after_ are falsy/empty, the added vertex will not have - * an incoming/outgoing edge. - * - * @method addEdges - * @param {String} name The name of the vertex to be added. - * @param value The value of that vertex. - * @param before An string or array of strings with the names of the vertices before - * which this vertex must be visited. - * @param after An string or array of strings with the names of the vertex after - * which this vertex must be visited. - * - */ - DAG.prototype.addEdges = function(name, value, before, after) { - var i; - this.map(name, value); - if (before) { - if (typeof before === 'string') { - this.addEdge(name, before); - } else { - for (i = 0; i < before.length; i++) { - this.addEdge(name, before[i]); - } - } - } - if (after) { - if (typeof after === 'string') { - this.addEdge(after, name); - } else { - for (i = 0; i < after.length; i++) { - this.addEdge(after[i], name); - } - } - } - }; - - __exports__["default"] = DAG; - }); enifed("ember-application/system/resolver", ["ember-metal/core","ember-metal/property_get","ember-metal/logger","ember-runtime/system/string","ember-runtime/system/object","ember-runtime/system/namespace","ember-handlebars","ember-metal/dictionary","exports"], function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) { @@ -3511,26 +3544,26 @@ enifed("ember-application/system/resolver", Some examples of how names are resolved: ``` - 'template:post' //=> Ember.TEMPLATES['post'] - 'template:posts/byline' //=> Ember.TEMPLATES['posts/byline'] - 'template:posts.byline' //=> Ember.TEMPLATES['posts/byline'] - 'template:blogPost' //=> Ember.TEMPLATES['blogPost'] - // OR - // Ember.TEMPLATES['blog_post'] - 'controller:post' //=> App.PostController - 'controller:posts.index' //=> App.PostsIndexController - 'controller:blog/post' //=> Blog.PostController - 'controller:basic' //=> Ember.Controller - 'route:post' //=> App.PostRoute - 'route:posts.index' //=> App.PostsIndexRoute - 'route:blog/post' //=> Blog.PostRoute - 'route:basic' //=> Ember.Route - 'view:post' //=> App.PostView - 'view:posts.index' //=> App.PostsIndexView - 'view:blog/post' //=> Blog.PostView - 'view:basic' //=> Ember.View - 'foo:post' //=> App.PostFoo - 'model:post' //=> App.Post + 'template:post' //=> Ember.TEMPLATES['post'] + 'template:posts/byline' //=> Ember.TEMPLATES['posts/byline'] + 'template:posts.byline' //=> Ember.TEMPLATES['posts/byline'] + 'template:blogPost' //=> Ember.TEMPLATES['blogPost'] + // OR + // Ember.TEMPLATES['blog_post'] + 'controller:post' //=> App.PostController + 'controller:posts.index' //=> App.PostsIndexController + 'controller:blog/post' //=> Blog.PostController + 'controller:basic' //=> Ember.Controller + 'route:post' //=> App.PostRoute + 'route:posts.index' //=> App.PostsIndexRoute + 'route:blog/post' //=> Blog.PostRoute + 'route:basic' //=> Ember.Route + 'view:post' //=> App.PostView + 'view:posts.index' //=> App.PostsIndexView + 'view:blog/post' //=> Blog.PostView + 'view:basic' //=> Ember.View + 'foo:post' //=> App.PostFoo + 'model:post' //=> App.Post ``` @class DefaultResolver @@ -3556,7 +3589,9 @@ enifed("ember-application/system/resolver", var type = split[0]; var name = split[1]; - Ember.assert("Tried to normalize a container name without a colon (:) in it. You probably tried to lookup a name that did not contain a type, a colon, and a name. A proper lookup name would be `view:post`.", split.length === 2); + Ember.assert("Tried to normalize a container name without a colon (:) in it." + + " You probably tried to lookup a name that did not contain a type," + + " a colon, and a name. A proper lookup name would be `view:post`.", split.length === 2); if (type !== 'template') { var result = name; @@ -3641,7 +3676,9 @@ enifed("ember-application/system/resolver", var namespaceName = capitalize(parts.slice(0, -1).join('.')); root = Namespace.byName(namespaceName); - Ember.assert('You are looking for a ' + name + ' ' + type + ' in the ' + namespaceName + ' namespace, but the namespace could not be found', root); + Ember.assert('You are looking for a ' + name + ' ' + type + + ' in the ' + namespaceName + + ' namespace, but the namespace could not be found', root); } return { @@ -3821,8 +3858,8 @@ enifed("ember-application/system/resolver", }); }); enifed("ember-debug", - ["ember-metal/core","ember-metal/error","ember-metal/logger"], - function(__dependency1__, __dependency2__, __dependency3__) { + ["ember-metal/core","ember-metal/error","ember-metal/logger","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __exports__) { "use strict"; /*global __fail__*/ @@ -3991,8 +4028,39 @@ enifed("ember-debug", func(); }; - // Inform the developer about the Ember Inspector if not installed. - if (!Ember.testing) { + /** + Will call `Ember.warn()` if ENABLE_ALL_FEATURES, ENABLE_OPTIONAL_FEATURES, or + any specific FEATURES flag is truthy. + + This method is called automatically in debug canary builds. + + @private + @method _warnIfUsingStrippedFeatureFlags + @return {void} + */ + function _warnIfUsingStrippedFeatureFlags(FEATURES, featuresWereStripped) { + if (featuresWereStripped) { + Ember.warn('Ember.ENV.ENABLE_ALL_FEATURES is only available in canary builds.', !Ember.ENV.ENABLE_ALL_FEATURES); + Ember.warn('Ember.ENV.ENABLE_OPTIONAL_FEATURES is only available in canary builds.', !Ember.ENV.ENABLE_OPTIONAL_FEATURES); + + for (var key in FEATURES) { + if (FEATURES.hasOwnProperty(key) && key !== 'isEnabled') { + Ember.warn('FEATURE["' + key + '"] is set as enabled, but FEATURE flags are only available in canary builds.', !FEATURES[key]); + } + } + } + } + + __exports__._warnIfUsingStrippedFeatureFlags = _warnIfUsingStrippedFeatureFlags;if (!Ember.testing) { + // Complain if they're using FEATURE flags in builds other than canary + Ember.FEATURES['features-stripped-test'] = true; + var featuresWereStripped = true; + + + delete Ember.FEATURES['features-stripped-test']; + _warnIfUsingStrippedFeatureFlags(Ember.ENV.FEATURES, featuresWereStripped); + + // Inform the developer about the Ember Inspector if not installed. var isFirefox = typeof InstallTrigger !== 'undefined'; var isChrome = !!window.chrome && !window.opera; @@ -4125,7 +4193,7 @@ enifed("ember-extension-support/container_debug_adapter", @return {Array} An array of strings. */ catalogEntriesByType: function(type) { - var namespaces = emberA(Namespace.NAMESPACES), types = emberA(), self = this; + var namespaces = emberA(Namespace.NAMESPACES), types = emberA(); var typeSuffixRegex = new RegExp(classify(type) + "$"); namespaces.forEach(function(namespace) { @@ -4469,8 +4537,7 @@ enifed("ember-extension-support/data_adapter", */ wrapModelType: function(type, name) { var records = this.getRecords(type); - var self = this; - var release, typeToSend; + var typeToSend; typeToSend = { name: name || type.toString(), @@ -4571,8 +4638,6 @@ enifed("ember-extension-support/data_adapter", */ wrapRecord: function(record) { var recordToSend = { object: record }; - var columnValues = {}; - var self = this; recordToSend.columnValues = this.getRecordColumnValues(record); recordToSend.searchKeywords = this.getRecordKeywords(record); @@ -4688,14 +4753,13 @@ enifed("ember-handlebars-compiler", Handlebars = eriuqer('handlebars'); } - Ember.assert("Ember Handlebars requires Handlebars version 1.0 or 1.1. Include " + + Ember.assert("Ember Handlebars requires Handlebars version 2.0. Include " + "a SCRIPT tag in the HTML HEAD linking to the Handlebars file " + "before you link to Ember.", Handlebars); - Ember.assert("Ember Handlebars requires Handlebars version 1.0 or 1.1, " + - "COMPILER_REVISION expected: 4, got: " + Handlebars.COMPILER_REVISION + - " - Please note: Builds of master may have other COMPILER_REVISION values.", - Handlebars.COMPILER_REVISION === 4); + Ember.assert("Ember Handlebars requires Handlebars version 2.0. " + + "Please see more details at http://emberjs.com/blog/2014/10/16/handlebars-update.html.", + Handlebars.COMPILER_REVISION === 6); /** Prepares the Handlebars templating library for use inside Ember's view @@ -4711,7 +4775,7 @@ enifed("ember-handlebars-compiler", @class Handlebars @namespace Ember */ - var EmberHandlebars = Ember.Handlebars = objectCreate(Handlebars); + var EmberHandlebars = Ember.Handlebars = Handlebars.create(); /** Register a bound helper or custom view helper. @@ -4770,7 +4834,8 @@ enifed("ember-handlebars-compiler", if (!View) { View = requireModule('ember-views/views/view')['default']; } // ES6TODO: stupid circular dep if (!Component) { Component = requireModule('ember-views/views/component')['default']; } // ES6TODO: stupid circular dep - Ember.assert("You tried to register a component named '" + name + "', but component names must include a '-'", !Component.detect(value) || name.match(/-/)); + Ember.assert("You tried to register a component named '" + name + + "', but component names must include a '-'", !Component.detect(value) || name.match(/-/)); if (View.detect(value)) { EmberHandlebars.registerHelper(name, EmberHandlebars.makeViewHelper(value)); @@ -4793,7 +4858,8 @@ enifed("ember-handlebars-compiler", */ EmberHandlebars.makeViewHelper = function(ViewClass) { return function(options) { - Ember.assert("You can only pass attributes (such as name=value) not bare values to a helper for a View found in '" + ViewClass.toString() + "'", arguments.length < 2); + Ember.assert("You can only pass attributes (such as name=value) not bare " + + "values to a helper for a View found in '" + ViewClass.toString() + "'", arguments.length < 2); return EmberHandlebars.helpers.view.call(this, ViewClass, options); }; }; @@ -4855,44 +4921,6 @@ enifed("ember-handlebars-compiler", return "data.buffer.push("+string+");"; }; - // Hacks ahead: - // Handlebars presently has a bug where the `blockHelperMissing` hook - // doesn't get passed the name of the missing helper name, but rather - // gets passed the value of that missing helper evaluated on the current - // context, which is most likely `undefined` and totally useless. - // - // So we alter the compiled template function to pass the name of the helper - // instead, as expected. - // - // This can go away once the following is closed: - // https://github.com/wycats/handlebars.js/issues/634 - - var DOT_LOOKUP_REGEX = /helpers\.(.*?)\)/; - var BRACKET_STRING_LOOKUP_REGEX = /helpers\['(.*?)'/; - var INVOCATION_SPLITTING_REGEX = /(.*blockHelperMissing\.call\(.*)(stack[0-9]+)(,.*)/; - - EmberHandlebars.JavaScriptCompiler.stringifyLastBlockHelperMissingInvocation = function(source) { - var helperInvocation = source[source.length - 1]; - var helperName = (DOT_LOOKUP_REGEX.exec(helperInvocation) || BRACKET_STRING_LOOKUP_REGEX.exec(helperInvocation))[1]; - var matches = INVOCATION_SPLITTING_REGEX.exec(helperInvocation); - - source[source.length - 1] = matches[1] + "'" + helperName + "'" + matches[3]; - }; - - var stringifyBlockHelperMissing = EmberHandlebars.JavaScriptCompiler.stringifyLastBlockHelperMissingInvocation; - - var originalBlockValue = EmberHandlebars.JavaScriptCompiler.prototype.blockValue; - EmberHandlebars.JavaScriptCompiler.prototype.blockValue = function() { - originalBlockValue.apply(this, arguments); - stringifyBlockHelperMissing(this.source); - }; - - var originalAmbiguousBlockValue = EmberHandlebars.JavaScriptCompiler.prototype.ambiguousBlockValue; - EmberHandlebars.JavaScriptCompiler.prototype.ambiguousBlockValue = function() { - originalAmbiguousBlockValue.apply(this, arguments); - stringifyBlockHelperMissing(this.source); - }; - /** Rewrite simple mustaches from `{{foo}}` to `{{bind "foo"}}`. This means that all simple mustaches in Ember's Handlebars will also set up an observer to @@ -4982,8 +5010,8 @@ enifed("ember-handlebars-compiler", __exports__["default"] = EmberHandlebars; }); enifed("ember-handlebars", - ["ember-handlebars-compiler","ember-metal/core","ember-runtime/system/lazy_load","ember-handlebars/loader","ember-handlebars/ext","ember-handlebars/string","ember-handlebars/helpers/shared","ember-handlebars/helpers/binding","ember-handlebars/helpers/collection","ember-handlebars/helpers/view","ember-handlebars/helpers/unbound","ember-handlebars/helpers/debug","ember-handlebars/helpers/each","ember-handlebars/helpers/template","ember-handlebars/helpers/partial","ember-handlebars/helpers/yield","ember-handlebars/helpers/loc","ember-handlebars/controls/checkbox","ember-handlebars/controls/select","ember-handlebars/controls/text_area","ember-handlebars/controls/text_field","ember-handlebars/controls/text_support","ember-handlebars/controls","ember-handlebars/component_lookup","ember-handlebars/views/handlebars_bound_view","ember-handlebars/views/metamorph_view","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__, __exports__) { + ["ember-handlebars-compiler","ember-metal/core","ember-runtime/system/lazy_load","ember-handlebars/loader","ember-handlebars/ext","ember-handlebars/string","ember-handlebars/helpers/binding","ember-handlebars/helpers/if_unless","ember-handlebars/helpers/with","ember-handlebars/helpers/bind_attr","ember-handlebars/helpers/collection","ember-handlebars/helpers/view","ember-handlebars/helpers/unbound","ember-handlebars/helpers/debug","ember-handlebars/helpers/each","ember-handlebars/helpers/template","ember-handlebars/helpers/partial","ember-handlebars/helpers/yield","ember-handlebars/helpers/loc","ember-handlebars/controls/checkbox","ember-handlebars/controls/select","ember-handlebars/controls/text_area","ember-handlebars/controls/text_field","ember-handlebars/controls/text_support","ember-handlebars/controls","ember-handlebars/component_lookup","ember-handlebars/views/handlebars_bound_view","ember-handlebars/views/metamorph_view","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__, __exports__) { "use strict"; var EmberHandlebars = __dependency1__["default"]; var Ember = __dependency2__["default"]; @@ -4992,68 +5020,61 @@ enifed("ember-handlebars", var runLoadHooks = __dependency3__.runLoadHooks; var bootstrap = __dependency4__["default"]; - var normalizePath = __dependency5__.normalizePath; - var template = __dependency5__.template; var makeBoundHelper = __dependency5__.makeBoundHelper; var registerBoundHelper = __dependency5__.registerBoundHelper; - var resolveHash = __dependency5__.resolveHash; - var resolveParams = __dependency5__.resolveParams; - var getEscaped = __dependency5__.getEscaped; - var handlebarsGet = __dependency5__.handlebarsGet; - var evaluateUnboundHelper = __dependency5__.evaluateUnboundHelper; var helperMissingHelper = __dependency5__.helperMissingHelper; var blockHelperMissingHelper = __dependency5__.blockHelperMissingHelper; + var handlebarsGet = __dependency5__.handlebarsGet; // side effect of extending StringUtils of htmlSafe - var resolvePaths = __dependency7__["default"]; - var bind = __dependency8__.bind; - var _triageMustacheHelper = __dependency8__._triageMustacheHelper; - var resolveHelper = __dependency8__.resolveHelper; - var bindHelper = __dependency8__.bindHelper; + var bind = __dependency7__.bind; + var _triageMustacheHelper = __dependency7__._triageMustacheHelper; + var resolveHelper = __dependency7__.resolveHelper; + var bindHelper = __dependency7__.bindHelper; + + var ifHelper = __dependency8__.ifHelper; var boundIfHelper = __dependency8__.boundIfHelper; var unboundIfHelper = __dependency8__.unboundIfHelper; - var withHelper = __dependency8__.withHelper; - var ifHelper = __dependency8__.ifHelper; var unlessHelper = __dependency8__.unlessHelper; - var bindAttrHelper = __dependency8__.bindAttrHelper; - var bindAttrHelperDeprecated = __dependency8__.bindAttrHelperDeprecated; - var bindClasses = __dependency8__.bindClasses; - var collectionHelper = __dependency9__["default"]; - var ViewHelper = __dependency10__.ViewHelper; - var viewHelper = __dependency10__.viewHelper; - var unboundHelper = __dependency11__["default"]; - var logHelper = __dependency12__.logHelper; - var debuggerHelper = __dependency12__.debuggerHelper; - var EachView = __dependency13__.EachView; - var GroupedEach = __dependency13__.GroupedEach; - var eachHelper = __dependency13__.eachHelper; - var templateHelper = __dependency14__["default"]; - var partialHelper = __dependency15__["default"]; - var yieldHelper = __dependency16__["default"]; - var locHelper = __dependency17__["default"]; + var withHelper = __dependency9__["default"]; + + var bindAttrHelper = __dependency10__.bindAttrHelper; + var bindAttrHelperDeprecated = __dependency10__.bindAttrHelperDeprecated; + var bindClasses = __dependency10__.bindClasses; + + var collectionHelper = __dependency11__["default"]; + var ViewHelper = __dependency12__.ViewHelper; + var viewHelper = __dependency12__.viewHelper; + var unboundHelper = __dependency13__["default"]; + var logHelper = __dependency14__.logHelper; + var debuggerHelper = __dependency14__.debuggerHelper; + var EachView = __dependency15__.EachView; + var eachHelper = __dependency15__.eachHelper; + var templateHelper = __dependency16__["default"]; + var partialHelper = __dependency17__["default"]; + var yieldHelper = __dependency18__["default"]; + var locHelper = __dependency19__["default"]; - var Checkbox = __dependency18__["default"]; - var Select = __dependency19__.Select; - var SelectOption = __dependency19__.SelectOption; - var SelectOptgroup = __dependency19__.SelectOptgroup; - var TextArea = __dependency20__["default"]; - var TextField = __dependency21__["default"]; - var TextSupport = __dependency22__["default"]; - var inputHelper = __dependency23__.inputHelper; - var textareaHelper = __dependency23__.textareaHelper; + var Checkbox = __dependency20__["default"]; + var Select = __dependency21__.Select; + var SelectOption = __dependency21__.SelectOption; + var SelectOptgroup = __dependency21__.SelectOptgroup; + var TextArea = __dependency22__["default"]; + var TextField = __dependency23__["default"]; + var TextSupport = __dependency24__["default"]; + var inputHelper = __dependency25__.inputHelper; + var textareaHelper = __dependency25__.textareaHelper; - - var ComponentLookup = __dependency24__["default"]; - var _HandlebarsBoundView = __dependency25__._HandlebarsBoundView; - var SimpleHandlebarsView = __dependency25__.SimpleHandlebarsView; - var _wrapMap = __dependency26__._wrapMap; - var _SimpleMetamorphView = __dependency26__._SimpleMetamorphView; - var _MetamorphView = __dependency26__._MetamorphView; - var _Metamorph = __dependency26__._Metamorph; + var ComponentLookup = __dependency26__["default"]; + var _HandlebarsBoundView = __dependency27__._HandlebarsBoundView; + var SimpleHandlebarsView = __dependency27__.SimpleHandlebarsView; + var _MetamorphView = __dependency28__["default"]; + var _SimpleMetamorphView = __dependency28__._SimpleMetamorphView; + var _Metamorph = __dependency28__._Metamorph; /** @@ -5066,33 +5087,24 @@ enifed("ember-handlebars", // Ember.Handlebars.Globals EmberHandlebars.bootstrap = bootstrap; - EmberHandlebars.template = template; EmberHandlebars.makeBoundHelper = makeBoundHelper; EmberHandlebars.registerBoundHelper = registerBoundHelper; - EmberHandlebars.resolveHash = resolveHash; - EmberHandlebars.resolveParams = resolveParams; EmberHandlebars.resolveHelper = resolveHelper; - EmberHandlebars.get = handlebarsGet; - EmberHandlebars.getEscaped = getEscaped; - EmberHandlebars.evaluateUnboundHelper = evaluateUnboundHelper; EmberHandlebars.bind = bind; EmberHandlebars.bindClasses = bindClasses; EmberHandlebars.EachView = EachView; - EmberHandlebars.GroupedEach = GroupedEach; - EmberHandlebars.resolvePaths = resolvePaths; EmberHandlebars.ViewHelper = ViewHelper; - EmberHandlebars.normalizePath = normalizePath; // Ember Globals Ember.Handlebars = EmberHandlebars; + EmberHandlebars.get = handlebarsGet; Ember.ComponentLookup = ComponentLookup; Ember._SimpleHandlebarsView = SimpleHandlebarsView; Ember._HandlebarsBoundView = _HandlebarsBoundView; Ember._SimpleMetamorphView = _SimpleMetamorphView; Ember._MetamorphView = _MetamorphView; Ember._Metamorph = _Metamorph; - Ember._metamorphWrapMap = _wrapMap; Ember.TextSupport = TextSupport; Ember.Checkbox = Checkbox; Ember.Select = Select; @@ -5138,7 +5150,7 @@ enifed("ember-handlebars/component_lookup", "use strict"; var EmberObject = __dependency1__["default"]; - var ComponentLookup = EmberObject.extend({ + __exports__["default"] = EmberObject.extend({ lookupFactory: function(name, container) { container = container || this.container; @@ -5164,12 +5176,10 @@ enifed("ember-handlebars/component_lookup", } } }); - - __exports__["default"] = ComponentLookup; }); enifed("ember-handlebars/controls", - ["ember-handlebars/controls/checkbox","ember-handlebars/controls/text_field","ember-handlebars/controls/text_area","ember-metal/core","ember-handlebars-compiler","ember-handlebars/ext","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) { + ["ember-handlebars/controls/checkbox","ember-handlebars/controls/text_field","ember-handlebars/controls/text_area","ember-metal/core","ember-handlebars-compiler","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) { "use strict"; var Checkbox = __dependency1__["default"]; var TextField = __dependency2__["default"]; @@ -5180,21 +5190,12 @@ enifed("ember-handlebars/controls", // var emberAssert = Ember.assert; var EmberHandlebars = __dependency5__["default"]; - var handlebarsGet = __dependency6__.handlebarsGet; - var helpers = EmberHandlebars.helpers; + /** @module ember @submodule ember-handlebars-compiler */ - function _resolveOption(context, options, key) { - if (options.hashTypes[key] === "ID") { - return handlebarsGet(context, options.hash[key], options); - } else { - return options.hash[key]; - } - } - /** The `{{input}}` helper inserts an HTML `` tag into the template, @@ -5261,10 +5262,12 @@ enifed("ember-handlebars/controls", The action property defines the action which is sent when the user presses the return key. + ```handlebars {{input action="submit"}} ``` + The helper allows some user events to send actions. * `enter` @@ -5278,10 +5281,12 @@ enifed("ember-handlebars/controls", For example, if you desire an action to be sent when the input is blurred, you only need to setup the action name to the event name property. + ```handlebars {{input focus-in="alertMessage"}} ``` + See more about [Text Support Actions](/api/classes/Ember.TextField.html) ## Extension @@ -5374,23 +5379,31 @@ enifed("ember-handlebars/controls", function inputHelper(options) { Ember.assert('You can only pass attributes to the `input` helper, not arguments', arguments.length < 2); + var view = options.data.view; var hash = options.hash; var types = options.hashTypes; - var inputType = _resolveOption(this, options, 'type'); var onEvent = hash.on; + var inputType; + + if (types.type === 'ID') { + inputType = view.getStream(hash.type).value(); + } else { + inputType = hash.type; + } if (inputType === 'checkbox') { delete hash.type; delete types.type; - Ember.assert("{{input type='checkbox'}} does not support setting `value=someBooleanValue`; you must use `checked=someBooleanValue` instead.", options.hashTypes.value !== 'ID'); + Ember.assert("{{input type='checkbox'}} does not support setting `value=someBooleanValue`;" + + " you must use `checked=someBooleanValue` instead.", options.hashTypes.value !== 'ID'); - return helpers.view.call(this, Checkbox, options); + return EmberHandlebars.helpers.view.call(this, Checkbox, options); } else { delete hash.on; hash.onEvent = onEvent || 'enter'; - return helpers.view.call(this, TextField, options); + return EmberHandlebars.helpers.view.call(this, TextField, options); } } @@ -5582,10 +5595,7 @@ enifed("ember-handlebars/controls", function textareaHelper(options) { Ember.assert('You can only pass attributes to the `textarea` helper, not arguments', arguments.length < 2); - var hash = options.hash; - var types = options.hashTypes; - - return helpers.view.call(this, TextArea, options); + return EmberHandlebars.helpers.view.call(this, TextArea, options); } __exports__.textareaHelper = textareaHelper; @@ -5693,7 +5703,6 @@ enifed("ember-handlebars/controls/select", var observer = __dependency11__.observer; var defineProperty = __dependency12__.defineProperty; - var precompileTemplate = EmberHandlebars.compile; var SelectOption = View.extend({ instrumentDisplay: 'Ember.SelectOption', @@ -6005,59 +6014,42 @@ enifed("ember-handlebars/controls/select", tagName: 'select', classNames: ['ember-select'], - defaultTemplate: Ember.Handlebars.template(function anonymous(Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [4,'>= 1.0.0']; - helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {}; - var buffer = '', stack1, escapeExpression=this.escapeExpression, self=this; - - function program1(depth0,data) { - - var buffer = '', stack1; + defaultTemplate: Ember.Handlebars.template({"1":function(depth0,helpers,partials,data) { + var stack1, buffer = ''; data.buffer.push(""); return buffer; - } - - function program3(depth0,data) { - + },"3":function(depth0,helpers,partials,data) { var stack1; - stack1 = helpers.each.call(depth0, "view.groupedContent", {hash:{},hashTypes:{},hashContexts:{},inverse:self.noop,fn:self.program(4, program4, data),contexts:[depth0],types:["ID"],data:data}); - if(stack1 || stack1 === 0) { data.buffer.push(stack1); } + stack1 = helpers.each.call(depth0, "group", "in", "view.groupedContent", {"name":"each","hash":{},"hashTypes":{},"hashContexts":{},"fn":this.program(4, data),"inverse":this.noop,"types":["ID","ID","ID"],"contexts":[depth0,depth0,depth0],"data":data}); + if (stack1 != null) { data.buffer.push(stack1); } else { data.buffer.push(''); } - } - function program4(depth0,data) { - - - data.buffer.push(escapeExpression(helpers.view.call(depth0, "view.groupView", {hash:{ - 'content': ("content"), - 'label': ("label") - },hashTypes:{'content': "ID",'label': "ID"},hashContexts:{'content': depth0,'label': depth0},contexts:[depth0],types:["ID"],data:data}))); - } - - function program6(depth0,data) { - + },"4":function(depth0,helpers,partials,data) { + var escapeExpression=this.escapeExpression; + data.buffer.push(escapeExpression(helpers.view.call(depth0, "view.groupView", {"name":"view","hash":{ + 'label': ("group.label"), + 'content': ("group.content") + },"hashTypes":{'label': "ID",'content': "ID"},"hashContexts":{'label': depth0,'content': depth0},"types":["ID"],"contexts":[depth0],"data":data}))); + },"6":function(depth0,helpers,partials,data) { var stack1; - stack1 = helpers.each.call(depth0, "view.content", {hash:{},hashTypes:{},hashContexts:{},inverse:self.noop,fn:self.program(7, program7, data),contexts:[depth0],types:["ID"],data:data}); - if(stack1 || stack1 === 0) { data.buffer.push(stack1); } + stack1 = helpers.each.call(depth0, "item", "in", "view.content", {"name":"each","hash":{},"hashTypes":{},"hashContexts":{},"fn":this.program(7, data),"inverse":this.noop,"types":["ID","ID","ID"],"contexts":[depth0,depth0,depth0],"data":data}); + if (stack1 != null) { data.buffer.push(stack1); } else { data.buffer.push(''); } - } - function program7(depth0,data) { - - - data.buffer.push(escapeExpression(helpers.view.call(depth0, "view.optionView", {hash:{ - 'content': ("") - },hashTypes:{'content': "ID"},hashContexts:{'content': depth0},contexts:[depth0],types:["ID"],data:data}))); - } - - stack1 = helpers['if'].call(depth0, "view.prompt", {hash:{},hashTypes:{},hashContexts:{},inverse:self.noop,fn:self.program(1, program1, data),contexts:[depth0],types:["ID"],data:data}); - if(stack1 || stack1 === 0) { data.buffer.push(stack1); } - stack1 = helpers['if'].call(depth0, "view.optionGroupPath", {hash:{},hashTypes:{},hashContexts:{},inverse:self.program(6, program6, data),fn:self.program(3, program3, data),contexts:[depth0],types:["ID"],data:data}); - if(stack1 || stack1 === 0) { data.buffer.push(stack1); } + },"7":function(depth0,helpers,partials,data) { + var escapeExpression=this.escapeExpression; + data.buffer.push(escapeExpression(helpers.view.call(depth0, "view.optionView", {"name":"view","hash":{ + 'content': ("item") + },"hashTypes":{'content': "ID"},"hashContexts":{'content': depth0},"types":["ID"],"contexts":[depth0],"data":data}))); + },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { + var stack1, buffer = ''; + stack1 = helpers['if'].call(depth0, "view.prompt", {"name":"if","hash":{},"hashTypes":{},"hashContexts":{},"fn":this.program(1, data),"inverse":this.noop,"types":["ID"],"contexts":[depth0],"data":data}); + if (stack1 != null) { data.buffer.push(stack1); } + stack1 = helpers['if'].call(depth0, "view.optionGroupPath", {"name":"if","hash":{},"hashTypes":{},"hashContexts":{},"fn":this.program(3, data),"inverse":this.program(6, data),"types":["ID"],"contexts":[depth0],"data":data}); + if (stack1 != null) { data.buffer.push(stack1); } return buffer; - - }), + },"useData":true}), attributeBindings: ['multiple', 'disabled', 'tabindex', 'name', 'required', 'autofocus', 'form', 'size'], @@ -6385,7 +6377,16 @@ enifed("ember-handlebars/controls/text_area", classNames: ['ember-text-area'], tagName: "textarea", - attributeBindings: ['rows', 'cols', 'name', 'selectionEnd', 'selectionStart', 'wrap', 'lang', 'dir'], + attributeBindings: [ + 'rows', + 'cols', + 'name', + 'selectionEnd', + 'selectionStart', + 'wrap', + 'lang', + 'dir' + ], rows: null, cols: null, @@ -6405,18 +6406,15 @@ enifed("ember-handlebars/controls/text_area", }); }); enifed("ember-handlebars/controls/text_field", - ["ember-metal/property_get","ember-metal/property_set","ember-views/views/component","ember-handlebars/controls/text_support","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) { + ["ember-views/views/component","ember-handlebars/controls/text_support","exports"], + function(__dependency1__, __dependency2__, __exports__) { "use strict"; /** @module ember @submodule ember-handlebars */ - - var get = __dependency1__.get; - var set = __dependency2__.set; - var Component = __dependency3__["default"]; - var TextSupport = __dependency4__["default"]; + var Component = __dependency1__["default"]; + var TextSupport = __dependency2__["default"]; /** @@ -6441,11 +6439,31 @@ enifed("ember-handlebars/controls/text_field", classNames: ['ember-text-field'], tagName: "input", - attributeBindings: ['type', 'value', 'size', 'pattern', 'name', 'min', 'max', - 'accept', 'autocomplete', 'autosave', 'formaction', - 'formenctype', 'formmethod', 'formnovalidate', 'formtarget', - 'height', 'inputmode', 'list', 'multiple', 'step', 'lang', 'dir', - 'width'], + attributeBindings: [ + 'accept', + 'autocomplete', + 'autosave', + 'dir', + 'formaction', + 'formenctype', + 'formmethod', + 'formnovalidate', + 'formtarget', + 'height', + 'inputmode', + 'lang', + 'list', + 'max', + 'min', + 'multiple', + 'name', + 'pattern', + 'size', + 'step', + 'type', + 'value', + 'width' + ], /** The `value` attribute of the input element. As the user inputs text, this @@ -6531,21 +6549,30 @@ enifed("ember-handlebars/controls/text_support", var TextSupport = Mixin.create(TargetActionSupport, { value: "", - attributeBindings: ['placeholder', 'disabled', 'maxlength', 'tabindex', 'readonly', - 'autofocus', 'form', 'selectionDirection', 'spellcheck', 'required', - 'title', 'autocapitalize', 'autocorrect'], + attributeBindings: [ + 'autocapitalize', + 'autocorrect', + 'autofocus', + 'disabled', + 'form', + 'maxlength', + 'placeholder', + 'readonly', + 'required', + 'selectionDirection', + 'spellcheck', + 'tabindex', + 'title' + ], placeholder: null, disabled: false, maxlength: null, init: function() { this._super(); - this.on("focusOut", this, this._elementValueDidChange); - this.on("change", this, this._elementValueDidChange); this.on("paste", this, this._elementValueDidChange); this.on("cut", this, this._elementValueDidChange); this.on("input", this, this._elementValueDidChange); - this.on("keyUp", this, this.interpretKeyEvents); }, /** @@ -6631,6 +6658,10 @@ enifed("ember-handlebars/controls/text_support", sendAction('escape-press', this, event); }, + change: function(event) { + this._elementValueDidChange(event); + }, + /** Called when the text area is focused. @@ -6652,6 +6683,7 @@ enifed("ember-handlebars/controls/text_support", @param {Event} event */ focusOut: function(event) { + this._elementValueDidChange(event); sendAction('focus-out', this, event); }, @@ -6666,8 +6698,36 @@ enifed("ember-handlebars/controls/text_support", */ keyPress: function(event) { sendAction('key-press', this, event); - } + }, + /** + Called when the browser triggers a `keyup` event on the element. + + Uses sendAction to send the `key-up` action passing the current value + and event as parameters. + + @method keyUp + @param {Event} event + */ + keyUp: function(event) { + this.interpretKeyEvents(event); + + this.sendAction('key-up', get(this, 'value'), event); + }, + + /** + Called when the browser triggers a `keydown` event on the element. + + Uses sendAction to send the `key-down` action passing the current value + and event as parameters. Note that generally in key-down the value is unchanged + (as the key pressing has not completed yet). + + @method keyDown + @param {Event} event + */ + keyDown: function(event) { + this.sendAction('key-down', get(this, 'value'), event); + } }); TextSupport.KEY_EVENTS = { @@ -6702,8 +6762,8 @@ enifed("ember-handlebars/controls/text_support", __exports__["default"] = TextSupport; }); enifed("ember-handlebars/ext", - ["ember-metal/core","ember-runtime/system/string","ember-handlebars-compiler","ember-metal/property_get","ember-metal/error","ember-metal/mixin","ember-views/views/view","ember-handlebars/views/metamorph_view","ember-metal/path_cache","ember-metal/is_empty","ember-metal/cache","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __exports__) { + ["ember-metal/core","ember-runtime/system/string","ember-handlebars-compiler","ember-metal/property_get","ember-metal/error","ember-metal/mixin","ember-views/views/view","ember-metal/path_cache","ember-metal/streams/stream","ember-metal/streams/read","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; // Ember.FEATURES, Ember.assert, Ember.Handlebars, Ember.lookup @@ -6712,76 +6772,22 @@ enifed("ember-handlebars/ext", var fmt = __dependency2__.fmt; var EmberHandlebars = __dependency3__["default"]; - var helpers = EmberHandlebars.helpers; var get = __dependency4__.get; var EmberError = __dependency5__["default"]; var IS_BINDING = __dependency6__.IS_BINDING; var View = __dependency7__["default"]; - var _Metamorph = __dependency8__._Metamorph; - var detectIsGlobal = __dependency9__.isGlobal; + var detectIsGlobal = __dependency8__.isGlobal; // late bound via requireModule because of circular dependencies. var resolveHelper, SimpleHandlebarsView; - var isEmpty = __dependency10__["default"]; + var Stream = __dependency9__["default"]; + var readArray = __dependency10__.readArray; + var readHash = __dependency10__.readHash; var slice = [].slice; - var originalTemplate = EmberHandlebars.template; - - /** - If a path starts with a reserved keyword, returns the root - that should be used. - - @private - @method normalizePath - @for Ember - @param root {Object} - @param path {String} - @param data {Hash} - */ - - var Cache = __dependency11__["default"]; - - var FIRST_SEGMENT_CACHE = new Cache(1000, function(path){ - return path.split('.', 1)[0]; - }); - - function normalizePath(root, path, data) { - var keywords = (data && data.keywords) || {}; - var keyword, isKeyword; - - // Get the first segment of the path. For example, if the - // path is "foo.bar.baz", returns "foo". - keyword = FIRST_SEGMENT_CACHE.get(path); - - // Test to see if the first path is a keyword that has been - // passed along in the view's data hash. If so, we will treat - // that object as the new root. - if (keywords.hasOwnProperty(keyword)) { - // Look up the value in the template's data hash. - root = keywords[keyword]; - isKeyword = true; - - // Handle cases where the entire path is the reserved - // word. In that case, return the object itself. - if (path === keyword) { - path = ''; - } else { - // Strip the keyword from the path and look up - // the remainder from the newly found root. - path = path.substr(keyword.length+1); - } - } - - return { - root: root, - path: path, - isKeyword: isKeyword - }; - } - /** Lookup both on root and on window. If the path starts with @@ -6793,53 +6799,12 @@ enifed("ember-handlebars/ext", @param {Object} root The object to look up the property on @param {String} path The path to be lookedup @param {Object} options The template's option hash + @deprecated */ function handlebarsGet(root, path, options) { - var data = options && options.data; - var normalizedPath = normalizePath(root, path, data); - var value; + Ember.deprecate('Usage of Ember.Handlebars.get is deprecated, use a Component or Ember.Handlebars.makeBoundHelper instead.'); - // In cases where the path begins with a keyword, change the - // root to the value represented by that keyword, and ensure - // the path is relative to it. - root = normalizedPath.root; - path = normalizedPath.path; - - // Ember.get with a null root and GlobalPath will fall back to - // Ember.lookup, which is no longer allowed in templates. - // - // But when outputting a primitive, root will be the primitive - // and path a blank string. These primitives should pass through - // to `get`. - if (root || path === '') { - value = get(root, path); - } - - if (detectIsGlobal(path)) { - if (value === undefined && root !== Ember.lookup) { - root = Ember.lookup; - value = get(root, path); - } - if (root === Ember.lookup || root === null) { - Ember.deprecate("Global lookup of "+path+" from a Handlebars template is deprecated."); - } - } - - return value; - } - - function lookupViewInContainer(container, path) { - Ember.assert("View requires a container to resolve views not passed in through the context", !!container); - return container.lookupFactory('view:'+path); - } - - function lookupViewByClassName(path) { - var viewClass; - if (detectIsGlobal(path)) { - viewClass = get(path); - Ember.deprecate('Resolved the view "'+path+'" on the global context. Pass a view name to be looked up on the container instead, such as {{view "select"}}. http://emberjs.com/guides/deprecations#toc_global-lookup-of-views-since-1-8', !viewClass); - return viewClass; - } + return options.data.view.getStream(path).value(); } /** @@ -6866,42 +6831,32 @@ enifed("ember-handlebars/ext", @param {Object} context The context of the template being rendered @param {String} path The path to be lookedup @param {Object} container The container - @param {Object} options The options from the template + @param {Object} data The template's data hash */ - function handlebarsGetView(context, path, container, options) { + function handlebarsGetView(context, path, container, data) { var viewClass; - var data; - var pathType; - if (options) { - data = options.data; - pathType = options.types && options.types[0]; - } - if ('string' === typeof path) { - if('STRING' === pathType && container) { - viewClass = lookupViewInContainer(container, path); - Ember.deprecate('Quoted view names must refer to a view in the container.', viewClass); - + if (!data) { + throw new Error("handlebarsGetView: must pass data"); } - if(!viewClass) { - viewClass = lookupViewByClassName(path); + // Only lookup view class on context if there is a context. If not, + // the global lookup path on get may kick in. + var lazyValue = data.view.getStream(path); + viewClass = lazyValue.value(); + var isGlobal = detectIsGlobal(path); + + if (!viewClass && !isGlobal) { + Ember.assert("View requires a container to resolve views not passed in through the context", !!container); + viewClass = container.lookupFactory('view:'+path); } - - if(!viewClass) { - if (data) { - var normalizedPath = normalizePath(context, path, data); - context = normalizedPath.root; - path = normalizedPath.path; - } - - // Only lookup view class on context if there is a context. If not, - // the global lookup path on get may kick in. - viewClass = context && get(context, path); - - if(!viewClass) { - // try the container once more with the normalized path - viewClass = lookupViewInContainer(container, path); + if (!viewClass && isGlobal) { + var globalViewClass = get(path); + Ember.deprecate('Resolved the view "'+path+'" on the global context. Pass a view name to be looked' + + ' up on the container instead, such as {{view "select"}}.' + + ' http://emberjs.com/guides/deprecations#toc_global-lookup-of-views', !globalViewClass); + if (globalViewClass) { + viewClass = globalViewClass; } } } else { @@ -6910,84 +6865,32 @@ enifed("ember-handlebars/ext", // Sometimes a view's value is yet another path if ('string' === typeof viewClass && data && data.view) { - viewClass = handlebarsGetView(data.view, viewClass, container, { - data: data, - types: ['ID'] - }); + viewClass = handlebarsGetView(data.view, viewClass, container, data); } Ember.assert( - fmt(path+" must be a subclass or an instance of Ember.View, not %@", [viewClass]), - View.detect(viewClass) || View.detectInstance(viewClass) + fmt(path+" must be a subclass of Ember.View, not %@", [viewClass]), + View.detect(viewClass) ); return viewClass; } - /** - This method uses `Ember.Handlebars.get` to lookup a value, then ensures - that the value is escaped properly. - - If `unescaped` is a truthy value then the escaping will not be performed. - - @method getEscaped - @for Ember.Handlebars - @param {Object} root The object to look up the property on - @param {String} path The path to be lookedup - @param {Object} options The template's option hash - @since 1.4.0 - */ - function getEscaped(root, path, options) { - var result = handlebarsGet(root, path, options); - - if (result === null || result === undefined) { - result = ""; - } else if (!(result instanceof Handlebars.SafeString)) { - result = String(result); - } - if (!options.hash.unescaped){ - result = Handlebars.Utils.escapeExpression(result); + function stringifyValue(value, shouldEscape) { + if (value === null || value === undefined) { + value = ""; + } else if (!(value instanceof Handlebars.SafeString)) { + value = String(value); } - return result; + if (shouldEscape) { + value = Handlebars.Utils.escapeExpression(value); + } + + return value; } - __exports__.getEscaped = getEscaped;function resolveParams(context, params, options) { - var resolvedParams = [], types = options.types, param, type; - - for (var i=0, l=params.length; i 0) { + var firstParam = params[0]; + // Only bother with subscriptions if the first argument + // is a stream itself, and not a primitive. + if (firstParam && firstParam.isStream) { + var onDependentKeyNotify = function onDependentKeyNotify(stream) { + stream.value(); + lazyValue.notify(); + }; + for (i = 0; i < dependentKeys.length; i++) { + var childParam = firstParam.get(dependentKeys[i]); + childParam.value(); + childParam.subscribe(onDependentKeyNotify); + } + } + } } } - helper._rawFunction = fn; return helper; } - /** - Renders the unbound form of an otherwise bound helper function. - - @private - @method evaluateUnboundHelper - @param {Function} fn - @param {Object} context - @param {Array} normalizedProperties - @param {String} options - */ - function evaluateUnboundHelper(context, fn, normalizedProperties, options) { - var args = []; - var hash = options.hash; - var boundOptions = hash.boundOptions; - var types = slice.call(options.types, 1); - var loc, len, property, propertyType, boundOption; - - for (boundOption in boundOptions) { - if (!boundOptions.hasOwnProperty(boundOption)) { continue; } - hash[boundOption] = handlebarsGet(context, boundOptions[boundOption], options); - } - - for (loc = 0, len = normalizedProperties.length; loc < len; ++loc) { - property = normalizedProperties[loc]; - propertyType = types[loc]; - if (propertyType === "ID") { - args.push(handlebarsGet(property.root, property.path, options)); - } else { - args.push(property.path); - } - } - args.push(options); - return fn.apply(context, args); - } - - /** - Overrides Handlebars.template so that we can distinguish - user-created, top-level templates from inner contexts. - - @private - @method template - @for Ember.Handlebars - @param {String} spec - */ - function template(spec) { - var t = originalTemplate(spec); - t.isTop = true; - return t; - } - - __exports__.template = template;__exports__.normalizePath = normalizePath; __exports__.makeBoundHelper = makeBoundHelper; - __exports__.handlebarsGet = handlebarsGet; __exports__.handlebarsGetView = handlebarsGetView; - __exports__.evaluateUnboundHelper = evaluateUnboundHelper; + __exports__.handlebarsGet = handlebarsGet; }); -enifed("ember-handlebars/helpers/binding", - ["ember-metal/core","ember-handlebars-compiler","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-runtime/system/string","ember-metal/platform","ember-metal/is_none","ember-metal/enumerable_utils","ember-metal/array","ember-views/views/view","ember-metal/run_loop","ember-metal/observer","ember-metal/binding","ember-views/system/jquery","ember-handlebars/ext","ember-metal/keys","ember-metal/cache","ember-handlebars/views/handlebars_bound_view","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __dependency19__, __exports__) { +enifed("ember-handlebars/helpers/bind_attr", + ["ember-metal/core","ember-handlebars-compiler","ember-metal/utils","ember-runtime/system/string","ember-metal/array","ember-views/views/view","ember-metal/keys","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) { "use strict"; /** @module ember @@ -7388,597 +7197,19 @@ enifed("ember-handlebars/helpers/binding", */ var Ember = __dependency1__["default"]; - // Ember.assert, Ember.warn, uuid - // var emberAssert = Ember.assert, Ember.warn = Ember.warn; - + // Ember.assert var EmberHandlebars = __dependency2__["default"]; - var get = __dependency3__.get; - var set = __dependency4__.set; - var apply = __dependency5__.apply; - var uuid = __dependency5__.uuid; - var fmt = __dependency6__.fmt; - var o_create = __dependency7__.create; - var isNone = __dependency8__["default"]; - var EnumerableUtils = __dependency9__["default"]; - var forEach = __dependency10__.forEach; - var View = __dependency11__["default"]; - var run = __dependency12__["default"]; - var removeObserver = __dependency13__.removeObserver; - var isGlobalPath = __dependency14__.isGlobalPath; - var emberBind = __dependency14__.bind; - var jQuery = __dependency15__["default"]; - var isArray = __dependency5__.isArray; - var handlebarsGetEscaped = __dependency16__.getEscaped; - var keys = __dependency17__["default"]; - var Cache = __dependency18__["default"]; - var _HandlebarsBoundView = __dependency19__._HandlebarsBoundView; - var SimpleHandlebarsView = __dependency19__.SimpleHandlebarsView; - - var normalizePath = __dependency16__.normalizePath; - var handlebarsGet = __dependency16__.handlebarsGet; - var getEscaped = __dependency16__.getEscaped; - - var guidFor = __dependency5__.guidFor; - var typeOf = __dependency5__.typeOf; + var uuid = __dependency3__.uuid; + var fmt = __dependency4__.fmt; + var typeOf = __dependency3__.typeOf; + var forEach = __dependency5__.forEach; + var View = __dependency6__["default"]; + var keys = __dependency7__["default"]; var helpers = EmberHandlebars.helpers; var SafeString = EmberHandlebars.SafeString; - function exists(value) { - return !isNone(value); - } - - var WithView = _HandlebarsBoundView.extend({ - init: function() { - var controller; - - apply(this, this._super, arguments); - - var keywords = this.templateData.keywords; - var keywordName = this.templateHash.keywordName; - var keywordPath = this.templateHash.keywordPath; - var controllerName = this.templateHash.controller; - var preserveContext = this.preserveContext; - - if (controllerName) { - var previousContext = this.previousContext; - controller = this.container.lookupFactory('controller:'+controllerName).create({ - parentController: previousContext, - target: previousContext - }); - - this._generatedController = controller; - - if (!preserveContext) { - this.set('controller', controller); - - this.valueNormalizerFunc = function(result) { - controller.set('model', result); - return controller; - }; - } else { - var controllerPath = jQuery.expando + guidFor(controller); - keywords[controllerPath] = controller; - emberBind(keywords, controllerPath + '.model', keywordPath); - keywordPath = controllerPath; - } - } - - if (preserveContext) { - emberBind(keywords, keywordName, keywordPath); - } - - }, - willDestroy: function() { - this._super(); - - if (this._generatedController) { - this._generatedController.destroy(); - } - } - }); - - // Binds a property into the DOM. This will create a hook in DOM that the - // KVO system will look for and update if the property changes. - function bind(property, options, preserveContext, shouldDisplay, valueNormalizer, childProperties) { - var data = options.data; - var fn = options.fn; - var inverse = options.inverse; - var view = data.view; - var normalized, observer, i; - - // we relied on the behavior of calling without - // context to mean this === window, but when running - // "use strict", it's possible for this to === undefined; - var currentContext = this || window; - - normalized = normalizePath(currentContext, property, data); - - if (data.insideGroup) { - observer = function() { - while (view._contextView) { - view = view._contextView; - } - run.once(view, 'rerender'); - }; - - var template, context; - var result = handlebarsGet(currentContext, property, options); - - result = valueNormalizer ? valueNormalizer(result) : result; - - context = preserveContext ? currentContext : result; - if (shouldDisplay(result)) { - template = fn; - } else if (inverse) { - template = inverse; - } - - template(context, { data: options.data }); - } else { - var viewClass = _HandlebarsBoundView; - var viewOptions = { - preserveContext: preserveContext, - shouldDisplayFunc: shouldDisplay, - valueNormalizerFunc: valueNormalizer, - displayTemplate: fn, - inverseTemplate: inverse, - path: property, - pathRoot: currentContext, - previousContext: currentContext, - isEscaped: !options.hash.unescaped, - templateData: options.data, - templateHash: options.hash, - helperName: options.helperName - }; - - if (options.isWithHelper) { - viewClass = WithView; - } - - // Create the view that will wrap the output of this template/property - // and add it to the nearest view's childViews array. - // See the documentation of Ember._HandlebarsBoundView for more. - var bindView = view.createChildView(viewClass, viewOptions); - - view.appendChild(bindView); - - observer = function() { - run.scheduleOnce('render', bindView, 'rerenderIfNeeded'); - }; - } - - // Observes the given property on the context and - // tells the Ember._HandlebarsBoundView to re-render. If property - // is an empty string, we are printing the current context - // object ({{this}}) so updating it is not our responsibility. - if (typeof this === 'object' && normalized.path !== '') { - view.registerObserver(normalized.root, normalized.path, observer); - if (childProperties) { - for (i=0; i{{user.name}} - -
-
{{user.role.label}}
- {{user.role.id}} - -

{{user.role.description}}

-
- ``` - - `{{with}}` can be our best friend in these cases, - instead of writing `user.role.*` over and over, we use `{{#with user.role}}`. - Now the context within the `{{#with}} .. {{/with}}` block is `user.role` so you can do the following: - - ```handlebars -
{{user.name}}
- -
- {{#with user.role}} -
{{label}}
- {{id}} - -

{{description}}

- {{/with}} -
- ``` - - ### `as` operator - - This operator aliases the scope to a new name. It's helpful for semantic clarity and to retain - default scope or to reference from another `{{with}}` block. - - ```handlebars - // posts might not be - {{#with user.posts as blogPosts}} -
- There are {{blogPosts.length}} blog posts written by {{user.name}}. -
- - {{#each post in blogPosts}} -
  • {{post.title}}
  • - {{/each}} - {{/with}} - ``` - - Without the `as` operator, it would be impossible to reference `user.name` in the example above. - - NOTE: The alias should not reuse a name from the bound property path. - For example: `{{#with foo.bar as foo}}` is not supported because it attempts to alias using - the first part of the property path, `foo`. Instead, use `{{#with foo.bar as baz}}`. - - ### `controller` option - - Adding `controller='something'` instructs the `{{with}}` helper to create and use an instance of - the specified controller with the new context as its content. - - This is very similar to using an `itemController` option with the `{{each}}` helper. - - ```handlebars - {{#with users.posts controller='userBlogPosts'}} - {{!- The current context is wrapped in our controller instance }} - {{/with}} - ``` - - In the above example, the template provided to the `{{with}}` block is now wrapped in the - `userBlogPost` controller, which provides a very elegant way to decorate the context with custom - functions/properties. - - @method with - @for Ember.Handlebars.helpers - @param {Function} context - @param {Hash} options - @return {String} HTML string - */ - function withHelper(context, options) { - var bindContext, preserveContext, controller; - var helperName = 'with'; - - if (arguments.length === 4) { - var keywordName, path, rootPath, normalized, contextPath; - - Ember.assert("If you pass more than one argument to the with helper, it must be in the form #with foo as bar", arguments[1] === "as"); - options = arguments[3]; - keywordName = arguments[2]; - path = arguments[0]; - - if (path) { - helperName += ' ' + path + ' as ' + keywordName; - } - - Ember.assert("You must pass a block to the with helper", options.fn && options.fn !== Handlebars.VM.noop); - - var localizedOptions = o_create(options); - localizedOptions.data = o_create(options.data); - localizedOptions.data.keywords = o_create(options.data.keywords || {}); - - if (isGlobalPath(path)) { - contextPath = path; - } else { - normalized = normalizePath(this, path, options.data); - path = normalized.path; - rootPath = normalized.root; - - // This is a workaround for the fact that you cannot bind separate objects - // together. When we implement that functionality, we should use it here. - var contextKey = jQuery.expando + guidFor(rootPath); - localizedOptions.data.keywords[contextKey] = rootPath; - // if the path is '' ("this"), just bind directly to the current context - contextPath = path ? contextKey + '.' + path : contextKey; - } - - localizedOptions.hash.keywordName = keywordName; - localizedOptions.hash.keywordPath = contextPath; - - bindContext = this; - context = contextPath; - options = localizedOptions; - preserveContext = true; - } else { - Ember.assert("You must pass exactly one argument to the with helper", arguments.length === 2); - Ember.assert("You must pass a block to the with helper", options.fn && options.fn !== Handlebars.VM.noop); - - helperName += ' ' + context; - bindContext = options.contexts[0]; - preserveContext = false; - } - - options.helperName = helperName; - options.isWithHelper = true; - - return bind.call(bindContext, context, options, preserveContext, exists); - } - /** - See [boundIf](/api/classes/Ember.Handlebars.helpers.html#method_boundIf) - and [unboundIf](/api/classes/Ember.Handlebars.helpers.html#method_unboundIf) - - @method if - @for Ember.Handlebars.helpers - @param {Function} context - @param {Hash} options - @return {String} HTML string - */ - function ifHelper(context, options) { - Ember.assert("You must pass exactly one argument to the if helper", arguments.length === 2); - Ember.assert("You must pass a block to the if helper", options.fn && options.fn !== Handlebars.VM.noop); - - options.helperName = options.helperName || ('if ' + context); - - if (options.data.isUnbound) { - return helpers.unboundIf.call(options.contexts[0], context, options); - } else { - return helpers.boundIf.call(options.contexts[0], context, options); - } - } - - /** - @method unless - @for Ember.Handlebars.helpers - @param {Function} context - @param {Hash} options - @return {String} HTML string - */ - function unlessHelper(context, options) { - Ember.assert("You must pass exactly one argument to the unless helper", arguments.length === 2); - Ember.assert("You must pass a block to the unless helper", options.fn && options.fn !== Handlebars.VM.noop); - - var fn = options.fn; - var inverse = options.inverse; - var helperName = 'unless'; - - if (context) { - helperName += ' ' + context; - } - - options.fn = inverse; - options.inverse = fn; - - options.helperName = options.helperName || helperName; - - if (options.data.isUnbound) { - return helpers.unboundIf.call(options.contexts[0], context, options); - } else { - return helpers.boundIf.call(options.contexts[0], context, options); - } - } - /** `bind-attr` allows you to create a binding between DOM element attributes and Ember objects. For example: @@ -8135,21 +7366,19 @@ enifed("ember-handlebars/helpers/binding", // current value of the property as an attribute. forEach.call(attrKeys, function(attr) { var path = attrs[attr]; - var normalized; - Ember.assert(fmt("You must provide an expression as the value of bound attribute. You specified: %@=%@", [attr, path]), typeof path === 'string'); + Ember.assert(fmt("You must provide an expression as the value of bound attribute." + + " You specified: %@=%@", [attr, path]), typeof path === 'string'); - normalized = normalizePath(ctx, path, options.data); - - var value = (path === 'this') ? normalized.root : handlebarsGet(ctx, path, options); + var lazyValue = view.getStream(path); + var value = lazyValue.value(); var type = typeOf(value); - Ember.assert(fmt("Attributes must be numbers, strings or booleans, not %@", [value]), value === null || value === undefined || type === 'number' || type === 'string' || type === 'boolean'); + Ember.assert(fmt("Attributes must be numbers, strings or booleans, not %@", [value]), + value === null || value === undefined || type === 'number' || type === 'string' || type === 'boolean'); - var observer; - - observer = function observer() { - var result = handlebarsGet(ctx, path, options); + lazyValue.subscribe(view._wrapAsScheduled(function applyAttributeBindings() { + var result = lazyValue.value(); Ember.assert(fmt("Attributes must be numbers, strings or booleans, not %@", [result]), result === null || result === undefined || typeof result === 'number' || @@ -8157,26 +7386,10 @@ enifed("ember-handlebars/helpers/binding", var elem = view.$("[data-bindattr-" + dataId + "='" + dataId + "']"); - // If we aren't able to find the element, it means the element - // to which we were bound has been removed from the view. - // In that case, we can assume the template has been re-rendered - // and we need to clean up the observer. - if (!elem || elem.length === 0) { - removeObserver(normalized.root, normalized.path, observer); - return; - } + Ember.assert("An attribute binding was triggered when the element was not in the DOM", elem && elem.length !== 0); View.applyAttributeBindings(elem, attr, result); - }; - - // Add an observer to the view for when the property changes. - // When the observer fires, find the element using the - // unique data id and update the attribute to the new value. - // Note: don't add observer when path is 'this' or path - // is whole keyword e.g. {{#each x in list}} ... {{bind-attr attr="x"}} - if (path !== 'this' && !(normalized.isKeyword && normalized.path === '' )) { - view.registerObserver(normalized.root, normalized.path, observer); - } + })); // if this changes, also change the logic in ember-views/lib/views/view.js if ((type === 'string' || (type === 'number' && !isNaN(value)))) { @@ -8204,7 +7417,8 @@ enifed("ember-handlebars/helpers/binding", @return {String} HTML string */ function bindAttrHelperDeprecated() { - Ember.warn("The 'bindAttr' view helper is deprecated in favor of 'bind-attr'"); + Ember.deprecate("The 'bindAttr' view helper is deprecated in favor of 'bind-attr'"); + return helpers['bind-attr'].apply(this, arguments); } @@ -8235,24 +7449,6 @@ enifed("ember-handlebars/helpers/binding", var ret = []; var newClass, value, elem; - // Helper method to retrieve the property from the context and - // determine which class string to return, based on whether it is - // a Boolean or not. - var classStringForPath = function(root, parsedPath, options) { - var val; - var path = parsedPath.path; - - if (path === 'this') { - val = root; - } else if (path === '') { - val = true; - } else { - val = handlebarsGet(root, path, options); - } - - return View._classStringForValue(path, val, parsedPath.className, parsedPath.falsyClassName); - }; - // For each property passed, loop through and setup // an observer. forEach.call(classBindings.split(' '), function(binding) { @@ -8261,31 +7457,26 @@ enifed("ember-handlebars/helpers/binding", // closes over this variable, so it knows which string to remove when // the property changes. var oldClass; - var observer; var parsedPath = View._parsePropertyPath(binding); var path = parsedPath.path; - var pathRoot = context; - var normalized; + var initialValue; - if (path !== '' && path !== 'this') { - normalized = normalizePath(context, path, options.data); + if (path === '') { + initialValue = true; + } else { + var lazyValue = view.getStream(path); + initialValue = lazyValue.value(); - pathRoot = normalized.root; - path = normalized.path; - } + // Set up an observer on the context. If the property changes, toggle the + // class name. + lazyValue.subscribe(view._wrapAsScheduled(function applyClassNameBindings() { + // Get the current value of the property + var value = lazyValue.value(); + newClass = classStringForParsedPath(parsedPath, value); + elem = bindAttrId ? view.$("[data-bindattr-" + bindAttrId + "='" + bindAttrId + "']") : view.$(); - // Set up an observer on the context. If the property changes, toggle the - // class name. - observer = function() { - // Get the current value of the property - newClass = classStringForPath(context, parsedPath, options); - elem = bindAttrId ? view.$("[data-bindattr-" + bindAttrId + "='" + bindAttrId + "']") : view.$(); + Ember.assert("A class name binding was triggered when the element was not in the DOM", elem && elem.length !== 0); - // If we can't find the element anymore, a parent template has been - // re-rendered and we've been nuked. Remove the observer. - if (!elem || elem.length === 0) { - removeObserver(pathRoot, path, observer); - } else { // If we had previously added a class to the element, remove it. if (oldClass) { elem.removeClass(oldClass); @@ -8299,16 +7490,12 @@ enifed("ember-handlebars/helpers/binding", } else { oldClass = null; } - } - }; - - if (path !== '' && path !== 'this') { - view.registerObserver(pathRoot, path, observer); + })); } // We've already setup the observer; now we just need to figure out the // correct behavior right now on the first pass through. - value = classStringForPath(context, parsedPath, options); + value = classStringForParsedPath(parsedPath, initialValue); if (value) { ret.push(value); @@ -8322,22 +7509,238 @@ enifed("ember-handlebars/helpers/binding", return ret; } - __exports__.bind = bind; - __exports__._triageMustacheHelper = _triageMustacheHelper; - __exports__.resolveHelper = resolveHelper; - __exports__.bindHelper = bindHelper; - __exports__.boundIfHelper = boundIfHelper; - __exports__.unboundIfHelper = unboundIfHelper; - __exports__.withHelper = withHelper; - __exports__.ifHelper = ifHelper; - __exports__.unlessHelper = unlessHelper; + function classStringForParsedPath(parsedPath, value) { + return View._classStringForValue(parsedPath.path, value, parsedPath.className, parsedPath.falsyClassName); + } + + __exports__["default"] = bindAttrHelper; + __exports__.bindAttrHelper = bindAttrHelper; __exports__.bindAttrHelperDeprecated = bindAttrHelperDeprecated; __exports__.bindClasses = bindClasses; }); +enifed("ember-handlebars/helpers/binding", + ["ember-metal/core","ember-handlebars-compiler","ember-metal/is_none","ember-metal/run_loop","ember-metal/cache","ember-metal/streams/simple","ember-handlebars/views/handlebars_bound_view","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) { + "use strict"; + /** + @module ember + @submodule ember-handlebars + */ + + var Ember = __dependency1__["default"]; + // Ember.assert + var EmberHandlebars = __dependency2__["default"]; + + var isNone = __dependency3__["default"]; + var run = __dependency4__["default"]; + var Cache = __dependency5__["default"]; + var SimpleStream = __dependency6__["default"]; + + var _HandlebarsBoundView = __dependency7__._HandlebarsBoundView; + var SimpleHandlebarsView = __dependency7__.SimpleHandlebarsView; + + var helpers = EmberHandlebars.helpers; + + function exists(value) { + return !isNone(value); + } + + // Binds a property into the DOM. This will create a hook in DOM that the + // KVO system will look for and update if the property changes. + function bind(property, options, preserveContext, shouldDisplay, valueNormalizer, childProperties, _viewClass) { + var data = options.data; + var view = data.view; + + // we relied on the behavior of calling without + // context to mean this === window, but when running + // "use strict", it's possible for this to === undefined; + var currentContext = this || window; + + var valueStream = view.getStream(property); + var lazyValue; + + if (childProperties) { + lazyValue = new SimpleStream(valueStream); + + var subscriber = function(childStream) { + childStream.value(); + lazyValue.notify(); + }; + + for (var i = 0; i < childProperties.length; i++) { + var childStream = valueStream.get(childProperties[i]); + childStream.value(); + childStream.subscribe(subscriber); + } + } else { + lazyValue = valueStream; + } + + // Set up observers for observable objects + var viewClass = _viewClass || _HandlebarsBoundView; + var viewOptions = { + preserveContext: preserveContext, + shouldDisplayFunc: shouldDisplay, + valueNormalizerFunc: valueNormalizer, + displayTemplate: options.fn, + inverseTemplate: options.inverse, + lazyValue: lazyValue, + previousContext: currentContext, + isEscaped: !options.hash.unescaped, + templateData: options.data, + templateHash: options.hash, + helperName: options.helperName + }; + + if (options.keywords) { + viewOptions._keywords = options.keywords; + } + + // Create the view that will wrap the output of this template/property + // and add it to the nearest view's childViews array. + // See the documentation of Ember._HandlebarsBoundView for more. + var bindView = view.createChildView(viewClass, viewOptions); + + view.appendChild(bindView); + + lazyValue.subscribe(view._wrapAsScheduled(function() { + run.scheduleOnce('render', bindView, 'rerenderIfNeeded'); + })); + } + + function simpleBind(currentContext, lazyValue, options) { + var data = options.data; + var view = data.view; + + var bindView = new SimpleHandlebarsView( + lazyValue, !options.hash.unescaped + ); + + bindView._parentView = view; + view.appendChild(bindView); + + lazyValue.subscribe(view._wrapAsScheduled(function() { + run.scheduleOnce('render', bindView, 'rerender'); + })); + } + + /** + '_triageMustache' is used internally select between a binding, helper, or component for + the given context. Until this point, it would be hard to determine if the + mustache is a property reference or a regular helper reference. This triage + helper resolves that. + + This would not be typically invoked by directly. + + @private + @method _triageMustache + @for Ember.Handlebars.helpers + @param {String} property Property/helperID to triage + @param {Object} options hash of template/rendering options + @return {String} HTML string + */ + function _triageMustacheHelper(property, options) { + Ember.assert("You cannot pass more than one argument to the _triageMustache helper", arguments.length <= 2); + + var helper = EmberHandlebars.resolveHelper(options.data.view.container, property); + if (helper) { + return helper.call(this, options); + } + + return helpers.bind.call(this, property, options); + } + + var ISNT_HELPER_CACHE = new Cache(1000, function(key) { + return key.indexOf('-') === -1; + }); + __exports__.ISNT_HELPER_CACHE = ISNT_HELPER_CACHE; + /** + Used to lookup/resolve handlebars helpers. The lookup order is: + + * Look for a registered helper + * If a dash exists in the name: + * Look for a helper registed in the container + * Use Ember.ComponentLookup to find an Ember.Component that resolves + to the given name + + @private + @method resolveHelper + @param {Container} container + @param {String} name the name of the helper to lookup + @return {Handlebars Helper} + */ + function resolveHelper(container, name) { + if (helpers[name]) { + return helpers[name]; + } + + if (!container || ISNT_HELPER_CACHE.get(name)) { + return; + } + + var helper = container.lookup('helper:' + name); + if (!helper) { + var componentLookup = container.lookup('component-lookup:main'); + Ember.assert("Could not find 'component-lookup:main' on the provided container," + + " which is necessary for performing component lookups", componentLookup); + + var Component = componentLookup.lookupFactory(name, container); + if (Component) { + helper = EmberHandlebars.makeViewHelper(Component); + container.register('helper:' + name, helper); + } + } + return helper; + } + + + /** + `bind` can be used to display a value, then update that value if it + changes. For example, if you wanted to print the `title` property of + `content`: + + ```handlebars + {{bind "content.title"}} + ``` + + This will return the `title` property as a string, then create a new observer + at the specified path. If it changes, it will update the value in DOM. Note + that if you need to support IE7 and IE8 you must modify the model objects + properties using `Ember.get()` and `Ember.set()` for this to work as it + relies on Ember's KVO system. For all other browsers this will be handled for + you automatically. + + @private + @method bind + @for Ember.Handlebars.helpers + @param {String} property Property to bind + @param {Function} fn Context to provide for rendering + @return {String} HTML string + */ + function bindHelper(property, options) { + Ember.assert("You cannot pass more than one argument to the bind helper", arguments.length <= 2); + + var context = (options.contexts && options.contexts.length) ? options.contexts[0] : this; + + if (!options.fn) { + var lazyValue = options.data.view.getStream(property); + return simpleBind(context, lazyValue, options); + } + + options.helperName = 'bind'; + + return bind.call(context, property, options, false, exists); + } + + __exports__.bind = bind; + __exports__._triageMustacheHelper = _triageMustacheHelper; + __exports__.resolveHelper = resolveHelper; + __exports__.bindHelper = bindHelper; + }); enifed("ember-handlebars/helpers/collection", - ["ember-metal/core","ember-metal/utils","ember-handlebars-compiler","ember-runtime/system/string","ember-metal/property_get","ember-handlebars/ext","ember-handlebars/helpers/view","ember-metal/computed","ember-views/views/collection_view","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __exports__) { + ["ember-metal/core","ember-handlebars-compiler","ember-metal/mixin","ember-runtime/system/string","ember-metal/property_get","ember-metal/streams/simple","ember-handlebars/ext","ember-handlebars/helpers/view","ember-views/views/view","ember-views/views/collection_view","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __exports__) { "use strict"; /** @module ember @@ -8346,23 +7749,21 @@ enifed("ember-handlebars/helpers/collection", var Ember = __dependency1__["default"]; // Ember.assert, Ember.deprecate - var inspect = __dependency2__.inspect; // var emberAssert = Ember.assert; // emberDeprecate = Ember.deprecate; - var EmberHandlebars = __dependency3__["default"]; - var helpers = EmberHandlebars.helpers; + var EmberHandlebars = __dependency2__["default"]; + var IS_BINDING = __dependency3__.IS_BINDING; var fmt = __dependency4__.fmt; var get = __dependency5__.get; - var handlebarsGet = __dependency6__.handlebarsGet; - var handlebarsGetView = __dependency6__.handlebarsGetView; - var ViewHelper = __dependency7__.ViewHelper; - var computed = __dependency8__.computed; - var CollectionView = __dependency9__["default"]; + var SimpleStream = __dependency6__["default"]; + var handlebarsGetView = __dependency7__.handlebarsGetView; + var ViewHelper = __dependency8__.ViewHelper; + var View = __dependency9__["default"]; + var CollectionView = __dependency10__["default"]; - var alias = computed.alias; /** `{{collection}}` is a `Ember.Handlebars` helper for adding instances of `Ember.CollectionView` to a template. See [Ember.CollectionView](/api/classes/Ember.CollectionView.html) @@ -8490,7 +7891,8 @@ enifed("ember-handlebars/helpers/collection", @deprecated Use `{{each}}` helper instead. */ function collectionHelper(path, options) { - Ember.deprecate("Using the {{collection}} helper without specifying a class has been deprecated as the {{each}} helper now supports the same functionality.", path !== 'collection'); + Ember.deprecate("Using the {{collection}} helper without specifying a class has been" + + " deprecated as the {{each}} helper now supports the same functionality.", path !== 'collection'); // If no path is provided, treat path param as options. if (path && path.data && path.data.isRenderData) { @@ -8513,7 +7915,7 @@ enifed("ember-handlebars/helpers/collection", // Otherwise, just default to the standard class. var collectionClass; if (path) { - collectionClass = handlebarsGetView(this, path, container, options); + collectionClass = handlebarsGetView(this, path, container, options.data); Ember.assert(fmt("%@ #collection: Could not find collection class %@", [data.view, path]), !!collectionClass); } else { @@ -8521,6 +7923,7 @@ enifed("ember-handlebars/helpers/collection", } var hash = options.hash; + var hashTypes = options.hashTypes; var itemHash = {}; var match; @@ -8529,29 +7932,46 @@ enifed("ember-handlebars/helpers/collection", var itemViewClass; if (hash.itemView) { - itemViewClass = handlebarsGetView(this, hash.itemView, container, options); + itemViewClass = hash.itemView; } else if (hash.itemViewClass) { - itemViewClass = handlebarsGetView(collectionPrototype, hash.itemViewClass, container, options); + if (hashTypes.itemViewClass === 'ID') { + var itemViewClassStream = view.getStream(hash.itemViewClass); + Ember.deprecate('Resolved the view "'+hash.itemViewClass+'" on the global context. Pass a view name to be looked up on the container instead, such as {{view "select"}}. http://emberjs.com/guides/deprecations#toc_global-lookup-of-views', !itemViewClassStream.isGlobal()); + itemViewClass = itemViewClassStream.value(); + } else { + itemViewClass = hash.itemViewClass; + } } else { - itemViewClass = handlebarsGetView(collectionPrototype, collectionPrototype.itemViewClass, container, options); + itemViewClass = collectionPrototype.itemViewClass; + } + + if (typeof itemViewClass === 'string') { + itemViewClass = container.lookupFactory('view:'+itemViewClass); } Ember.assert(fmt("%@ #collection: Could not find itemViewClass %@", [data.view, itemViewClass]), !!itemViewClass); delete hash.itemViewClass; delete hash.itemView; + delete hashTypes.itemViewClass; + delete hashTypes.itemView; // Go through options passed to the {{collection}} helper and extract options // that configure item views instead of the collection itself. for (var prop in hash) { + if (prop === 'itemController' || prop === 'itemClassBinding') { + continue; + } if (hash.hasOwnProperty(prop)) { match = prop.match(/^item(.)(.*)$/); + if (match) { + var childProp = match[1].toLowerCase() + match[2]; - if (match && prop !== 'itemController') { - // Convert itemShouldFoo -> shouldFoo - itemHash[match[1].toLowerCase() + match[2]] = hash[prop]; - // Delete from hash as this will end up getting passed to the - // {{view}} helper method. + if (hashTypes[prop] === 'ID' || IS_BINDING.test(prop)) { + itemHash[childProp] = view._getBindingForStream(hash[prop]); + } else { + itemHash[childProp] = hash[prop]; + } delete hash[prop]; } } @@ -8570,29 +7990,47 @@ enifed("ember-handlebars/helpers/collection", tagName: itemHash.tagName }); } else if (hash.emptyViewClass) { - emptyViewClass = handlebarsGetView(this, hash.emptyViewClass, container, options); + emptyViewClass = handlebarsGetView(this, hash.emptyViewClass, container, options.data); } if (emptyViewClass) { hash.emptyView = emptyViewClass; } if (hash.keyword) { - itemHash._context = this; + itemHash._contextBinding = '_parentView.context'; } else { - itemHash._context = alias('content'); + itemHash._contextBinding = 'content'; } var viewOptions = ViewHelper.propertiesFromHTMLOptions({ data: data, hash: itemHash }, this); - hash.itemViewClass = itemViewClass.extend(viewOptions); + + if (hash.itemClassBinding) { + var itemClassBindings = hash.itemClassBinding.split(' '); + + for (var i = 0; i < itemClassBindings.length; i++) { + var parsedPath = View._parsePropertyPath(itemClassBindings[i]); + if (parsedPath.path === '') { + parsedPath.stream = new SimpleStream(true); + } else { + parsedPath.stream = view.getStream(parsedPath.path); + } + itemClassBindings[i] = parsedPath; + } + + viewOptions.classNameBindings = itemClassBindings; + } + + hash.itemViewClass = itemViewClass; + hash._itemViewProps = viewOptions; options.helperName = options.helperName || 'collection'; - return helpers.view.call(this, collectionClass, options); + return EmberHandlebars.helpers.view.call(this, collectionClass, options); } __exports__["default"] = collectionHelper; }); enifed("ember-handlebars/helpers/debug", - ["ember-metal/core","ember-metal/utils","ember-metal/logger","ember-metal/property_get","ember-handlebars/ext","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) { + ["ember-metal/core","ember-metal/utils","ember-metal/logger","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __exports__) { "use strict"; /*jshint debug:true*/ @@ -8605,10 +8043,6 @@ enifed("ember-handlebars/helpers/debug", var inspect = __dependency2__.inspect; var Logger = __dependency3__["default"]; - var get = __dependency4__.get; - var normalizePath = __dependency5__.normalizePath; - var handlebarsGet = __dependency5__.handlebarsGet; - var a_slice = [].slice; /** @@ -8626,22 +8060,14 @@ enifed("ember-handlebars/helpers/debug", function logHelper() { var params = a_slice.call(arguments, 0, -1); var options = arguments[arguments.length - 1]; + var view = options.data.view; var logger = Logger.log; var values = []; - var allowPrimitives = true; for (var i = 0; i < params.length; i++) { - var type = options.types[i]; - - if (type === 'ID' || !allowPrimitives) { - var context = (options.contexts && options.contexts[i]) || this; - var normalized = normalizePath(context, params[i], options.data); - - if (normalized.path === 'this') { - values.push(normalized.root); - } else { - values.push(handlebarsGet(normalized.root, normalized.path, options)); - } + if (options.types[i] === 'ID') { + var stream = view.getStream(params[i]); + values.push(stream.value()); } else { values.push(params[i]); } @@ -8687,6 +8113,7 @@ enifed("ember-handlebars/helpers/debug", function debuggerHelper(options) { // These are helpful values you can inspect while debugging. + /* jshint unused: false */ var templateContext = this; var typeOfTemplateContext = inspect(templateContext); Ember.Logger.info('Use `this` to access the context of the calling template.'); @@ -8698,8 +8125,8 @@ enifed("ember-handlebars/helpers/debug", __exports__.debuggerHelper = debuggerHelper; }); enifed("ember-handlebars/helpers/each", - ["ember-metal/core","ember-handlebars-compiler","ember-runtime/system/string","ember-metal/property_get","ember-metal/property_set","ember-views/views/collection_view","ember-metal/binding","ember-runtime/mixins/controller","ember-runtime/controllers/array_controller","ember-runtime/mixins/array","ember-runtime/copy","ember-metal/run_loop","ember-metal/events","ember-handlebars/ext","ember-metal/computed","ember-metal/observer","ember-handlebars/views/metamorph_view","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __exports__) { + ["ember-metal/core","ember-handlebars-compiler","ember-runtime/system/string","ember-metal/property_get","ember-metal/property_set","ember-views/views/collection_view","ember-metal/binding","ember-runtime/mixins/controller","ember-runtime/controllers/array_controller","ember-runtime/mixins/array","ember-metal/observer","ember-handlebars/views/metamorph_view","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __exports__) { "use strict"; /** @@ -8708,10 +8135,8 @@ enifed("ember-handlebars/helpers/each", */ var Ember = __dependency1__["default"]; // Ember.assert;, Ember.K - var K = Ember.K; var EmberHandlebars = __dependency2__["default"]; - var helpers = EmberHandlebars.helpers; var fmt = __dependency3__.fmt; var get = __dependency4__.get; @@ -8721,19 +8146,14 @@ enifed("ember-handlebars/helpers/each", var ControllerMixin = __dependency8__["default"]; var ArrayController = __dependency9__["default"]; var EmberArray = __dependency10__["default"]; - var copy = __dependency11__["default"]; - var run = __dependency12__["default"]; - var on = __dependency13__.on; - var handlebarsGet = __dependency14__.handlebarsGet; - var computed = __dependency15__.computed; - var addObserver = __dependency16__.addObserver; - var removeObserver = __dependency16__.removeObserver; - var addBeforeObserver = __dependency16__.addBeforeObserver; - var removeBeforeObserver = __dependency16__.removeBeforeObserver; + var addObserver = __dependency11__.addObserver; + var removeObserver = __dependency11__.removeObserver; + var addBeforeObserver = __dependency11__.addBeforeObserver; + var removeBeforeObserver = __dependency11__.removeBeforeObserver; - var _Metamorph = __dependency17__._Metamorph; - var _MetamorphView = __dependency17__._MetamorphView; + var _MetamorphView = __dependency12__["default"]; + var _Metamorph = __dependency12__._Metamorph; var EachView = CollectionView.extend(_Metamorph, { @@ -8774,7 +8194,11 @@ enifed("ember-handlebars/helpers/each", !ControllerMixin.detect(content) || (content && content.isGenerated) || content instanceof ArrayController); - Ember.assert(fmt("The value that #each loops over must be an Array. You passed %@", [(ControllerMixin.detect(content) && content.get('model') !== undefined) ? fmt("'%@' (wrapped in %@)", [content.get('model'), content]) : content]), EmberArray.detect(content)); + Ember.assert(fmt("The value that #each loops over must be an Array. You passed %@", + [(ControllerMixin.detect(content) && + content.get('model') !== undefined) ? + fmt("'%@' (wrapped in %@)", [content.get('model'), content]) : content]), + EmberArray.detect(content)); }, disableContentObservers: function(callback) { @@ -8793,22 +8217,11 @@ enifed("ember-handlebars/helpers/each", createChildView: function(view, attrs) { view = this._super(view, attrs); - // At the moment, if a container view subclass wants - // to insert keywords, it is responsible for cloning - // the keywords hash. This will be fixed momentarily. - var keyword = get(this, 'keyword'); var content = get(view, 'content'); + var keyword = get(this, 'keyword'); if (keyword) { - var data = get(view, 'templateData'); - - data = copy(data); - data.keywords = view.cloneKeywords(); - set(view, 'templateData', data); - - // In this case, we do not bind, because the `content` of - // a #each item cannot change. - data.keywords[keyword] = content; + view._keywords[keyword] = content; } // If {{#each}} is looping over an array of controllers, @@ -8833,133 +8246,17 @@ enifed("ember-handlebars/helpers/each", } }); - var GroupedEach = EmberHandlebars.GroupedEach = function(context, path, options) { - var self = this; - var normalized = EmberHandlebars.normalizePath(context, path, options.data); - - this.context = context; - this.path = path; - this.options = options; - this.template = options.fn; - this.containingView = options.data.view; - this.normalizedRoot = normalized.root; - this.normalizedPath = normalized.path; - this.content = this.lookupContent(); - - this.addContentObservers(); - this.addArrayObservers(); - - this.containingView.on('willClearRender', function() { - self.destroy(); - }); - }; - - GroupedEach.prototype = { - contentWillChange: function() { - this.removeArrayObservers(); - }, - - contentDidChange: function() { - this.content = this.lookupContent(); - this.addArrayObservers(); - this.rerenderContainingView(); - }, - - contentArrayWillChange: K, - - contentArrayDidChange: function() { - this.rerenderContainingView(); - }, - - lookupContent: function() { - return handlebarsGet(this.normalizedRoot, this.normalizedPath, this.options); - }, - - addArrayObservers: function() { - if (!this.content) { return; } - - this.content.addArrayObserver(this, { - willChange: 'contentArrayWillChange', - didChange: 'contentArrayDidChange' - }); - }, - - removeArrayObservers: function() { - if (!this.content) { return; } - - this.content.removeArrayObserver(this, { - willChange: 'contentArrayWillChange', - didChange: 'contentArrayDidChange' - }); - }, - - addContentObservers: function() { - addBeforeObserver(this.normalizedRoot, this.normalizedPath, this, this.contentWillChange); - addObserver(this.normalizedRoot, this.normalizedPath, this, this.contentDidChange); - }, - - removeContentObservers: function() { - removeBeforeObserver(this.normalizedRoot, this.normalizedPath, this.contentWillChange); - removeObserver(this.normalizedRoot, this.normalizedPath, this.contentDidChange); - }, - - render: function() { - if (!this.content) { return; } - - var content = this.content; - var contentLength = get(content, 'length'); - var options = this.options; - var data = options.data; - var template = this.template; - - data.insideEach = true; - for (var i = 0; i < contentLength; i++) { - var context = content.objectAt(i); - options.data.keywords[options.hash.keyword] = context; - template(context, { data: data }); - } - }, - - rerenderContainingView: function() { - var self = this; - run.scheduleOnce('render', this, function() { - // It's possible it's been destroyed after we enqueued a re-render call. - if (!self.destroyed) { - self.containingView.rerender(); - } - }); - }, - - destroy: function() { - this.removeContentObservers(); - if (this.content) { - this.removeArrayObservers(); - } - this.destroyed = true; - } - }; - /** The `{{#each}}` helper loops over elements in a collection. It is an extension of the base Handlebars `{{#each}}` helper. The default behavior of `{{#each}}` is to yield its inner block once for every - item in an array. Each yield will provide the item as the context of the block. + item in an array. ```javascript var developers = [{name: 'Yehuda'},{name: 'Tom'}, {name: 'Paul'}]; ``` - ```handlebars - {{#each developers}} - {{name}} - {{! `this` is each developer }} - {{/each}} - ``` - - `{{#each}}` supports an alternative syntax with element naming. This preserves - context of the yielded block: - ```handlebars {{#each person in developers}} {{person.name}} @@ -8975,8 +8272,8 @@ enifed("ember-handlebars/helpers/each", ``` ```handlebars - {{#each developerNames}} - {{this}} + {{#each name in developerNames}} + {{name}} {{/each}} ``` @@ -9002,8 +8299,8 @@ enifed("ember-handlebars/helpers/each", ```handlebars
      - {{#each developers itemViewClass="person"}} - {{name}} + {{#each developer in developers itemViewClass="person"}} + {{developer.name}} {{/each}}
    ``` @@ -9034,13 +8331,13 @@ enifed("ember-handlebars/helpers/each", ```javascript App.PersonView = Ember.View.extend({ tagName: 'li', - template: '{{name}}' + template: '{{developer.name}}' }); ``` ```handlebars
      - {{each developers itemViewClass="person"}} + {{each developer in developers itemViewClass="person"}}
    ``` @@ -9058,8 +8355,8 @@ enifed("ember-handlebars/helpers/each", ```handlebars
      - {{#each developers emptyViewClass="no-people"}} -
    • {{name}}
    • + {{#each developer in developers emptyViewClass="no-people"}} +
    • {{developer.name}}
    • {{/each}}
    ``` @@ -9090,47 +8387,6 @@ enifed("ember-handlebars/helpers/each", {{/each}} ``` - ### (Experimental) Grouped Each - - If a list's membership often changes, but properties of items in that - group rarely change, a significant improvement in template rendering - time can be achieved by using the experimental [group helper](https://github.com/emberjs/group-helper). - - ```handlebars - {{#group}} - {{#each people}} - {{firstName}} {{lastName}} - {{/each}} - {{/group}} - ``` - - When the membership of `people` changes, or when any property changes, the entire - `{{#group}}` block will be re-rendered. - - An `{{#each}}` inside the `{{#group}}` helper can opt-out of the special group - behavior by passing the `groupedRows` option. For example: - - ```handlebars - {{#group}} - {{#each dealers}} - {{! uses group's special behavior }} - {{firstName}} {{lastName}} - {{/each}} - - {{#each car in cars groupedRows=true}} - {{! does not use group's special behavior }} - {{car.make}} {{car.model}} {{car.color}} - {{/each}} - {{/group}} - ``` - - Any change to the `dealers` collection will cause the entire group to be re-rendered. - Changes to the `cars` collection will be re-rendered individually, as they are with - normal `{{#each}}` usage. - - `{{#group}}` is implemented with an `itemViewClass`, so specifying an `itemViewClass` - on an `{{#each}}` will also disable the special re-rendering behavior. - @method each @for Ember.Handlebars.helpers @param [name] {String} name for item (used with `in`) @@ -9139,54 +8395,193 @@ enifed("ember-handlebars/helpers/each", @param [options.itemViewClass] {String} a path to a view class used for each item @param [options.emptyViewClass] {String} a path to a view class used for each item @param [options.itemController] {String} name of a controller to be created for each item - @param [options.groupedRows] {boolean} enable normal item-by-item rendering when inside a `#group` helper */ - function eachHelper(path, options) { - var ctx; + function eachHelper(path) { + var options = arguments[arguments.length - 1]; var helperName = 'each'; + var keywordName; if (arguments.length === 4) { - Ember.assert("If you pass more than one argument to the each helper, it must be in the form #each foo in bar", arguments[1] === "in"); + Ember.assert("If you pass more than one argument to the each helper," + + " it must be in the form #each foo in bar", arguments[1] === "in"); - var keywordName = arguments[0]; - - - options = arguments[3]; + keywordName = arguments[0]; path = arguments[2]; helperName += ' ' + keywordName + ' in ' + path; - if (path === '') { path = "this"; } - options.hash.keyword = keywordName; - } else if (arguments.length === 1) { - options = path; - path = 'this'; + path = ''; } else { helperName += ' ' + path; } + Ember.deprecate('Using the context switching form of {{each}} is deprecated. Please use the keyword form (`{{#each foo in bar}}`) instead. See http://emberjs.com/guides/deprecations/#toc_more-consistent-handlebars-scope for more details.', keywordName); + + options.hash.emptyViewClass = Ember._MetamorphView; options.hash.dataSourceBinding = path; - // Set up emptyView as a metamorph with no tag - //options.hash.emptyViewClass = Ember._MetamorphView; - - // can't rely on this default behavior when use strict - ctx = this || window; - + options.hashTypes.dataSourceBinding = 'STRING'; options.helperName = options.helperName || helperName; - if (options.data.insideGroup && !options.hash.groupedRows && !options.hash.itemViewClass) { - new GroupedEach(ctx, path, options).render(); - } else { - return helpers.collection.call(ctx, EmberHandlebars.EachView, options); - } + return EmberHandlebars.helpers.collection.call(this, EmberHandlebars.EachView, options); } __exports__.EachView = EachView; - __exports__.GroupedEach = GroupedEach; __exports__.eachHelper = eachHelper; }); +enifed("ember-handlebars/helpers/if_unless", + ["ember-metal/core","ember-handlebars-compiler","ember-handlebars/helpers/binding","ember-metal/property_get","ember-metal/utils","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) { + "use strict"; + /** + @module ember + @submodule ember-handlebars + */ + + var Ember = __dependency1__["default"]; + // Ember.assert + var EmberHandlebars = __dependency2__["default"]; + + var bind = __dependency3__.bind; + + var get = __dependency4__.get; + var isArray = __dependency5__.isArray; + + var helpers = EmberHandlebars.helpers; + + function shouldDisplayIfHelperContent(result) { + var truthy = result && get(result, 'isTruthy'); + if (typeof truthy === 'boolean') { return truthy; } + + if (isArray(result)) { + return get(result, 'length') !== 0; + } else { + return !!result; + } + } + + /** + Use the `boundIf` helper to create a conditional that re-evaluates + whenever the truthiness of the bound value changes. + + ```handlebars + {{#boundIf "content.shouldDisplayTitle"}} + {{content.title}} + {{/boundIf}} + ``` + + @private + @method boundIf + @for Ember.Handlebars.helpers + @param {String} property Property to bind + @param {Function} fn Context to provide for rendering + @return {String} HTML string + */ + function boundIfHelper(property, fn) { + var context = (fn.contexts && fn.contexts.length) ? fn.contexts[0] : this; + + fn.helperName = fn.helperName || 'boundIf'; + + return bind.call(context, property, fn, true, shouldDisplayIfHelperContent, shouldDisplayIfHelperContent, [ + 'isTruthy', + 'length' + ]); + } + + /** + @private + + Use the `unboundIf` helper to create a conditional that evaluates once. + + ```handlebars + {{#unboundIf "content.shouldDisplayTitle"}} + {{content.title}} + {{/unboundIf}} + ``` + + @method unboundIf + @for Ember.Handlebars.helpers + @param {String} property Property to bind + @param {Function} fn Context to provide for rendering + @return {String} HTML string + @since 1.4.0 + */ + function unboundIfHelper(property, fn) { + var context = (fn.contexts && fn.contexts.length) ? fn.contexts[0] : this; + var data = fn.data; + var view = data.view; + var template = fn.fn; + var inverse = fn.inverse; + + var propertyValue = view.getStream(property).value(); + + if (!shouldDisplayIfHelperContent(propertyValue)) { + template = inverse; + } + + template(context, { data: data }); + } + + /** + See [boundIf](/api/classes/Ember.Handlebars.helpers.html#method_boundIf) + and [unboundIf](/api/classes/Ember.Handlebars.helpers.html#method_unboundIf) + + @method if + @for Ember.Handlebars.helpers + @param {Function} context + @param {Hash} options + @return {String} HTML string + */ + function ifHelper(context, options) { + Ember.assert("You must pass exactly one argument to the if helper", arguments.length === 2); + Ember.assert("You must pass a block to the if helper", options.fn && options.fn !== Handlebars.VM.noop); + + options.helperName = options.helperName || ('if ' + context); + + if (options.data.isUnbound) { + return helpers.unboundIf.call(options.contexts[0], context, options); + } else { + return helpers.boundIf.call(options.contexts[0], context, options); + } + } + + /** + @method unless + @for Ember.Handlebars.helpers + @param {Function} context + @param {Hash} options + @return {String} HTML string + */ + function unlessHelper(context, options) { + Ember.assert("You must pass exactly one argument to the unless helper", arguments.length === 2); + Ember.assert("You must pass a block to the unless helper", options.fn && options.fn !== Handlebars.VM.noop); + + var fn = options.fn; + var inverse = options.inverse; + var helperName = 'unless'; + + if (context) { + helperName += ' ' + context; + } + + options.fn = inverse; + options.inverse = fn; + + options.helperName = options.helperName || helperName; + + if (options.data.isUnbound) { + return helpers.unboundIf.call(options.contexts[0], context, options); + } else { + return helpers.boundIf.call(options.contexts[0], context, options); + } + } + + __exports__.ifHelper = ifHelper; + __exports__.boundIfHelper = boundIfHelper; + __exports__.unboundIfHelper = unboundIfHelper; + __exports__.unlessHelper = unlessHelper; + }); enifed("ember-handlebars/helpers/loc", ["ember-runtime/system/string","exports"], function(__dependency1__, __exports__) { @@ -9233,16 +8628,15 @@ enifed("ember-handlebars/helpers/loc", __exports__["default"] = loc; }); enifed("ember-handlebars/helpers/partial", - ["ember-metal/core","ember-metal/is_none","ember-handlebars/ext","ember-handlebars/helpers/binding","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) { + ["ember-metal/core","ember-metal/is_none","ember-handlebars/helpers/binding","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; // Ember.assert // var emberAssert = Ember.assert; - var isNone = __dependency2__.isNone; - var handlebarsGet = __dependency3__.handlebarsGet; - var bind = __dependency4__.bind; + var isNone = __dependency2__["default"]; + var bind = __dependency3__.bind; /** @module ember @@ -9283,16 +8677,6 @@ enifed("ember-handlebars/helpers/partial", changes, the partial will be re-rendered using the new template name. - ## Setting the partial's context with `with` - - The `partial` helper can be used in conjunction with the `with` - helper to set a context that will be used by the partial: - - ```handlebars - {{#with currentUser}} - {{partial "user_info"}} - {{/with}} - ``` @method partial @for Ember.Handlebars.helpers @@ -9300,18 +8684,19 @@ enifed("ember-handlebars/helpers/partial", */ __exports__["default"] = function partialHelper(name, options) { + var view = options.data.view; var context = (options.contexts && options.contexts.length) ? options.contexts[0] : this; options.helperName = options.helperName || 'partial'; if (options.types[0] === "ID") { + var partialNameStream = view.getStream(name); // Helper was passed a property path; we need to // create a binding that will re-render whenever // this property changes. options.fn = function(context, fnOptions) { - var partialName = handlebarsGet(context, name, fnOptions); - renderPartial(context, partialName, fnOptions); + renderPartial(context, partialNameStream.value(), fnOptions); }; return bind.call(context, name, options, true, exists); @@ -9340,26 +8725,9 @@ enifed("ember-handlebars/helpers/partial", template = template || deprecatedTemplate; - template(context, { data: options.data }); - } - }); -enifed("ember-handlebars/helpers/shared", - ["ember-handlebars/ext","exports"], - function(__dependency1__, __exports__) { - "use strict"; - var handlebarsGet = __dependency1__.handlebarsGet; - - __exports__["default"] = function resolvePaths(options) { - var ret = []; - var contexts = options.contexts; - var roots = options.roots; - var data = options.data; - - for (var i=0, l=contexts.length; i 2) { - // Unbound helper call. + if (argsLength <= 2) { + return view.getStream(property).value(); + } else { options.data.isUnbound = true; - helper = resolveHelper(container, property) || helpers.helperMissing; - out = helper.apply(ctx, slice.call(arguments, 1)); - delete options.data.isUnbound; - return out; - } + options.types.shift(); - context = (fn.contexts && fn.contexts.length) ? fn.contexts[0] : ctx; - return handlebarsGet(context, property, fn); + var args = new Array(argsLength - 1); + for (var i = 1; i < argsLength; i++) { + args[i - 1] = arguments[i]; + } + + var helper = resolveHelper(container, property) || EmberHandlebars.helpers.helperMissing; + + // Attempt to exec the first field as a helper + options.name = arguments[0]; + + var result = helper.apply(this, args); + + delete options.data.isUnbound; + return result; + } } }); enifed("ember-handlebars/helpers/view", - ["ember-metal/core","ember-runtime/system/object","ember-metal/property_get","ember-metal/property_set","ember-metal/mixin","ember-views/system/jquery","ember-views/views/view","ember-metal/binding","ember-metal/keys","ember-handlebars/ext","ember-runtime/system/string","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __exports__) { + ["ember-metal/core","ember-runtime/system/object","ember-metal/property_get","ember-metal/keys","ember-metal/mixin","ember-views/streams/read","ember-views/views/view","ember-metal/streams/simple","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) { "use strict"; - /*globals Handlebars */ - /** @module ember @submodule ember-handlebars @@ -9465,54 +8835,62 @@ enifed("ember-handlebars/helpers/view", var EmberObject = __dependency2__["default"]; var get = __dependency3__.get; - var set = __dependency4__.set; + var keys = __dependency4__["default"]; var IS_BINDING = __dependency5__.IS_BINDING; - var jQuery = __dependency6__["default"]; + var readViewFactory = __dependency6__.readViewFactory; var View = __dependency7__["default"]; - var isGlobalPath = __dependency8__.isGlobalPath; - var keys = __dependency9__["default"]; - var normalizePath = __dependency10__.normalizePath; - var handlebarsGet = __dependency10__.handlebarsGet; - var handlebarsGetView = __dependency10__.handlebarsGetView; - var EmberString = __dependency11__["default"]; + var SimpleStream = __dependency8__["default"]; - - var LOWERCASE_A_Z = /^[a-z]/; - var VIEW_PREFIX = /^view\./; - - function makeBindings(thisContext, options) { + function makeBindings(options) { var hash = options.hash; - var hashType = options.hashTypes; + var hashTypes = options.hashTypes; + var view = options.data.view; for (var prop in hash) { - if (hashType[prop] === 'ID') { + var hashType = hashTypes[prop]; + var value = hash[prop]; - var value = hash[prop]; + if (IS_BINDING.test(prop)) { + // classBinding is processed separately + if (prop === 'classBinding') { + continue; + } - if (IS_BINDING.test(prop)) { - Ember.warn("You're attempting to render a view by passing " + prop + "=" + value + " to a view helper, but this syntax is ambiguous. You should either surround " + value + " in quotes or remove `Binding` from " + prop + "."); - } else { - hash[prop + 'Binding'] = value; - hashType[prop + 'Binding'] = 'STRING'; + if (hashType === 'ID') { + Ember.warn("You're attempting to render a view by passing " + + prop + "=" + value + + " to a view helper, but this syntax is ambiguous. You should either surround " + + value + " in quotes or remove `Binding` from " + prop + "."); + hash[prop] = view._getBindingForStream(value); + } else if (typeof value === 'string') { + hash[prop] = view._getBindingForStream(value); + } + } else { + if (hashType === 'ID') { + if (prop === 'class') { + hash.classBinding = value; + } else { + hash[prop + 'Binding'] = view._getBindingForStream(value); + } delete hash[prop]; - delete hashType[prop]; + delete hashTypes[prop]; } } } - if (hash.hasOwnProperty('idBinding')) { + if (hash.idBinding) { // id can't be bound, so just perform one-time lookup. - hash.id = handlebarsGet(thisContext, hash.idBinding, options); - hashType.id = 'STRING'; + hash.id = hash.idBinding.value(); + hashTypes.id = 'STRING'; delete hash.idBinding; - delete hashType.idBinding; + delete hashTypes.idBinding; } } var ViewHelper = EmberObject.create({ propertiesFromHTMLOptions: function(options) { + var view = options.data.view; var hash = options.hash; - var data = options.data; var classes = hash['class']; var extensions = { @@ -9544,100 +8922,55 @@ enifed("ember-handlebars/helpers/view", } if (hash.attributeBindings) { - Ember.assert("Setting 'attributeBindings' via Handlebars is not allowed. Please subclass Ember.View and set it there instead."); + Ember.assert("Setting 'attributeBindings' via Handlebars is not allowed." + + " Please subclass Ember.View and set it there instead."); extensions.attributeBindings = null; } // Set the proper context for all bindings passed to the helper. This applies to regular attribute bindings // as well as class name bindings. If the bindings are local, make them relative to the current context // instead of the view. - var path; + var hashKeys = keys(hash); for (var i = 0, l = hashKeys.length; i < l; i++) { - var prop = hashKeys[i]; - var isBinding = IS_BINDING.test(prop); + var prop = hashKeys[i]; if (prop !== 'classNameBindings') { extensions[prop] = hash[prop]; } - - // Test if the property ends in "Binding" - if (isBinding && typeof extensions[prop] === 'string') { - path = this.contextualizeBindingPath(hash[prop], data); - if (path) { - extensions[prop] = path; - } - } } - if (extensions.classNameBindings) { - // Evaluate the context of class name bindings: - for (var j = 0, k = extensions.classNameBindings.length; j < k; j++) { - var full = extensions.classNameBindings[j]; - - if (typeof full === 'string') { - // Contextualize the path of classNameBinding so this: - // - // classNameBinding="isGreen:green" - // - // is converted to this: - // - // classNameBinding="_parentView.context.isGreen:green" - var parsedPath = View._parsePropertyPath(full); - if (parsedPath.path !== '') { - path = this.contextualizeBindingPath(parsedPath.path, data); - if (path) { - extensions.classNameBindings[j] = path + parsedPath.classNames; - } - } + var classNameBindings = extensions.classNameBindings; + if (classNameBindings) { + for (var j = 0; j < classNameBindings.length; j++) { + var parsedPath = View._parsePropertyPath(classNameBindings[j]); + if (parsedPath.path === '') { + parsedPath.stream = new SimpleStream(true); + } else { + parsedPath.stream = view.getStream(parsedPath.path); } + classNameBindings[j] = parsedPath; } } return extensions; }, - // Transform bindings from the current context to a context that can be evaluated within the view. - // Returns null if the path shouldn't be changed. - // - // TODO: consider the addition of a prefix that would allow this method to return `path`. - contextualizeBindingPath: function(path, data) { - var normalized = normalizePath(null, path, data); - if (normalized.isKeyword) { - return 'templateData.keywords.' + path; - } else if (isGlobalPath(path)) { - return null; - } else if (path === 'this' || path === '') { - return '_parentView.context'; - } else { - return '_parentView.context.' + path; - } - }, - - helper: function(thisContext, path, options) { + helper: function(thisContext, newView, options) { var data = options.data; var fn = options.fn; - var newView; - var newViewProto; - makeBindings(thisContext, options); - - var container = this.container || (data && data.view && data.view.container); - newView = handlebarsGetView(thisContext, path, container, options); - - if (View.detectInstance(newView)) { - newViewProto = newView; - } else { - newViewProto = newView.proto(); - } + makeBindings(options); var viewOptions = this.propertiesFromHTMLOptions(options, thisContext); var currentView = data.view; viewOptions.templateData = data; + var newViewProto = newView.proto(); if (fn) { - Ember.assert("You cannot provide a template block if you also specified a templateName", !get(viewOptions, 'templateName') && !get(newViewProto, 'templateName')); + Ember.assert("You cannot provide a template block if you also specified a templateName", + !get(viewOptions, 'templateName') && !get(newViewProto, 'templateName')); viewOptions.template = fn; } @@ -9654,7 +8987,7 @@ enifed("ember-handlebars/helpers/view", var data = options.data; var fn = options.fn; - makeBindings(thisContext, options); + makeBindings(options); Ember.assert( 'Only a instance of a view may be passed to the ViewHelper.instanceHelper', @@ -9666,13 +8999,15 @@ enifed("ember-handlebars/helpers/view", viewOptions.templateData = data; if (fn) { - Ember.assert("You cannot provide a template block if you also specified a templateName", !get(viewOptions, 'templateName') && !get(newView, 'templateName')); + Ember.assert("You cannot provide a template block if you also specified a templateName", + !get(viewOptions, 'templateName') && !get(newView, 'templateName')); viewOptions.template = fn; } // We only want to override the `_context` computed property if there is // no specified controller. See View#_context for more information. - if (!newView.controller && !newView.controllerBinding && !viewOptions.controller && !viewOptions.controllerBinding) { + if (!newView.controller && !newView.controllerBinding && + !viewOptions.controller && !viewOptions.controllerBinding) { viewOptions._context = thisContext; } @@ -9858,27 +9193,199 @@ enifed("ember-handlebars/helpers/view", @param {Hash} options @return {String} HTML string */ - function viewHelper(path, options) { + function viewHelper(path) { Ember.assert("The view helper only takes a single argument", arguments.length <= 2); + var options = arguments[arguments.length - 1]; + var types = options.types; + var view = options.data.view; + var container = view.container || view._keywords.view.value().container; + var viewClass; + // If no path is provided, treat path param as options // and get an instance of the registered `view:toplevel` - if (path && path.data && path.data.isRenderData) { - options = path; - if (options.data && options.data.view && options.data.view.container) { - path = options.data.view.container.lookupFactory('view:toplevel'); + if (arguments.length === 1) { + if (container) { + viewClass = container.lookupFactory('view:toplevel'); } else { - path = View; + viewClass = View; } + } else { + var pathStream; + if (typeof path === 'string' && types[0] === 'ID') { + pathStream = view.getStream(path); + Ember.deprecate('Resolved the view "'+path+'" on the global context. Pass a view name to be looked up on the container instead, such as {{view "select"}}. http://emberjs.com/guides/deprecations#toc_global-lookup-of-views', !pathStream.isGlobal()); + } else { + pathStream = path; + } + + viewClass = readViewFactory(pathStream, container); } options.helperName = options.helperName || 'view'; - return ViewHelper.helper(this, path, options); + return ViewHelper.helper(this, viewClass, options); } __exports__.viewHelper = viewHelper; }); +enifed("ember-handlebars/helpers/with", + ["ember-metal/core","ember-metal/property_set","ember-metal/utils","ember-metal/platform","ember-metal/is_none","ember-handlebars/helpers/binding","ember-handlebars/views/handlebars_bound_view","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) { + "use strict"; + /** + @module ember + @submodule ember-handlebars + */ + + var Ember = __dependency1__["default"]; + // Ember.assert + + var set = __dependency2__.set; + var apply = __dependency3__.apply; + var o_create = __dependency4__.create; + var isNone = __dependency5__["default"]; + var bind = __dependency6__.bind; + var _HandlebarsBoundView = __dependency7__._HandlebarsBoundView; + + function exists(value) { + return !isNone(value); + } + + var WithView = _HandlebarsBoundView.extend({ + init: function() { + apply(this, this._super, arguments); + + var keywordName = this.templateHash.keywordName; + var controllerName = this.templateHash.controller; + + if (controllerName) { + var previousContext = this.previousContext; + var controller = this.container.lookupFactory('controller:'+controllerName).create({ + parentController: previousContext, + target: previousContext + }); + + this._generatedController = controller; + + if (this.preserveContext) { + this._keywords[keywordName] = controller; + this.lazyValue.subscribe(function(modelStream) { + set(controller, 'model', modelStream.value()); + }); + } else { + set(this, 'controller', controller); + this.valueNormalizerFunc = function(result) { + controller.set('model', result); + return controller; + }; + } + + set(controller, 'model', this.lazyValue.value()); + } + }, + + willDestroy: function() { + this._super(); + + if (this._generatedController) { + this._generatedController.destroy(); + } + } + }); + + /** + Use the `{{with}}` helper when you want to aliases the to a new name. It's helpful + for semantic clarity and to retain default scope or to reference from another + `{{with}}` block. + + ```handlebars + // posts might not be + {{#with user.posts as blogPosts}} +
    + There are {{blogPosts.length}} blog posts written by {{user.name}}. +
    + + {{#each post in blogPosts}} +
  • {{post.title}}
  • + {{/each}} + {{/with}} + ``` + + Without the `as` operator, it would be impossible to reference `user.name` in the example above. + + NOTE: The alias should not reuse a name from the bound property path. + For example: `{{#with foo.bar as foo}}` is not supported because it attempts to alias using + the first part of the property path, `foo`. Instead, use `{{#with foo.bar as baz}}`. + + ### `controller` option + + Adding `controller='something'` instructs the `{{with}}` helper to create and use an instance of + the specified controller wrapping the aliased keyword. + + This is very similar to using an `itemController` option with the `{{each}}` helper. + + ```handlebars + {{#with users.posts as posts controller='userBlogPosts'}} + {{!- `posts` is wrapped in our controller instance }} + {{/with}} + ``` + + In the above example, the `posts` keyword is now wrapped in the `userBlogPost` controller, + which provides an elegant way to decorate the context with custom + functions/properties. + + @method with + @for Ember.Handlebars.helpers + @param {Function} context + @param {Hash} options + @return {String} HTML string + */ + __exports__["default"] = function withHelper(contextPath) { + var options = arguments[arguments.length - 1]; + var view = options.data.view; + var bindContext, preserveContext; + var helperName = 'with'; + + if (arguments.length === 4) { + Ember.assert("If you pass more than one argument to the with helper," + + " it must be in the form #with foo as bar", arguments[1] === "as"); + + var keywordName = arguments[2]; + + if (contextPath) { + helperName += ' ' + contextPath + ' as ' + keywordName; + } + + Ember.assert("You must pass a block to the with helper", options.fn && options.fn !== Handlebars.VM.noop); + + var localizedOptions = o_create(options); + localizedOptions.data = o_create(options.data); + + localizedOptions.keywords = {}; + localizedOptions.keywords[keywordName] = view.getStream(contextPath); + + localizedOptions.hash.keywordName = keywordName; + + bindContext = this; + options = localizedOptions; + preserveContext = true; + } else { + Ember.deprecate('Using the context switching form of `{{with}}` is deprecated. Please use the keyword form (`{{with foo as bar}}`) instead. See http://emberjs.com/guides/deprecations/#toc_more-consistent-handlebars-scope for more details.'); + + Ember.assert("You must pass exactly one argument to the with helper", arguments.length === 2); + Ember.assert("You must pass a block to the with helper", options.fn && options.fn !== Handlebars.VM.noop); + + helperName += ' ' + contextPath; + bindContext = options.contexts[0]; + preserveContext = false; + } + + options.helperName = helperName; + + return bind.call(bindContext, contextPath, options, preserveContext, exists, undefined, undefined, WithView); + } + }); enifed("ember-handlebars/helpers/yield", ["ember-metal/core","ember-metal/property_get","exports"], function(__dependency1__, __dependency2__, __exports__) { @@ -10111,6 +9618,10 @@ enifed("ember-handlebars/string", @return {Handlebars.SafeString} a string that will not be html escaped by Handlebars */ function htmlSafe(str) { + if (str === null || str === undefined) { + return ""; + } + if (typeof str !== 'string') { str = ''+str; } @@ -10141,10 +9652,9 @@ enifed("ember-handlebars/string", __exports__["default"] = htmlSafe; }); enifed("ember-handlebars/views/handlebars_bound_view", - ["ember-handlebars-compiler","ember-metal/core","ember-metal/error","ember-metal/property_get","ember-metal/property_set","ember-metal/merge","ember-metal/run_loop","ember-views/views/view","ember-handlebars/string","ember-views/views/states","ember-handlebars/views/metamorph_view","ember-handlebars/ext","ember-metal/utils","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __exports__) { + ["ember-handlebars-compiler","ember-metal/core","ember-metal/error","ember-metal/property_get","ember-metal/property_set","ember-metal/merge","ember-metal/run_loop","ember-handlebars/string","ember-views/views/states","ember-handlebars/views/metamorph_view","ember-metal/utils","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __exports__) { "use strict"; - /*globals Handlebars, Metamorph:true */ /*jshint newcap:false*/ @@ -10155,7 +9665,6 @@ enifed("ember-handlebars/views/handlebars_bound_view", var EmberHandlebars = __dependency1__["default"]; // EmberHandlebars.SafeString; - var SafeString = EmberHandlebars.SafeString; var Ember = __dependency2__["default"]; // Ember.K @@ -10166,21 +9675,16 @@ enifed("ember-handlebars/views/handlebars_bound_view", var set = __dependency5__.set; var merge = __dependency6__["default"]; var run = __dependency7__["default"]; - var View = __dependency8__["default"]; - var htmlSafe = __dependency9__["default"]; - var cloneStates = __dependency10__.cloneStates; - var states = __dependency10__.states; - var viewStates = states; + var htmlSafe = __dependency8__["default"]; + var cloneStates = __dependency9__.cloneStates; + var viewStates = __dependency9__.states; - var _MetamorphView = __dependency11__["default"]; - var handlebarsGet = __dependency12__.handlebarsGet; - var uuid = __dependency13__.uuid; + var _MetamorphView = __dependency10__["default"]; + var uuid = __dependency11__.uuid; - function SimpleHandlebarsView(path, pathRoot, isEscaped, templateData) { - this.path = path; - this.pathRoot = pathRoot; + function SimpleHandlebarsView(lazyValue, isEscaped) { + this.lazyValue = lazyValue; this.isEscaped = isEscaped; - this.templateData = templateData; this[Ember.GUID_KEY] = uuid(); this._lastNormalizedValue = undefined; this.state = 'preRender'; @@ -10211,23 +9715,11 @@ enifed("ember-handlebars/views/handlebars_bound_view", propertyDidChange: K, normalizedValue: function() { - var path = this.path; - var pathRoot = this.pathRoot; - var escape = this.isEscaped; - var result, templateData; + var result = this.lazyValue.value(); - // Use the pathRoot as the result if no path is provided. This - // happens if the path is `this`, which gets normalized into - // a `pathRoot` of the current Handlebars context and a path - // of `''`. - if (path === '') { - result = pathRoot; - } else { - templateData = this.templateData; - result = handlebarsGet(pathRoot, path, { data: templateData }); - } - - if (!escape && !(result instanceof SafeString)) { + if (result === null || result === undefined) { + result = ""; + } else if (!this.isEscaped && !(result instanceof EmberHandlebars.SafeString)) { result = htmlSafe(result); } @@ -10258,7 +9750,7 @@ enifed("ember-handlebars/views/handlebars_bound_view", update: function () { this.updateId = null; var value = this.normalizedValue(); - // doesn't diff SafeString instances + // doesn't diff EmberHandlebars.SafeString instances if (value !== this._lastNormalizedValue) { this._lastNormalizedValue = value; this._morph.update(value); @@ -10270,7 +9762,7 @@ enifed("ember-handlebars/views/handlebars_bound_view", } }; - states = cloneStates(viewStates); + var states = cloneStates(viewStates); merge(states._default, { rerenderIfNeeded: K @@ -10358,49 +9850,12 @@ enifed("ember-handlebars/views/handlebars_bound_view", */ inverseTemplate: null, - - /** - The path to look up on `pathRoot` that is passed to - `shouldDisplayFunc` to determine which template to render. - - In addition, if `preserveContext` is `false,` the object at this path will - be passed to the template when rendering. - - @property path - @type String - @default null - */ - path: null, - - /** - The object from which the `path` will be looked up. Sometimes this is the - same as the `previousContext`, but in cases where this view has been - generated for paths that start with a keyword such as `view` or - `controller`, the path root will be that resolved object. - - @property pathRoot - @type Object - */ - pathRoot: null, + lazyValue: null, normalizedValue: function() { - var path = get(this, 'path'); - var pathRoot = get(this, 'pathRoot'); + var value = this.lazyValue.value(); var valueNormalizer = get(this, 'valueNormalizerFunc'); - var result, templateData; - - // Use the pathRoot as the result if no path is provided. This - // happens if the path is `this`, which gets normalized into - // a `pathRoot` of the current Handlebars context and a path - // of `''`. - if (path === '') { - result = pathRoot; - } else { - templateData = get(this, 'templateData'); - result = handlebarsGet(pathRoot, path, { data: templateData }); - } - - return valueNormalizer ? valueNormalizer(result) : result; + return valueNormalizer ? valueNormalizer(value) : value; }, rerenderIfNeeded: function() { @@ -10459,7 +9914,7 @@ enifed("ember-handlebars/views/handlebars_bound_view", // expression to the render context and return. if (result === null || result === undefined) { result = ""; - } else if (!(result instanceof SafeString)) { + } else if (!(result instanceof EmberHandlebars.SafeString)) { result = String(result); } @@ -10488,11 +9943,9 @@ enifed("ember-handlebars/views/handlebars_bound_view", __exports__.SimpleHandlebarsView = SimpleHandlebarsView; }); enifed("ember-handlebars/views/metamorph_view", - ["ember-metal/core","ember-views/views/core_view","ember-views/views/view","ember-metal/mixin","ember-metal/run_loop","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) { + ["ember-metal/core","ember-views/views/core_view","ember-views/views/view","ember-metal/mixin","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) { "use strict"; - /* global Metamorph:true */ - /*jshint newcap:false*/ var Ember = __dependency1__["default"]; // Ember.deprecate @@ -10500,17 +9953,12 @@ enifed("ember-handlebars/views/metamorph_view", var CoreView = __dependency2__["default"]; var View = __dependency3__["default"]; var Mixin = __dependency4__.Mixin; - var run = __dependency5__["default"]; /** @module ember @submodule ember-handlebars */ - function notifyMutationListeners() { - run.once(View, 'notifyMutationListeners'); - } - // The `morph` and `outerHTML` properties are internal only // and not observable. @@ -10527,7 +9975,8 @@ enifed("ember-handlebars/views/metamorph_view", init: function() { this._super(); - Ember.deprecate('Supplying a tagName to Metamorph views is unreliable and is deprecated. You may be setting the tagName on a Handlebars helper that creates a Metamorph.', !this.tagName); + Ember.deprecate('Supplying a tagName to Metamorph views is unreliable and is deprecated.' + + ' You may be setting the tagName on a Handlebars helper that creates a Metamorph.', !this.tagName); } }); __exports__._Metamorph = _Metamorph; @@ -10538,8 +9987,8 @@ enifed("ember-handlebars/views/metamorph_view", @uses Ember._Metamorph @private */ - var _MetamorphView = View.extend(_Metamorph); - __exports__._MetamorphView = _MetamorphView; + __exports__["default"] = View.extend(_Metamorph); + /** @class _SimpleMetamorphView @namespace Ember @@ -10548,7 +9997,7 @@ enifed("ember-handlebars/views/metamorph_view", @private */ var _SimpleMetamorphView = CoreView.extend(_Metamorph); - __exports__._SimpleMetamorphView = _SimpleMetamorphView;__exports__["default"] = View.extend(_Metamorph); + __exports__._SimpleMetamorphView = _SimpleMetamorphView; }); enifed("ember-metal-views", ["ember-metal-views/renderer","exports"], @@ -10599,7 +10048,7 @@ enifed("ember-metal-views/renderer", var level = 0; var view = _view; - var children, i, l, child; + var children, i, child; while (length) { elements[level] = element; if (!view._morph) { @@ -10673,7 +10122,7 @@ enifed("ember-metal-views/renderer", this.insertElement(view, _parentView, element, insertAt); - for (i=total-1;i>=0;i--) { + for (i=total-1; i>=0; i--) { if (willInsert) { views[i]._elementInserted = true; this.didInsertElement(views[i]); @@ -10700,7 +10149,7 @@ enifed("ember-metal-views/renderer", Ember.assert("You cannot insert a View without a morph", morph); view._morph = morph; var viewId = this.uuid(view); - this._inserts[viewId] = this.scheduleRender(this, function() { + this._inserts[viewId] = this.scheduleRender(this, function scheduledRenderTree() { this._inserts[viewId] = null; this.renderTree(view); }); @@ -10733,8 +10182,7 @@ enifed("ember-metal-views/renderer", var removeQueue = []; var destroyQueue = []; var morph = _view._morph; - var idx, len, view, staticChildren, queue, - childViews, i, l, parentView; + var idx, len, view, queue, childViews, i, l; removeQueue.push(_view); @@ -10864,30 +10312,30 @@ enifed("ember-metal", var Ember = __dependency1__["default"]; var merge = __dependency2__["default"]; var instrument = __dependency3__.instrument; + var reset = __dependency3__.reset; var subscribe = __dependency3__.subscribe; var unsubscribe = __dependency3__.unsubscribe; - var reset = __dependency3__.reset; - var generateGuid = __dependency4__.generateGuid; - var GUID_KEY = __dependency4__.GUID_KEY; - var guidFor = __dependency4__.guidFor; - var META_DESC = __dependency4__.META_DESC; var EMPTY_META = __dependency4__.EMPTY_META; - var meta = __dependency4__.meta; - var getMeta = __dependency4__.getMeta; - var setMeta = __dependency4__.setMeta; - var metaPath = __dependency4__.metaPath; - var inspect = __dependency4__.inspect; - var typeOf = __dependency4__.typeOf; - var tryCatchFinally = __dependency4__.tryCatchFinally; - var isArray = __dependency4__.isArray; - var makeArray = __dependency4__.makeArray; - var canInvoke = __dependency4__.canInvoke; - var tryInvoke = __dependency4__.tryInvoke; - var tryFinally = __dependency4__.tryFinally; - var wrap = __dependency4__.wrap; + var GUID_KEY = __dependency4__.GUID_KEY; + var META_DESC = __dependency4__.META_DESC; var apply = __dependency4__.apply; var applyStr = __dependency4__.applyStr; + var canInvoke = __dependency4__.canInvoke; + var generateGuid = __dependency4__.generateGuid; + var getMeta = __dependency4__.getMeta; + var guidFor = __dependency4__.guidFor; + var inspect = __dependency4__.inspect; + var isArray = __dependency4__.isArray; + var makeArray = __dependency4__.makeArray; + var meta = __dependency4__.meta; + var metaPath = __dependency4__.metaPath; + var setMeta = __dependency4__.setMeta; + var tryCatchFinally = __dependency4__.tryCatchFinally; + var tryFinally = __dependency4__.tryFinally; + var tryInvoke = __dependency4__.tryInvoke; + var typeOf = __dependency4__.typeOf; var uuid = __dependency4__.uuid; + var wrap = __dependency4__.wrap; var EmberError = __dependency5__["default"]; var EnumerableUtils = __dependency6__["default"]; var Cache = __dependency7__["default"]; @@ -10899,55 +10347,55 @@ enifed("ember-metal", var map = __dependency9__.map; var Logger = __dependency10__["default"]; + var _getPath = __dependency11__._getPath; var get = __dependency11__.get; var getWithDefault = __dependency11__.getWithDefault; var normalizeTuple = __dependency11__.normalizeTuple; - var _getPath = __dependency11__._getPath; - var on = __dependency12__.on; var addListener = __dependency12__.addListener; + var hasListeners = __dependency12__.hasListeners; + var listenersDiff = __dependency12__.listenersDiff; + var listenersFor = __dependency12__.listenersFor; + var listenersUnion = __dependency12__.listenersUnion; + var on = __dependency12__.on; var removeListener = __dependency12__.removeListener; + var sendEvent = __dependency12__.sendEvent; 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 ObserverSet = __dependency13__["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 endPropertyChanges = __dependency14__.endPropertyChanges; + var overrideChains = __dependency14__.overrideChains; + var propertyDidChange = __dependency14__.propertyDidChange; + var propertyWillChange = __dependency14__.propertyWillChange; var Descriptor = __dependency15__.Descriptor; var defineProperty = __dependency15__.defineProperty; var set = __dependency16__.set; var trySet = __dependency16__.trySet; - var OrderedSet = __dependency17__.OrderedSet; var Map = __dependency17__.Map; var MapWithDefault = __dependency17__.MapWithDefault; + var OrderedSet = __dependency17__.OrderedSet; 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 flushPendingChains = __dependency21__.flushPendingChains; + var removeChainWatcher = __dependency21__.removeChainWatcher; 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 isWatching = __dependency23__.isWatching; + var rewatch = __dependency23__.rewatch; + var unwatch = __dependency23__.unwatch; + var watch = __dependency23__.watch; var expandProperties = __dependency24__["default"]; var ComputedProperty = __dependency25__.ComputedProperty; var computed = __dependency25__.computed; @@ -10955,34 +10403,32 @@ enifed("ember-metal", // side effect of defining the computed.* macros - 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 _suspendObserver = __dependency27__._suspendObserver; var _suspendObservers = __dependency27__._suspendObservers; + var addBeforeObserver = __dependency27__.addBeforeObserver; + var addObserver = __dependency27__.addObserver; var beforeObserversFor = __dependency27__.beforeObserversFor; + var observersFor = __dependency27__.observersFor; var removeBeforeObserver = __dependency27__.removeBeforeObserver; + var removeObserver = __dependency27__.removeObserver; 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 immediateObserver = __dependency28__.immediateObserver; + var mixin = __dependency28__.mixin; + var observer = __dependency28__.observer; + var required = __dependency28__.required; var Binding = __dependency29__.Binding; - var isGlobalPath = __dependency29__.isGlobalPath; var bind = __dependency29__.bind; + var isGlobalPath = __dependency29__.isGlobalPath; 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 isNone = __dependency32__["default"]; + var isEmpty = __dependency33__["default"]; var isBlank = __dependency34__["default"]; var isPresent = __dependency35__["default"]; var keys = __dependency36__["default"]; @@ -11135,11 +10581,7 @@ enifed("ember-metal", Ember.libraries.registerCoreLibrary('Ember', Ember.VERSION); Ember.isNone = isNone; - Ember.none = none; - Ember.isEmpty = isEmpty; - Ember.empty = empty; - Ember.isBlank = isBlank; @@ -11180,26 +10622,28 @@ enifed("ember-metal", __exports__["default"] = Ember; }); enifed("ember-metal/alias", - ["ember-metal/property_get","ember-metal/property_set","ember-metal/error","ember-metal/properties","ember-metal/computed","ember-metal/platform","ember-metal/utils","ember-metal/dependent_keys","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) { + ["ember-metal/property_get","ember-metal/property_set","ember-metal/core","ember-metal/error","ember-metal/properties","ember-metal/computed","ember-metal/platform","ember-metal/utils","ember-metal/dependent_keys","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __exports__) { "use strict"; var get = __dependency1__.get; var set = __dependency2__.set; - var EmberError = __dependency3__["default"]; - var Descriptor = __dependency4__.Descriptor; - var defineProperty = __dependency4__.defineProperty; - var ComputedProperty = __dependency5__.ComputedProperty; - var create = __dependency6__.create; - var meta = __dependency7__.meta; - var inspect = __dependency7__.inspect; - var addDependentKeys = __dependency8__.addDependentKeys; - var removeDependentKeys = __dependency8__.removeDependentKeys; + var Ember = __dependency3__["default"]; + // Ember.assert + var EmberError = __dependency4__["default"]; + var Descriptor = __dependency5__.Descriptor; + var defineProperty = __dependency5__.defineProperty; + var ComputedProperty = __dependency6__.ComputedProperty; + var create = __dependency7__.create; + var meta = __dependency8__.meta; + var inspect = __dependency8__.inspect; + var addDependentKeys = __dependency9__.addDependentKeys; + var removeDependentKeys = __dependency9__.removeDependentKeys; - function alias(altKey) { + __exports__["default"] = function alias(altKey) { return new AliasedProperty(altKey); } - __exports__.alias = alias;function AliasedProperty(altKey) { + function AliasedProperty(altKey) { this.altKey = altKey; this._dependentKeys = [ altKey ]; } @@ -11223,6 +10667,7 @@ enifed("ember-metal/alias", }; AliasedProperty.prototype.setup = function(obj, keyName) { + Ember.assert("Setting alias '" + keyName + "' on self", this.altKey !== keyName); var m = meta(obj); if (m.watching[keyName]) { addDependentKeys(this, obj, keyName, m); @@ -11397,7 +10842,6 @@ enifed("ember-metal/binding", var Ember = __dependency1__["default"]; // Ember.Logger, Ember.LOG_BINDINGS, assert var get = __dependency2__.get; - var set = __dependency3__.set; var trySet = __dependency3__.trySet; var guidFor = __dependency4__.guidFor; var addObserver = __dependency5__.addObserver; @@ -11560,7 +11004,9 @@ enifed("ember-metal/binding", addObserver(obj, fromPath, this, this.fromDidChange); // if the binding is a two-way binding, also set up an observer on the target - if (!this._oneWay) { addObserver(obj, toPath, this, this.toDidChange); } + if (!this._oneWay) { + addObserver(obj, toPath, this, this.toDidChange); + } this._readyToSync = true; @@ -11585,7 +11031,9 @@ enifed("ember-metal/binding", removeObserver(obj, this._from, this, this.fromDidChange); // if the binding is two-way, remove the observer from the target as well - if (twoWay) { removeObserver(obj, this._to, this, this.toDidChange); } + if (twoWay) { + removeObserver(obj, this._to, this, this.toDidChange); + } this._readyToSync = false; // disable scheduled syncs... return this; @@ -11899,10 +11347,7 @@ enifed("ember-metal/cache", this.func = func; } - var FALSE = function() { }; - var ZERO = function() { }; var UNDEFINED = function() { }; - var NULL = function() { }; Cache.prototype = { set: function(key, value) { @@ -11951,12 +11396,11 @@ enifed("ember-metal/chains", // warn, assert, etc; var get = __dependency2__.get; var normalizeTuple = __dependency2__.normalizeTuple; - var meta = __dependency3__.meta; + var metaFor = __dependency3__.meta; var forEach = __dependency4__.forEach; var watchKey = __dependency5__.watchKey; var unwatchKey = __dependency5__.unwatchKey; - var metaFor = meta; var warn = Ember.warn; var FIRST_KEY = /^([^\.]+)/; @@ -11975,9 +11419,12 @@ enifed("ember-metal/chains", var queue = pendingQueue; pendingQueue = []; - forEach.call(queue, function(q) { q[0].add(q[1]); }); + forEach.call(queue, function(q) { + q[0].add(q[1]); + }); - warn('Watching an undefined global, Ember expects watched globals to be setup by the time the run loop is flushed, check for typos', pendingQueue.length === 0); + warn('Watching an undefined global, Ember expects watched globals to be' + + ' setup by the time the run loop is flushed, check for typos', pendingQueue.length === 0); } __exports__.flushPendingChains = flushPendingChains;function addChainWatcher(obj, keyName, node) { @@ -11990,7 +11437,9 @@ enifed("ember-metal/chains", nodes = m.chainWatchers = {}; } - if (!nodes[keyName]) { nodes[keyName] = []; } + if (!nodes[keyName]) { + nodes[keyName] = []; + } nodes[keyName].push(node); watchKey(obj, keyName, m); } @@ -12034,7 +11483,9 @@ enifed("ember-metal/chains", this._paths = {}; if (this._watching) { this._object = parent.value(); - if (this._object) { addChainWatcher(this._object, this._key, this); } + if (this._object) { + addChainWatcher(this._object, this._key, this); + } } // Special-case: the EachProxy relies on immediate evaluation to @@ -12054,9 +11505,13 @@ enifed("ember-metal/chains", var meta = obj['__ember_meta__']; // check if object meant only to be a prototype - if (meta && meta.proto === obj) return undefined; + if (meta && meta.proto === obj) { + return undefined; + } - if (key === "@each") return get(obj, key); + if (key === "@each") { + return get(obj, key); + } // if a CP only return cached value var desc = meta && meta.descs[key]; @@ -12082,7 +11537,9 @@ enifed("ember-metal/chains", ChainNodePrototype.destroy = function() { if (this._watching) { var obj = this._object; - if (obj) { removeChainWatcher(obj, this._key, this); } + if (obj) { + removeChainWatcher(obj, this._key, this); + } this._watching = false; // so future calls do nothing } }; @@ -12094,7 +11551,10 @@ enifed("ember-metal/chains", var path; for (path in paths) { - if (paths[path] <= 0) { continue; } // this check will also catch non-number vals. + // this check will also catch non-number vals. + if (paths[path] <= 0) { + continue; + } ret.add(path); } return ret; @@ -12141,7 +11601,9 @@ enifed("ember-metal/chains", var obj, tuple, key, src, paths; paths = this._paths; - if (paths[path] > 0) { paths[path]--; } + if (paths[path] > 0) { + paths[path]--; + } obj = this.value(); tuple = normalizeTuple(obj, path); @@ -12164,10 +11626,14 @@ enifed("ember-metal/chains", ChainNodePrototype.chain = function(key, path, src) { var chains = this._chains; var node; - if (!chains) { chains = this._chains = {}; } + if (!chains) { + chains = this._chains = {}; + } node = chains[key]; - if (!node) { node = chains[key] = new ChainNode(this, key, src); } + if (!node) { + node = chains[key] = new ChainNode(this, key, src); + } node.count++; // count chains... // chain rest of path if there is one @@ -12183,10 +11649,10 @@ enifed("ember-metal/chains", var node = chains[key]; // unchain rest of path first... - if (path && path.length>1) { - key = firstKey(path); - path = path.slice(key.length+1); - node.unchain(key, path); + if (path && path.length > 1) { + var nextKey = firstKey(path); + var nextPath = path.slice(nextKey.length + 1); + node.unchain(nextKey, nextPath); } // delete node if needed. @@ -12202,16 +11668,22 @@ enifed("ember-metal/chains", var chains = this._chains; if (chains) { for(var key in chains) { - if (!chains.hasOwnProperty(key)) { continue; } + if (!chains.hasOwnProperty(key)) { + continue; + } chains[key].willChange(events); } } - if (this._parent) { this._parent.chainWillChange(this, this._key, 1, events); } + if (this._parent) { + this._parent.chainWillChange(this, this._key, 1, events); + } }; ChainNodePrototype.chainWillChange = function(chain, path, depth, events) { - if (this._key) { path = this._key + '.' + path; } + if (this._key) { + path = this._key + '.' + path; + } if (this._parent) { this._parent.chainWillChange(this, path, depth+1, events); @@ -12227,7 +11699,10 @@ enifed("ember-metal/chains", }; ChainNodePrototype.chainDidChange = function(chain, path, depth, events) { - if (this._key) { path = this._key + '.' + path; } + if (this._key) { + path = this._key + '.' + path; + } + if (this._parent) { this._parent.chainDidChange(this, path, depth+1, events); } else { @@ -12254,8 +11729,9 @@ enifed("ember-metal/chains", // Special-case: the EachProxy relies on immediate evaluation to // establish its observers. - if (this._parent && this._parent._key === '@each') + if (this._parent && this._parent._key === '@each') { this.value(); + } } // then notify chains... @@ -12268,22 +11744,30 @@ enifed("ember-metal/chains", } // if no events are passed in then we only care about the above wiring update - if (events === null) { return; } + if (events === null) { + return; + } // and finally tell parent about my path changing... - if (this._parent) { this._parent.chainDidChange(this, this._key, 1, events); } + if (this._parent) { + this._parent.chainDidChange(this, this._key, 1, events); + } }; function finishChains(obj) { // We only create meta if we really have to - var m = obj['__ember_meta__'], - chains, chainWatchers, chainNodes; + var m = obj['__ember_meta__']; + var chains, chainWatchers, chainNodes; + if (m) { // finish any current chains node watchers that reference obj chainWatchers = m.chainWatchers; if (chainWatchers) { for(var key in chainWatchers) { - if (!chainWatchers.hasOwnProperty(key)) { continue; } + if (!chainWatchers.hasOwnProperty(key)) { + continue; + } + chainNodes = chainWatchers[key]; if (chainNodes) { for (var i=0,l=chainNodes.length;i 0) { - mixin.mixins = a_map.call(args, function(x) { - if (x instanceof Mixin) { return x; } - - // Note: Manually setup a primitive mixin here. This is the only - // way to actually get a primitive mixin. This way normal creation - // of mixins will give you combined mixins... - var mixin = new Mixin(); - mixin.properties = x; - return mixin; - }); - } - return mixin; - } - function isMethod(obj) { return 'function' === typeof obj && obj.isMethod !== false && - obj !== Boolean && obj !== Object && obj !== Number && obj !== Array && obj !== Date && obj !== String; + obj !== Boolean && + obj !== Object && + obj !== Number && + obj !== Array && + obj !== Date && + obj !== String; } var CONTINUE = {}; @@ -16192,6 +15721,10 @@ enifed("ember-metal/mixin", return property; } + var sourceAvailable = (function() { + return this; + }).toString().indexOf('return this;') > -1; + function giveMethodSuper(obj, key, method, values, descs) { var superMethod; @@ -16210,7 +15743,21 @@ enifed("ember-metal/mixin", return method; } - return wrap(method, superMethod); + var hasSuper; + if (sourceAvailable) { + hasSuper = method.__hasSuper; + + if (hasSuper === undefined) { + hasSuper = method.toString().indexOf('_super') > -1; + method.__hasSuper = hasSuper; + } + } + + if (sourceAvailable === false || hasSuper) { + return wrap(method, superMethod); + } else { + return method; + } } function applyConcatenatedProperties(obj, key, value, values) { @@ -16218,7 +15765,11 @@ enifed("ember-metal/mixin", if (baseValue) { if ('function' === typeof baseValue.concat) { - return baseValue.concat(value); + if (value === null || value === undefined) { + return baseValue; + } else { + return baseValue.concat(value); + } } else { return makeArray(baseValue).concat(value); } @@ -16337,6 +15888,31 @@ enifed("ember-metal/mixin", } } + function connectStreamBinding(obj, key, stream) { + var onNotify = function(stream) { + _suspendObserver(obj, key, null, didChange, function() { + trySet(obj, key, stream.value()); + }); + }; + + var didChange = function() { + stream.setValue(get(obj, key), onNotify); + }; + + // Initialize value + set(obj, key, stream.value()); + + addObserver(obj, key, null, didChange); + + stream.subscribe(onNotify); + + if (obj._streamBindingSubscriptions === undefined) { + obj._streamBindingSubscriptions = o_create(null); + } + + obj._streamBindingSubscriptions[key] = onNotify; + } + function connectBindings(obj, m) { // TODO Mixin.apply(instance) should disconnect binding if exists var bindings = m.bindings; @@ -16346,7 +15922,10 @@ enifed("ember-metal/mixin", binding = bindings[key]; if (binding) { to = key.slice(0, -7); // strip Binding off end - if (binding instanceof Binding) { + if (binding.isStream) { + connectStreamBinding(obj, to, binding); + continue; + } else if (binding instanceof Binding) { binding = binding.copy(); // copy prototypes' instance binding.to(to); } else { // binding is string path @@ -16524,12 +16103,29 @@ enifed("ember-metal/mixin", @namespace Ember */ __exports__["default"] = Mixin; - function Mixin() { return initMixin(this, arguments); } - Mixin.prototype = { - properties: null, - mixins: null, - ownerConstructor: null - }; + function Mixin(args, properties) { + this.properties = properties; + + var length = args && args.length; + + if (length > 0) { + var m = new Array(length); + + for (var i = 0; i < length; i++) { + var x = args[i]; + if (x instanceof Mixin) { + m[i] = x; + } else { + m[i] = new Mixin(undefined, x); + } + } + + this.mixins = m; + } else { + this.mixins = undefined; + } + this.ownerConstructor = undefined; + } Mixin._apply = applyMixin; @@ -16552,7 +16148,12 @@ enifed("ember-metal/mixin", // ES6TODO: this relies on a global state? Ember.anyUnprocessedMixins = true; var M = this; - return initMixin(new M(), arguments); + var length = arguments.length; + var args = new Array(length); + for (var i = 0; i < length; i++) { + args[i] = arguments[i]; + } + return new M(args, undefined); }; var MixinPrototype = Mixin.prototype; @@ -16562,12 +16163,11 @@ enifed("ember-metal/mixin", @param arguments* */ MixinPrototype.reopen = function() { - var mixin, tmp; + var mixin; if (this.properties) { - mixin = Mixin.create(); - mixin.properties = this.properties; - delete this.properties; + mixin = new Mixin(undefined, this.properties); + this.properties = undefined; this.mixins = [mixin]; } else if (!this.mixins) { this.mixins = []; @@ -16580,14 +16180,13 @@ enifed("ember-metal/mixin", 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]'); + typeof mixin === 'object' && mixin !== null && + Object.prototype.toString.call(mixin) !== '[object Array]'); if (mixin instanceof Mixin) { mixins.push(mixin); } else { - tmp = Mixin.create(); - tmp.properties = mixin; - mixins.push(tmp); + mixins.push(new Mixin(undefined, mixin)); } } @@ -16639,7 +16238,7 @@ enifed("ember-metal/mixin", }; MixinPrototype.without = function() { - var ret = new Mixin(this); + var ret = new Mixin([this]); ret._without = a_slice.call(arguments); return ret; }; @@ -16664,7 +16263,9 @@ enifed("ember-metal/mixin", var ret = []; _keys(keys, this, seen); for(var key in keys) { - if (keys.hasOwnProperty(key)) { ret.push(key); } + if (keys.hasOwnProperty(key)) { + ret.push(key); + } } return ret; }; @@ -16814,7 +16415,8 @@ enifed("ember-metal/mixin", function immediateObserver() { for (var i=0, l=arguments.length; i

    My great app

    {{render "navigation"}} @@ -21593,25 +21559,26 @@ enifed("ember-routing-handlebars/helpers/render", */ __exports__["default"] = function renderHelper(name, contextString, options) { var length = arguments.length; - var contextProvided = length === 3; - var container, router, controller, view, context, lookupOptions; + var container, router, controller, view, initialContext; - container = (options || contextString).data.keywords.controller.container; + container = (options || contextString).data.view._keywords.controller.value().container; router = container.lookup('router:main'); if (length === 2) { // use the singleton controller options = contextString; contextString = undefined; - Ember.assert("You can only use the {{render}} helper once without a model object as its second argument, as in {{render \"post\" post}}.", !router || !router._lookupActiveView(name)); + Ember.assert("You can only use the {{render}} helper once without a model object as its" + + " second argument, as in {{render \"post\" post}}.", !router || !router._lookupActiveView(name)); } else if (length === 3) { // create a new controller - context = handlebarsGet(options.contexts[1], contextString, options); + initialContext = options.data.view.getStream(contextString).value(); } else { throw new EmberError("You must pass a templateName to render"); } - Ember.deprecate("Using a quoteless parameter with {{render}} is deprecated. Please update to quoted usage '{{render \"" + name + "\"}}.", options.types[0] !== 'ID'); + Ember.deprecate("Using a quoteless parameter with {{render}} is deprecated. Please update to" + + " quoted usage '{{render \"" + name + "\"}}.", options.types[0] !== 'ID'); // # legacy namespace name = name.replace(/\//g, '.'); @@ -21625,18 +21592,19 @@ enifed("ember-routing-handlebars/helpers/render", var controllerFullName = 'controller:' + controllerName; if (options.hash.controller) { - Ember.assert("The controller name you supplied '" + controllerName + "' did not resolve to a controller.", container.has(controllerFullName)); + Ember.assert("The controller name you supplied '" + controllerName + + "' did not resolve to a controller.", container.has(controllerFullName)); } - var parentController = options.data.keywords.controller; + var parentController = options.data.view._keywords.controller.value(); // choose name if (length > 2) { var factory = container.lookupFactory(controllerFullName) || - generateControllerFactory(container, controllerName, context); + generateControllerFactory(container, controllerName, initialContext); controller = factory.create({ - model: context, + modelBinding: options.data.view._getBindingForStream(contextString), parentController: parentController, target: parentController }); @@ -21654,23 +21622,16 @@ enifed("ember-routing-handlebars/helpers/render", }); } - var root = options.contexts[1]; - - if (root) { - view.registerObserver(root, contextString, function() { - controller.set('model', handlebarsGet(root, contextString, options)); - }); - } - options.hash.viewName = camelize(name); var templateName = 'template:' + name; - Ember.assert("You used `{{render '" + name + "'}}`, but '" + name + "' can not be found as either a template or a view.", container.has("view:" + name) || container.has(templateName) || options.fn); + Ember.assert("You used `{{render '" + name + "'}}`, but '" + name + "' can not be found as either" + + " a template or a view.", container.has("view:" + name) || container.has(templateName) || options.fn); options.hash.template = container.lookup(templateName); options.hash.controller = controller; - if (router && !context) { + if (router && !initialContext) { router._connectActiveView(name, view); } @@ -21679,102 +21640,9 @@ enifed("ember-routing-handlebars/helpers/render", ViewHelper.instanceHelper(this, view, options); } }); -enifed("ember-routing-handlebars/helpers/shared", - ["ember-metal/property_get","ember-metal/array","ember-runtime/mixins/controller","ember-handlebars/ext","ember-metal/utils","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) { - "use strict"; - var get = __dependency1__.get; - var map = __dependency2__.map; - var ControllerMixin = __dependency3__["default"]; - var handlebarsResolve = __dependency4__.resolveParams; - var handlebarsGet = __dependency4__.handlebarsGet; - var typeOf = __dependency5__.typeOf; - var get = __dependency1__.get; - - function routeArgs(targetRouteName, models, queryParams) { - var args = []; - if (typeOf(targetRouteName) === 'string') { - args.push('' + targetRouteName); - } - args.push.apply(args, models); - args.push({ queryParams: queryParams }); - return args; - } - - __exports__.routeArgs = routeArgs;function getActiveTargetName(router) { - var handlerInfos = router.activeTransition ? - router.activeTransition.state.handlerInfos : - router.state.handlerInfos; - return handlerInfos[handlerInfos.length - 1].name; - } - - __exports__.getActiveTargetName = getActiveTargetName;function resolveParams(context, params, options) { - return map.call(resolvePaths(context, params, options), function(path, i) { - if (null === path) { - // Param was string/number, not a path, so just return raw string/number. - return params[i]; - } else { - return handlebarsGet(context, path, options); - } - }); - } - - __exports__.resolveParams = resolveParams;function stashParamNames(router, handlerInfos) { - if (handlerInfos._namesStashed) { return; } - - // This helper exists because router.js/route-recognizer.js awkwardly - // keeps separate a handlerInfo's list of parameter names depending - // on whether a URL transition or named transition is happening. - // Hopefully we can remove this in the future. - var targetRouteName = handlerInfos[handlerInfos.length-1].name; - var recogHandlers = router.router.recognizer.handlersFor(targetRouteName); - var dynamicParent = null; - - for (var i = 0, len = handlerInfos.length; i < len; ++i) { - var handlerInfo = handlerInfos[i]; - var names = recogHandlers[i].names; - - if (names.length) { - dynamicParent = handlerInfo; - } - - handlerInfo._names = names; - - var route = handlerInfo.handler; - route._stashNames(handlerInfo, dynamicParent); - } - - handlerInfos._namesStashed = true; - } - - __exports__.stashParamNames = stashParamNames;function resolvePaths(context, params, options) { - var resolved = handlebarsResolve(context, params, options); - var types = options.types; - - return map.call(resolved, function(object, i) { - if (types[i] === 'ID') { - return unwrap(object, params[i]); - } else { - return null; - } - }); - - function unwrap(object, path) { - if (path === 'controller') { return path; } - - if (ControllerMixin.detect(object)) { - return unwrap(get(object, 'model'), path ? path + '.model' : 'model'); - } else { - return path; - } - } - } - - __exports__.resolvePaths = resolvePaths; - }); enifed("ember-routing", - ["ember-handlebars","ember-metal/core","ember-routing/ext/run_loop","ember-routing/ext/controller","ember-routing/ext/view","ember-routing/location/api","ember-routing/location/none_location","ember-routing/location/hash_location","ember-routing/location/history_location","ember-routing/location/auto_location","ember-routing/system/generate_controller","ember-routing/system/controller_for","ember-routing/system/dsl","ember-routing/system/router","ember-routing/system/route","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __exports__) { + ["ember-metal/core","ember-routing/ext/run_loop","ember-routing/ext/controller","ember-routing/ext/view","ember-routing/location/api","ember-routing/location/none_location","ember-routing/location/hash_location","ember-routing/location/history_location","ember-routing/location/auto_location","ember-routing/system/generate_controller","ember-routing/system/controller_for","ember-routing/system/dsl","ember-routing/system/router","ember-routing/system/route","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __exports__) { "use strict"; /** Ember Routing @@ -21784,23 +21652,22 @@ enifed("ember-routing", @requires ember-views */ - var EmberHandlebars = __dependency1__["default"]; - var Ember = __dependency2__["default"]; + var Ember = __dependency1__["default"]; // ES6TODO: Cleanup modules with side-effects below - var EmberLocation = __dependency6__["default"]; - var NoneLocation = __dependency7__["default"]; - var HashLocation = __dependency8__["default"]; - var HistoryLocation = __dependency9__["default"]; - var AutoLocation = __dependency10__["default"]; + var EmberLocation = __dependency5__["default"]; + var NoneLocation = __dependency6__["default"]; + var HashLocation = __dependency7__["default"]; + var HistoryLocation = __dependency8__["default"]; + var AutoLocation = __dependency9__["default"]; - var generateControllerFactory = __dependency11__.generateControllerFactory; - var generateController = __dependency11__["default"]; - var controllerFor = __dependency12__["default"]; - var RouterDSL = __dependency13__["default"]; - var Router = __dependency14__["default"]; - var Route = __dependency15__["default"]; + var generateControllerFactory = __dependency10__.generateControllerFactory; + var generateController = __dependency10__["default"]; + var controllerFor = __dependency11__["default"]; + var RouterDSL = __dependency12__["default"]; + var Router = __dependency13__["default"]; + var Route = __dependency14__["default"]; Ember.Location = EmberLocation; Ember.AutoLocation = AutoLocation; @@ -21818,8 +21685,8 @@ enifed("ember-routing", __exports__["default"] = Ember; }); enifed("ember-routing/ext/controller", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/computed","ember-metal/utils","ember-metal/merge","ember-metal/enumerable_utils","ember-runtime/mixins/controller","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) { + ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/computed","ember-metal/utils","ember-metal/merge","ember-runtime/mixins/controller","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; // FEATURES, deprecate @@ -21829,9 +21696,8 @@ enifed("ember-routing/ext/controller", var typeOf = __dependency5__.typeOf; var meta = __dependency5__.meta; var merge = __dependency6__["default"]; - var map = __dependency7__.map; - var ControllerMixin = __dependency8__["default"]; + var ControllerMixin = __dependency7__["default"]; /** @module ember @@ -21847,6 +21713,11 @@ enifed("ember-routing/ext/controller", }, /** + Defines which query parameters the controller accepts. + If you give the names ['category','page'] it will bind + the values of these query parameters to the variables + `this.category` and `this.page` + @property queryParams @public */ @@ -22173,8 +22044,6 @@ enifed("ember-routing/ext/run_loop", // resolve), which is used in router transitions to prevent unnecessary // loading state entry if all context promises resolve on the // 'actions' queue first. - - var queues = run.queues; run._addQueue('routerTransitions', 'actions'); }); enifed("ember-routing/ext/view", @@ -22199,7 +22068,7 @@ enifed("ember-routing/ext/view", @method init */ init: function() { - set(this, '_outlets', {}); + this._outlets = {}; this._super(); }, @@ -22335,13 +22204,11 @@ enifed("ember-routing/ext/view", __exports__["default"] = EmberView; }); enifed("ember-routing/location/api", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __exports__) { + ["ember-metal/core","exports"], + function(__dependency1__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; // deprecate, assert - var get = __dependency2__.get; - var set = __dependency3__.set; /** @module ember @@ -22514,7 +22381,8 @@ enifed("ember-routing/location/api", container directly. */ registerImplementation: function(name, implementation) { - Ember.deprecate('Using the Ember.Location.registerImplementation is no longer supported. Register your custom location implementation with the container instead.', false); + Ember.deprecate('Using the Ember.Location.registerImplementation is no longer supported.' + + ' Register your custom location implementation with the container instead.', false); this.implementations[name] = implementation; }, @@ -22547,18 +22415,17 @@ enifed("ember-routing/location/api", }; }); enifed("ember-routing/location/auto_location", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-routing/location/api","ember-routing/location/history_location","ember-routing/location/hash_location","ember-routing/location/none_location","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) { + ["ember-metal/core","ember-metal/property_set","ember-routing/location/api","ember-routing/location/history_location","ember-routing/location/hash_location","ember-routing/location/none_location","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; // FEATURES - var get = __dependency2__.get; - var set = __dependency3__.set; + var set = __dependency2__.set; - var EmberLocation = __dependency4__["default"]; - var HistoryLocation = __dependency5__["default"]; - var HashLocation = __dependency6__["default"]; - var NoneLocation = __dependency7__["default"]; + var EmberLocation = __dependency3__["default"]; + var HistoryLocation = __dependency4__["default"]; + var HashLocation = __dependency5__["default"]; + var NoneLocation = __dependency6__["default"]; /** @module ember @@ -22887,7 +22754,8 @@ enifed("ember-routing/location/auto_location", */ create: function (options) { if (options && options.rootURL) { - Ember.assert('rootURL must end with a trailing forward slash e.g. "/app/"', options.rootURL.charAt(options.rootURL.length-1) === '/'); + Ember.assert('rootURL must end with a trailing forward slash e.g. "/app/"', + options.rootURL.charAt(options.rootURL.length-1) === '/'); this.rootURL = options.rootURL; } @@ -22985,15 +22853,33 @@ enifed("ember-routing/location/hash_location", getHash: EmberLocation._getHash, /** - Returns the current `location.hash`, minus the '#' at the front. + Returns the normalized URL, constructed from `location.hash`. + + e.g. `#/foo` => `/foo` as well as `#/foo#bar` => `/foo#bar`. + + By convention, hashed paths must begin with a forward slash, otherwise they + are not treated as a path so we can distinguish intent. @private @method getURL */ getURL: function() { - var path = this.getHash().substr(1); - Ember.deprecate('location.hash value is ambiguous. Support for this will be removed soon. When using location: "hash|auto" your hash paths MUST begin with a forward slash. e.g. #/' + path + ' NOT #' + path + '. See http://emberjs.com/guides/deprecations/#toc_location-hash-paths-must-now-include-a-forward-slash-e-g-foo-not-foo', path.length === 0 || path.charAt(0) === '/'); - return path; + var originalPath = this.getHash().substr(1); + var outPath = originalPath; + + if (outPath.charAt(0) !== '/') { + outPath = '/'; + + // Only add the # if the path isn't empty. + // We do NOT want `/#` since the ampersand + // is only included (conventionally) when + // the location.hash has a value + if (originalPath) { + outPath += '#' + originalPath; + } + } + + return outPath; }, /** @@ -23077,16 +22963,15 @@ enifed("ember-routing/location/hash_location", }); }); enifed("ember-routing/location/history_location", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-runtime/system/object","ember-views/system/jquery","exports"], + ["ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-runtime/system/object","ember-routing/location/api","ember-views/system/jquery","exports"], function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) { "use strict"; - var Ember = __dependency1__["default"]; - // FEATURES - var get = __dependency2__.get; - var set = __dependency3__.set; - var guidFor = __dependency4__.guidFor; + var get = __dependency1__.get; + var set = __dependency2__.set; + var guidFor = __dependency3__.guidFor; - var EmberObject = __dependency5__["default"]; + var EmberObject = __dependency4__["default"]; + var EmberLocation = __dependency5__["default"]; var jQuery = __dependency6__["default"]; /** @@ -23152,6 +23037,7 @@ enifed("ember-routing/location/history_location", var search = location.search || ''; url += search; + url += this.getHash(); return url; }, @@ -23233,7 +23119,6 @@ enifed("ember-routing/location/history_location", */ replaceState: function(path) { var state = { path: path }; - get(this, 'history').replaceState(state, null, path); // store state if browser doesn't support `history.state` @@ -23299,7 +23184,16 @@ enifed("ember-routing/location/history_location", var guid = guidFor(this); jQuery(window).off('popstate.ember-location-'+guid); - } + }, + + /** + @private + + Returns normalized location.hash + + @method getHash + */ + getHash: EmberLocation._getHash }); }); enifed("ember-routing/location/none_location", @@ -23485,28 +23379,20 @@ enifed("ember-routing/system/dsl", var type = options.resetNamespace === true ? 'resource' : 'route'; Ember.assert("'basic' cannot be used as a " + type + " name.", name !== 'basic'); - - if (typeof options.path !== 'string') { - options.path = "/" + name; - } - - if (canNest(this) && options.resetNamespace !== true) { - name = this.parent + "." + name; - } - + if (callback) { - var dsl = new DSL(name); - route(dsl, 'loading'); - route(dsl, 'error', { path: "/_unused_dummy_error_path_route_" + name + "/:error" }); + var fullName = getFullName(this, name, options.resetNamespace); + var dsl = new DSL(fullName); + createRoute(dsl, 'loading'); + createRoute(dsl, 'error', { path: "/_unused_dummy_error_path_route_" + name + "/:error" }); - if (callback) { callback.call(dsl); } + callback.call(dsl); - this.push(options.path, name, dsl.generate()); + createRoute(this, name, options, dsl.generate()); } else { - this.push(options.path, name, null); + createRoute(this, name, options); } - - }, + }, push: function(url, name, callback) { var parts = name.split('.'); @@ -23533,13 +23419,13 @@ enifed("ember-routing/system/dsl", var dslMatches = this.matches; if (!this.explicitIndex) { - route(this, "index", { path: "/" }); + this.route("index", { path: "/" }); } return function(match) { for (var i=0, l=dslMatches.length; i1) args = a_slice.call(arguments, 1); + var ret = Ember.A(); + var args; + + if (arguments.length > 1) { + args = a_slice.call(arguments, 1); + } this.forEach(function(x, idx) { var method = x && x[methodName]; + if ('function' === typeof method) { ret[idx] = args ? apply(x, method, args) : x[methodName](); } @@ -31555,23 +31722,29 @@ enifed("ember-runtime/mixins/enumerable", */ toArray: function() { var ret = Ember.A(); - this.forEach(function(o, idx) { ret[idx] = o; }); + + this.forEach(function(o, idx) { + ret[idx] = o; + }); + return ret; }, /** - Returns a copy of the array with all null and undefined elements removed. + Returns a copy of the array with all `null` and `undefined` elements removed. ```javascript - var arr = ["a", null, "c", undefined]; - arr.compact(); // ["a", "c"] + var arr = ['a', null, 'c', undefined]; + arr.compact(); // ['a', 'c'] ``` @method compact @return {Array} the array without null and undefined elements. */ compact: function() { - return this.filter(function(value) { return value != null; }); + return this.filter(function(value) { + return value != null; + }); }, /** @@ -31580,8 +31753,8 @@ enifed("ember-runtime/mixins/enumerable", the receiver does not contain the value. ```javascript - var arr = ["a", "b", "a", "c"]; - arr.without("a"); // ["b", "c"] + var arr = ['a', 'b', 'a', 'c']; + arr.without('a'); // ['b', 'c'] ``` @method without @@ -31589,12 +31762,19 @@ enifed("ember-runtime/mixins/enumerable", @return {Ember.Enumerable} */ without: function(value) { - if (!this.contains(value)) return this; // nothing to do + if (!this.contains(value)) { + return this; // nothing to do + } + var ret = Ember.A(); + this.forEach(function(k) { - if (k !== value) ret[ret.length] = k; - }) ; - return ret ; + if (k !== value) { + ret[ret.length] = k; + } + }); + + return ret; }, /** @@ -31602,18 +31782,24 @@ enifed("ember-runtime/mixins/enumerable", implementation returns an array regardless of the receiver type. ```javascript - var arr = ["a", "a", "b", "b"]; - arr.uniq(); // ["a", "b"] + var arr = ['a', 'a', 'b', 'b']; + arr.uniq(); // ['a', 'b'] ``` + This only works on primitive data types, e.g. Strings, Numbers, etc. + @method uniq @return {Ember.Enumerable} */ uniq: function() { var ret = Ember.A(); + this.forEach(function(k) { - if (indexOf(ret, k)<0) ret.push(k); + if (indexOf(ret, k) < 0) { + ret.push(k); + } }); + return ret; }, @@ -31651,10 +31837,17 @@ enifed("ember-runtime/mixins/enumerable", var didChange = (opts && opts.didChange) || 'enumerableDidChange'; var hasObservers = get(this, 'hasEnumerableObservers'); - if (!hasObservers) propertyWillChange(this, 'hasEnumerableObservers'); + if (!hasObservers) { + propertyWillChange(this, 'hasEnumerableObservers'); + } + addListener(this, '@enumerable:before', target, willChange); addListener(this, '@enumerable:change', target, didChange); - if (!hasObservers) propertyDidChange(this, 'hasEnumerableObservers'); + + if (!hasObservers) { + propertyDidChange(this, 'hasEnumerableObservers'); + } + return this; }, @@ -31669,12 +31862,19 @@ enifed("ember-runtime/mixins/enumerable", removeEnumerableObserver: function(target, opts) { var willChange = (opts && opts.willChange) || 'enumerableWillChange'; var didChange = (opts && opts.didChange) || 'enumerableDidChange'; - var hasObservers = get(this, 'hasEnumerableObservers'); - if (hasObservers) propertyWillChange(this, 'hasEnumerableObservers'); + + if (hasObservers) { + propertyWillChange(this, 'hasEnumerableObservers'); + } + removeListener(this, '@enumerable:before', target, willChange); removeListener(this, '@enumerable:change', target, didChange); - if (hasObservers) propertyDidChange(this, 'hasEnumerableObservers'); + + if (hasObservers) { + propertyDidChange(this, 'hasEnumerableObservers'); + } + return this; }, @@ -31703,24 +31903,40 @@ enifed("ember-runtime/mixins/enumerable", @chainable */ enumerableContentWillChange: function(removing, adding) { - var removeCnt, addCnt, hasDelta; - if ('number' === typeof removing) removeCnt = removing; - else if (removing) removeCnt = get(removing, 'length'); - else removeCnt = removing = -1; + if ('number' === typeof removing) { + removeCnt = removing; + } else if (removing) { + removeCnt = get(removing, 'length'); + } else { + removeCnt = removing = -1; + } - if ('number' === typeof adding) addCnt = adding; - else if (adding) addCnt = get(adding,'length'); - else addCnt = adding = -1; + if ('number' === typeof adding) { + addCnt = adding; + } else if (adding) { + addCnt = get(adding,'length'); + } else { + addCnt = adding = -1; + } - hasDelta = addCnt<0 || removeCnt<0 || addCnt-removeCnt!==0; + hasDelta = addCnt < 0 || removeCnt < 0 || addCnt - removeCnt !== 0; - if (removing === -1) removing = null; - if (adding === -1) adding = null; + if (removing === -1) { + removing = null; + } + + if (adding === -1) { + adding = null; + } propertyWillChange(this, '[]'); - if (hasDelta) propertyWillChange(this, 'length'); + + if (hasDelta) { + propertyWillChange(this, 'length'); + } + sendEvent(this, '@enumerable:before', [this, removing, adding]); return this; @@ -31743,21 +31959,38 @@ enifed("ember-runtime/mixins/enumerable", enumerableContentDidChange: function(removing, adding) { var removeCnt, addCnt, hasDelta; - if ('number' === typeof removing) removeCnt = removing; - else if (removing) removeCnt = get(removing, 'length'); - else removeCnt = removing = -1; + if ('number' === typeof removing) { + removeCnt = removing; + } else if (removing) { + removeCnt = get(removing, 'length'); + } else { + removeCnt = removing = -1; + } - if ('number' === typeof adding) addCnt = adding; - else if (adding) addCnt = get(adding, 'length'); - else addCnt = adding = -1; + if ('number' === typeof adding) { + addCnt = adding; + } else if (adding) { + addCnt = get(adding, 'length'); + } else { + addCnt = adding = -1; + } - hasDelta = addCnt<0 || removeCnt<0 || addCnt-removeCnt!==0; + hasDelta = addCnt < 0 || removeCnt < 0 || addCnt - removeCnt !== 0; - if (removing === -1) removing = null; - if (adding === -1) adding = null; + if (removing === -1) { + removing = null; + } + + if (adding === -1) { + adding = null; + } sendEvent(this, '@enumerable:change', [this, removing, adding]); - if (hasDelta) propertyDidChange(this, 'length'); + + if (hasDelta) { + propertyDidChange(this, 'length'); + } + propertyDidChange(this, '[]'); return this ; @@ -31776,6 +32009,7 @@ enifed("ember-runtime/mixins/enumerable", */ sortBy: function() { var sortKeys = arguments; + return this.toArray().sort(function(a, b){ for(var i = 0; i < sortKeys.length; i++) { var key = sortKeys[i]; @@ -31783,7 +32017,10 @@ enifed("ember-runtime/mixins/enumerable", var propB = get(b, key); // return 1 or -1 else continue to the next sortKey var compareValue = compare(propA, propB); - if (compareValue) { return compareValue; } + + if (compareValue) { + return compareValue; + } } return 0; }); @@ -32046,8 +32283,8 @@ enifed("ember-runtime/mixins/freezable", __exports__.FROZEN_ERROR = FROZEN_ERROR; }); enifed("ember-runtime/mixins/mutable_array", - ["ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/error","ember-metal/mixin","ember-runtime/mixins/array","ember-runtime/mixins/mutable_enumerable","ember-runtime/mixins/enumerable","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) { + ["ember-metal/property_get","ember-metal/utils","ember-metal/error","ember-metal/mixin","ember-runtime/mixins/array","ember-runtime/mixins/mutable_enumerable","ember-runtime/mixins/enumerable","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) { "use strict"; /** @module ember @@ -32070,14 +32307,13 @@ enifed("ember-runtime/mixins/mutable_array", // var get = __dependency1__.get; - var set = __dependency2__.set; - var isArray = __dependency3__.isArray; - var EmberError = __dependency4__["default"]; - var Mixin = __dependency5__.Mixin; - var required = __dependency5__.required; - var EmberArray = __dependency6__["default"]; - var MutableEnumerable = __dependency7__["default"]; - var Enumerable = __dependency8__["default"]; + var isArray = __dependency2__.isArray; + var EmberError = __dependency3__["default"]; + var Mixin = __dependency4__.Mixin; + var required = __dependency4__.required; + var EmberArray = __dependency5__["default"]; + var MutableEnumerable = __dependency6__["default"]; + var Enumerable = __dependency7__["default"]; /** This mixin defines the API for modifying array-like objects. These methods can be applied only to a collection that keeps its items in an ordered set. @@ -32356,7 +32592,7 @@ enifed("ember-runtime/mixins/mutable_array", // /** - Remove all occurances of an object in the array. + Remove all occurrences of an object in the array. ```javascript var cities = ["Chicago", "Berlin", "Lima", "Chicago"]; @@ -32548,7 +32784,7 @@ enifed("ember-runtime/mixins/observable", var removeObserver = __dependency10__.removeObserver; var observersFor = __dependency10__.observersFor; var cacheFor = __dependency11__.cacheFor; - var isNone = __dependency12__.isNone; + var isNone = __dependency12__["default"]; var slice = Array.prototype.slice; @@ -33245,8 +33481,8 @@ enifed("ember-runtime/mixins/promise_proxy", } }); enifed("ember-runtime/mixins/sortable", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/enumerable_utils","ember-metal/mixin","ember-runtime/mixins/mutable_enumerable","ember-runtime/compare","ember-metal/observer","ember-metal/computed","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __exports__) { + ["ember-metal/core","ember-metal/property_get","ember-metal/enumerable_utils","ember-metal/mixin","ember-runtime/mixins/mutable_enumerable","ember-runtime/compare","ember-metal/observer","ember-metal/computed","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) { "use strict"; /** @module ember @@ -33257,23 +33493,22 @@ enifed("ember-runtime/mixins/sortable", // Ember.assert, Ember.A var get = __dependency2__.get; - var set = __dependency3__.set; - var forEach = __dependency4__.forEach; - var Mixin = __dependency5__.Mixin; - var MutableEnumerable = __dependency6__["default"]; - var compare = __dependency7__["default"]; - var addObserver = __dependency8__.addObserver; - var removeObserver = __dependency8__.removeObserver; - var computed = __dependency9__.computed; - var beforeObserver = __dependency5__.beforeObserver; - var observer = __dependency5__.observer; - //ES6TODO: should we access these directly from their package or from how thier exposed in ember-metal? + var forEach = __dependency3__.forEach; + var Mixin = __dependency4__.Mixin; + var MutableEnumerable = __dependency5__["default"]; + var compare = __dependency6__["default"]; + var addObserver = __dependency7__.addObserver; + var removeObserver = __dependency7__.removeObserver; + var computed = __dependency8__.computed; + var beforeObserver = __dependency4__.beforeObserver; + var observer = __dependency4__.observer; + //ES6TODO: should we access these directly from their package or from how their exposed in ember-metal? /** `Ember.SortableMixin` provides a standard interface for array proxies to specify a sort order and maintain this sorting when objects are added, removed, or updated without changing the implicit order of their underlying - modelarray: + model array: ```javascript songs = [ @@ -33305,8 +33540,8 @@ enifed("ember-runtime/mixins/sortable", songsController.get('firstObject'); // {trackNumber: 4, title: 'Ob-La-Di, Ob-La-Da'} ``` - SortableMixin works by sorting the arrangedContent array, which is the array that - arrayProxy displays. Due to the fact that the underlying 'content' array is not changed, that + `SortableMixin` works by sorting the `arrangedContent` array, which is the array that + `ArrayProxy` displays. Due to the fact that the underlying 'content' array is not changed, that array will not display the sorted list: ```javascript @@ -33314,8 +33549,8 @@ enifed("ember-runtime/mixins/sortable", songsController.get('firstObject'); // Returns the sorted content. ``` - Although the sorted content can also be accessed through the arrangedContent property, - it is preferable to use the proxied class and not the arrangedContent array directly. + Although the sorted content can also be accessed through the `arrangedContent` property, + it is preferable to use the proxied class and not the `arrangedContent` array directly. @class SortableMixin @namespace Ember @@ -33324,7 +33559,7 @@ enifed("ember-runtime/mixins/sortable", __exports__["default"] = Mixin.create(MutableEnumerable, { /** - Specifies which properties dictate the arrangedContent's sort order. + Specifies which properties dictate the `arrangedContent`'s sort order. When specifying multiple properties the sorting will use properties from the `sortProperties` array prioritized from first to last. @@ -33334,7 +33569,7 @@ enifed("ember-runtime/mixins/sortable", sortProperties: null, /** - Specifies the arrangedContent's sort direction. + Specifies the `arrangedContent`'s sort direction. Sorts the content in ascending order by default. Set to `false` to use descending order. @@ -33346,13 +33581,14 @@ enifed("ember-runtime/mixins/sortable", /** The function used to compare two values. You can override this if you want to do custom comparisons. Functions must be of the type expected by - Array#sort, i.e. - return 0 if the two parameters are equal, - return a negative value if the first parameter is smaller than the second or - return a positive value otherwise: + Array#sort, i.e., + + * return 0 if the two parameters are equal, + * return a negative value if the first parameter is smaller than the second or + * return a positive value otherwise: ```javascript - function(x,y) { // These are assumed to be integers + function(x, y) { // These are assumed to be integers if (x === y) return 0; return x < y ? -1 : 1; @@ -33403,12 +33639,11 @@ enifed("ember-runtime/mixins/sortable", isSorted: computed.notEmpty('sortProperties'), /** - Overrides the default arrangedContent from arrayProxy in order to sort by sortFunction. - Also sets up observers for each sortProperty on each item in the content Array. + Overrides the default `arrangedContent` from `ArrayProxy` in order to sort by `sortFunction`. + Also sets up observers for each `sortProperty` on each item in the content Array. @property arrangedContent */ - arrangedContent: computed('content', 'sortProperties.@each', function(key, value) { var content = get(this, 'content'); var isSorted = get(this, 'isSorted'); @@ -33551,8 +33786,8 @@ enifed("ember-runtime/mixins/sortable", }); }); enifed("ember-runtime/mixins/target_action_support", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/mixin","ember-metal/computed","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) { + ["ember-metal/core","ember-metal/property_get","ember-metal/utils","ember-metal/mixin","ember-metal/computed","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) { "use strict"; /** @module ember @@ -33562,10 +33797,9 @@ enifed("ember-runtime/mixins/target_action_support", // Ember.lookup, Ember.assert var get = __dependency2__.get; - var set = __dependency3__.set; - var typeOf = __dependency4__.typeOf; - var Mixin = __dependency5__.Mixin; - var computed = __dependency6__.computed; + var typeOf = __dependency3__.typeOf; + var Mixin = __dependency4__.Mixin; + var computed = __dependency5__.computed; /** `Ember.TargetActionSupport` is a mixin that can be included in a class @@ -33709,25 +33943,25 @@ enifed("ember-runtime/system/application", __exports__["default"] = Namespace.extend(); }); enifed("ember-runtime/system/array_proxy", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/computed","ember-metal/mixin","ember-metal/property_events","ember-metal/error","ember-runtime/system/object","ember-runtime/mixins/mutable_array","ember-runtime/mixins/enumerable","ember-runtime/system/string","exports"], + ["ember-metal/core","ember-metal/property_get","ember-metal/utils","ember-metal/computed","ember-metal/mixin","ember-metal/property_events","ember-metal/error","ember-runtime/system/object","ember-runtime/mixins/mutable_array","ember-runtime/mixins/enumerable","ember-runtime/system/string","ember-metal/alias","exports"], function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; // Ember.K, Ember.assert var get = __dependency2__.get; - var set = __dependency3__.set; - var isArray = __dependency4__.isArray; - var apply = __dependency4__.apply; - var computed = __dependency5__.computed; - var beforeObserver = __dependency6__.beforeObserver; - var observer = __dependency6__.observer; - var beginPropertyChanges = __dependency7__.beginPropertyChanges; - var endPropertyChanges = __dependency7__.endPropertyChanges; - var EmberError = __dependency8__["default"]; - var EmberObject = __dependency9__["default"]; - var MutableArray = __dependency10__["default"]; - var Enumerable = __dependency11__["default"]; - var fmt = __dependency12__.fmt; + var isArray = __dependency3__.isArray; + var apply = __dependency3__.apply; + var computed = __dependency4__.computed; + var beforeObserver = __dependency5__.beforeObserver; + var observer = __dependency5__.observer; + var beginPropertyChanges = __dependency6__.beginPropertyChanges; + var endPropertyChanges = __dependency6__.endPropertyChanges; + var EmberError = __dependency7__["default"]; + var EmberObject = __dependency8__["default"]; + var MutableArray = __dependency9__["default"]; + var Enumerable = __dependency10__["default"]; + var fmt = __dependency11__.fmt; + var alias = __dependency12__["default"]; /** @module ember @@ -33736,7 +33970,6 @@ enifed("ember-runtime/system/array_proxy", var OUT_OF_RANGE_EXCEPTION = "Index out of range"; var EMPTY = []; - var alias = computed.alias; var K = Ember.K; /** @@ -34087,18 +34320,18 @@ enifed("ember-runtime/system/array_proxy", __exports__["default"] = ArrayProxy; }); enifed("ember-runtime/system/container", - ["ember-metal/property_set","exports"], - function(__dependency1__, __exports__) { + ["ember-metal/property_set","container","exports"], + function(__dependency1__, __dependency2__, __exports__) { "use strict"; - var set = __dependency1__["default"]; + var set = __dependency1__.set; + var Container = __dependency2__["default"]; - var Container = requireModule('container')["default"]; Container.set = set; __exports__["default"] = Container; }); enifed("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-metal/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/utils","ember-metal/platform","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/injected_property","ember-metal/run_loop","ember-metal/watching","exports"], function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __exports__) { // Remove "use strict"; from transpiled module until // https://bugs.webkit.org/show_bug.cgi?id=138038 is fixed @@ -34116,32 +34349,32 @@ enifed("ember-runtime/system/core_object", // NOTE: this object should never be included directly. Instead use `Ember.Object`. // We only define this separately so that `Ember.Set` can depend on it. var get = __dependency2__.get; - var set = __dependency3__.set; - var guidFor = __dependency4__.guidFor; - var apply = __dependency4__.apply; - var o_create = __dependency5__.create; - var generateGuid = __dependency4__.generateGuid; - var GUID_KEY = __dependency4__.GUID_KEY; - var meta = __dependency4__.meta; - var makeArray = __dependency4__.makeArray; - var rewatch = __dependency6__.rewatch; - var finishChains = __dependency7__.finishChains; - var sendEvent = __dependency8__.sendEvent; - var IS_BINDING = __dependency9__.IS_BINDING; - var Mixin = __dependency9__.Mixin; - var required = __dependency9__.required; - var indexOf = __dependency10__.indexOf; - var EmberError = __dependency11__["default"]; - var o_defineProperty = __dependency5__.defineProperty; - var keys = __dependency12__["default"]; - var ActionHandler = __dependency13__["default"]; - var defineProperty = __dependency14__.defineProperty; - var Binding = __dependency15__.Binding; - var ComputedProperty = __dependency16__.ComputedProperty; - var run = __dependency17__["default"]; - var destroy = __dependency6__.destroy; + var guidFor = __dependency3__.guidFor; + var apply = __dependency3__.apply; + var o_create = __dependency4__.create; + var generateGuid = __dependency3__.generateGuid; + var GUID_KEY = __dependency3__.GUID_KEY; + var meta = __dependency3__.meta; + var makeArray = __dependency3__.makeArray; + var finishChains = __dependency5__.finishChains; + var sendEvent = __dependency6__.sendEvent; + var IS_BINDING = __dependency7__.IS_BINDING; + var Mixin = __dependency7__.Mixin; + var required = __dependency7__.required; + var indexOf = __dependency8__.indexOf; + var EmberError = __dependency9__["default"]; + var o_defineProperty = __dependency4__.defineProperty; + var keys = __dependency10__["default"]; + var ActionHandler = __dependency11__["default"]; + var defineProperty = __dependency12__.defineProperty; + var Binding = __dependency13__.Binding; + var ComputedProperty = __dependency14__.ComputedProperty; + var computed = __dependency14__.computed; + var InjectedProperty = __dependency15__["default"]; + var run = __dependency16__["default"]; + var destroy = __dependency17__.destroy; var K = __dependency1__.K; - var hasPropertyAccessors = __dependency5__.hasPropertyAccessors; + var hasPropertyAccessors = __dependency4__.hasPropertyAccessors; var schedule = run.schedule; var applyMixin = Mixin._apply; @@ -34209,8 +34442,6 @@ enifed("ember-runtime/system/core_object", for (var j = 0, ll = keyNames.length; j < ll; j++) { var keyName = keyNames[j]; - if (!properties.hasOwnProperty(keyName)) { continue; } - var value = properties[keyName]; if (IS_BINDING.test(keyName)) { @@ -34231,7 +34462,9 @@ enifed("ember-runtime/system/core_object", "time, when Ember.ActionHandler is used (i.e. views, " + "controllers & routes).", !((keyName === 'actions') && ActionHandler.detect(this))); - if (concatenatedProperties && indexOf(concatenatedProperties, keyName) >= 0) { + if (concatenatedProperties && + concatenatedProperties.length > 0 && + indexOf(concatenatedProperties, keyName) >= 0) { var baseValue = this[keyName]; if (baseValue) { @@ -34292,7 +34525,6 @@ enifed("ember-runtime/system/core_object", if (!wasApplied) { wasApplied = true; Class.PrototypeMixin.applyPartial(Class.prototype); - rewatch(Class.prototype); } return this.prototype; @@ -34545,7 +34777,7 @@ enifed("ember-runtime/system/core_object", CoreObject.__super__ = null; - var ClassMixin = Mixin.create({ + var ClassMixinProps = { ClassMixin: required(), @@ -34890,7 +35122,7 @@ enifed("ember-runtime/system/core_object", return desc._meta || {}; }, - _computedProperties: Ember.computed(function() { + _computedProperties: computed(function() { hasCachedComputedProperties = true; var proto = this.proto(); var descs = meta(proto).descs; @@ -34930,7 +35162,10 @@ enifed("ember-runtime/system/core_object", callback.call(binding || this, property.name, property.meta || empty); } } - }); + }; + + + var ClassMixin = Mixin.create(ClassMixinProps); ClassMixin.ownerConstructor = CoreObject; @@ -34958,13 +35193,12 @@ enifed("ember-runtime/system/core_object", __exports__["default"] = CoreObject; }); enifed("ember-runtime/system/deferred", - ["ember-metal/core","ember-runtime/mixins/deferred","ember-metal/property_get","ember-runtime/system/object","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) { + ["ember-metal/core","ember-runtime/mixins/deferred","ember-runtime/system/object","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; var DeferredMixin = __dependency2__["default"]; - var get = __dependency3__.get; - var EmberObject = __dependency4__["default"]; + var EmberObject = __dependency3__["default"]; var Deferred = EmberObject.extend(DeferredMixin, { init: function() { @@ -34984,8 +35218,8 @@ enifed("ember-runtime/system/deferred", __exports__["default"] = Deferred; }); enifed("ember-runtime/system/each_proxy", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/enumerable_utils","ember-metal/array","ember-runtime/mixins/array","ember-runtime/system/object","ember-metal/computed","ember-metal/observer","ember-metal/events","ember-metal/properties","ember-metal/property_events","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __exports__) { + ["ember-metal/core","ember-metal/property_get","ember-metal/utils","ember-metal/enumerable_utils","ember-metal/array","ember-runtime/mixins/array","ember-runtime/system/object","ember-metal/computed","ember-metal/observer","ember-metal/events","ember-metal/properties","ember-metal/property_events","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __exports__) { "use strict"; /** @module ember @@ -34996,26 +35230,25 @@ enifed("ember-runtime/system/each_proxy", // Ember.assert var get = __dependency2__.get; - var set = __dependency3__.set; - var guidFor = __dependency4__.guidFor; - var forEach = __dependency5__.forEach; - var indexOf = __dependency6__.indexOf; - var EmberArray = __dependency7__["default"]; + var guidFor = __dependency3__.guidFor; + var forEach = __dependency4__.forEach; + var indexOf = __dependency5__.indexOf; + var EmberArray = __dependency6__["default"]; // ES6TODO: WAT? Circular dep? - var EmberObject = __dependency8__["default"]; - var computed = __dependency9__.computed; - var addObserver = __dependency10__.addObserver; - var addBeforeObserver = __dependency10__.addBeforeObserver; - var removeBeforeObserver = __dependency10__.removeBeforeObserver; - var removeObserver = __dependency10__.removeObserver; - var typeOf = __dependency4__.typeOf; - var watchedEvents = __dependency11__.watchedEvents; - var defineProperty = __dependency12__.defineProperty; - var beginPropertyChanges = __dependency13__.beginPropertyChanges; - var propertyDidChange = __dependency13__.propertyDidChange; - var propertyWillChange = __dependency13__.propertyWillChange; - var endPropertyChanges = __dependency13__.endPropertyChanges; - var changeProperties = __dependency13__.changeProperties; + var EmberObject = __dependency7__["default"]; + var computed = __dependency8__.computed; + var addObserver = __dependency9__.addObserver; + var addBeforeObserver = __dependency9__.addBeforeObserver; + var removeBeforeObserver = __dependency9__.removeBeforeObserver; + var removeObserver = __dependency9__.removeObserver; + var typeOf = __dependency3__.typeOf; + var watchedEvents = __dependency10__.watchedEvents; + var defineProperty = __dependency11__.defineProperty; + var beginPropertyChanges = __dependency12__.beginPropertyChanges; + var propertyDidChange = __dependency12__.propertyDidChange; + var propertyWillChange = __dependency12__.propertyWillChange; + var endPropertyChanges = __dependency12__.endPropertyChanges; + var changeProperties = __dependency12__.changeProperties; var EachArray = EmberObject.extend(EmberArray, { @@ -35428,7 +35661,7 @@ enifed("ember-runtime/system/namespace", function findNamespaces() { var lookup = Ember.lookup; - var obj, isNamespace; + var obj; if (Namespace.PROCESSED) { return; } @@ -35515,8 +35748,8 @@ enifed("ember-runtime/system/namespace", __exports__["default"] = Namespace; }); enifed("ember-runtime/system/native_array", - ["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__) { + ["ember-metal/core","ember-metal/property_get","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__, __exports__) { "use strict"; /** @module ember @@ -35527,18 +35760,17 @@ enifed("ember-runtime/system/native_array", // Ember.EXTEND_PROTOTYPES var get = __dependency2__.get; - var set = __dependency3__.set; - var replace = __dependency4__._replace; - var forEach = __dependency4__.forEach; - var Mixin = __dependency5__.Mixin; - 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"]; + var replace = __dependency3__._replace; + var forEach = __dependency3__.forEach; + var Mixin = __dependency4__.Mixin; + var indexOf = __dependency5__.indexOf; + var lastIndexOf = __dependency5__.lastIndexOf; + 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"]; // Add Ember.Array to Array.prototype. Remove methods with native // implementations and supply some more optimized versions of generic methods @@ -35693,16 +35925,19 @@ enifed("ember-runtime/system/native_array", __exports__["default"] = NativeArray; }); enifed("ember-runtime/system/object", - ["ember-runtime/system/core_object","ember-runtime/mixins/observable","exports"], - function(__dependency1__, __dependency2__, __exports__) { + ["ember-metal/core","ember-runtime/system/core_object","ember-runtime/mixins/observable","ember-runtime/inject","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) { "use strict"; /** @module ember @submodule ember-runtime */ - var CoreObject = __dependency1__["default"]; - var Observable = __dependency2__["default"]; + var Ember = __dependency1__["default"]; + // Ember.assert + var CoreObject = __dependency2__["default"]; + var Observable = __dependency3__["default"]; + var validatePropertyInjections = __dependency4__.validatePropertyInjections; /** `Ember.Object` is the main base class for all Ember objects. It is a subclass @@ -35719,6 +35954,13 @@ enifed("ember-runtime/system/object", return "Ember.Object"; }; + function injectedPropertyAssertion(props) { + // Injection validations are a debugging aid only, so ensure that they are + // not performed in production builds by invoking from an assertion + Ember.assert("Injected properties are invalid", validatePropertyInjections(this.constructor, props)); + } + + __exports__["default"] = EmberObject; }); enifed("ember-runtime/system/object_proxy", @@ -35799,6 +36041,18 @@ enifed("ember-runtime/system/object_proxy", __exports__["default"] = EmberObject.extend(_ProxyMixin); }); +enifed("ember-runtime/system/service", + ["ember-runtime/system/object","ember-runtime/inject","exports"], + function(__dependency1__, __dependency2__, __exports__) { + "use strict"; + var Object = __dependency1__["default"]; + var createInjectionHelper = __dependency2__.createInjectionHelper; + + var Service; + + + __exports__["default"] = Service; + }); enifed("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__) { @@ -35813,7 +36067,7 @@ enifed("ember-runtime/system/set", var get = __dependency2__.get; var set = __dependency3__.set; var guidFor = __dependency4__.guidFor; - var isNone = __dependency5__.isNone; + var isNone = __dependency5__["default"]; var fmt = __dependency6__.fmt; var CoreObject = __dependency7__["default"]; var MutableEnumerable = __dependency8__["default"]; @@ -35923,6 +36177,7 @@ enifed("ember-runtime/system/set", @uses Ember.Copyable @uses Ember.Freezable @since Ember 0.9 + @deprecated */ __exports__["default"] = CoreObject.extend(MutableEnumerable, Copyable, Freezable, { @@ -36587,12 +36842,11 @@ enifed("ember-runtime/system/string", __exports__.capitalize = capitalize; }); enifed("ember-runtime/system/subarray", - ["ember-metal/property_get","ember-metal/error","ember-metal/enumerable_utils","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __exports__) { + ["ember-metal/error","ember-metal/enumerable_utils","exports"], + function(__dependency1__, __dependency2__, __exports__) { "use strict"; - var get = __dependency1__.get; - var EmberError = __dependency2__["default"]; - var EnumerableUtils = __dependency3__["default"]; + var EmberError = __dependency1__["default"]; + var EnumerableUtils = __dependency2__["default"]; var RETAIN = 'r'; var FILTER = 'f'; @@ -36824,7 +37078,7 @@ enifed("ember-runtime/system/tracked_array", var arrayOperation = match.operation; var arrayOperationIndex = match.index; var arrayOperationRangeStart = match.rangeStart; - var composeIndex, splitIndex, splitItems, splitArrayOperation, newArrayOperation; + var composeIndex, newArrayOperation; newArrayOperation = new ArrayOperation(INSERT, count, newItems); @@ -36857,7 +37111,6 @@ enifed("ember-runtime/system/tracked_array", if (count < 1) { return; } var match = this._findArrayOperation(index); - var arrayOperation = match.operation; var arrayOperationIndex = match.index; var arrayOperationRangeStart = match.rangeStart; var newArrayOperation, composeIndex; @@ -37129,13 +37382,12 @@ enifed("ember-testing", Ember.setupForTesting = setupForTesting; }); enifed("ember-testing/adapters/adapter", - ["ember-metal/core","ember-metal/utils","ember-runtime/system/object","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __exports__) { + ["ember-metal/core","ember-runtime/system/object","exports"], + function(__dependency1__, __dependency2__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; // Ember.K - var inspect = __dependency2__.inspect; - var EmberObject = __dependency3__["default"]; + var EmberObject = __dependency2__["default"]; /** @module ember @@ -37257,6 +37509,11 @@ enifed("ember-testing/helpers", return get(router, 'location').getURL(); } + function pauseTest(){ + Test.adapter.asyncStart(); + return new Ember.RSVP.Promise(function(){ }, 'TestAdapter paused promise'); + } + function visit(app, url) { var router = app.__container__.lookup('router:main'); router.location.setURL(url); @@ -37546,7 +37803,7 @@ enifed("ember-testing/helpers", Ember.Test.registerAsyncHelper('loginUser', function(app, username, password) { visit('secured/path/here') .fillIn('#username', username) - .fillIn('#password', username) + .fillIn('#password', password) .click('.submit') return app.testHelpers.wait(); @@ -37617,6 +37874,26 @@ enifed("ember-testing/helpers", */ helper('currentURL', currentURL); + + /** + Pauses the current test - this is useful for debugging while testing or for test-driving. + It allows you to inspect the state of your application at any point. + + Example (The test will pause before clicking the button): + + ```javascript + visit('/') + return pauseTest(); + + click('.btn'); + ``` + + @method pauseTest + @return {Object} A promise that will never resolve + */ + helper('pauseTest', pauseTest); + + /** Triggers the given DOM event on the element identified by the provided selector. @@ -38321,6 +38598,8 @@ enifed("ember-views", var Ember = __dependency1__["default"]; var jQuery = __dependency2__["default"]; var isSimpleClick = __dependency3__.isSimpleClick; + var getViewClientRects = __dependency3__.getViewClientRects; + var getViewBoundingClientRect = __dependency3__.getViewBoundingClientRect; var RenderBuffer = __dependency4__["default"]; // for the side effect of extending Ember.run.queues var cloneStates = __dependency6__.cloneStates; @@ -38351,6 +38630,8 @@ enifed("ember-views", var ViewUtils = Ember.ViewUtils = {}; ViewUtils.isSimpleClick = isSimpleClick; + ViewUtils.getViewClientRects = getViewClientRects; + ViewUtils.getViewBoundingClientRect = getViewBoundingClientRect; Ember.CoreView = CoreView; Ember.View = View; @@ -38434,15 +38715,12 @@ enifed("ember-views/mixins/component_template_deprecation", }); }); enifed("ember-views/mixins/view_target_action_support", - ["ember-metal/mixin","ember-runtime/mixins/target_action_support","ember-metal/computed","exports"], + ["ember-metal/mixin","ember-runtime/mixins/target_action_support","ember-metal/alias","exports"], function(__dependency1__, __dependency2__, __dependency3__, __exports__) { "use strict"; var Mixin = __dependency1__.Mixin; var TargetActionSupport = __dependency2__["default"]; - - // ES6TODO: computed should have its own export path so you can do import {defaultTo} from computed - var computed = __dependency3__.computed; - var alias = computed.alias; + var alias = __dependency3__["default"]; /** `Ember.ViewTargetActionSupport` is a mixin that can be included in a @@ -38496,6 +38774,213 @@ enifed("ember-views/mixins/view_target_action_support", actionContext: alias('context') }); }); +enifed("ember-views/streams/context_stream", + ["ember-metal/core","ember-metal/merge","ember-metal/platform","ember-metal/path_cache","ember-metal/streams/stream","ember-metal/streams/simple","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) { + "use strict"; + var Ember = __dependency1__["default"]; + + var merge = __dependency2__["default"]; + var create = __dependency3__.create; + var isGlobal = __dependency4__.isGlobal; + var Stream = __dependency5__["default"]; + var SimpleStream = __dependency6__["default"]; + + function ContextStream(view) { + Ember.assert("ContextStream error: the argument is not a view", view && view.isView); + this.view = view; + } + + ContextStream.prototype = create(Stream.prototype); + + merge(ContextStream.prototype, { + value: function() {}, + + _makeChildStream: function(key, _fullPath) { + var stream; + + if (key === '' || key === 'this') { + stream = this.view._baseContext; + } else if (isGlobal(key) && Ember.lookup[key]) { + Ember.deprecate("Global lookup of " + _fullPath + " from a Handlebars template is deprecated."); + stream = new SimpleStream(Ember.lookup[key]); + stream._isGlobal = true; + } else if (key in this.view._keywords) { + stream = new SimpleStream(this.view._keywords[key]); + } else { + stream = new SimpleStream(this.view._baseContext.get(key)); + } + + stream._isRoot = true; + + if (key === 'controller') { + stream._isController = true; + } + + return stream; + } + }); + + __exports__["default"] = ContextStream; + }); +enifed("ember-views/streams/key_stream", + ["ember-metal/core","ember-metal/merge","ember-metal/platform","ember-metal/property_get","ember-metal/property_set","ember-metal/observer","ember-metal/streams/stream","ember-metal/streams/read","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) { + "use strict"; + var Ember = __dependency1__["default"]; + + var merge = __dependency2__["default"]; + var create = __dependency3__.create; + var get = __dependency4__.get; + var set = __dependency5__.set; + var addObserver = __dependency6__.addObserver; + var removeObserver = __dependency6__.removeObserver; + var Stream = __dependency7__["default"]; + var read = __dependency8__.read; + + function KeyStream(source, key) { + Ember.assert("KeyStream error: key must be a non-empty string", typeof key === 'string' && key.length > 0); + Ember.assert("KeyStream error: key must not have a '.'", key.indexOf('.') === -1); + + this.source = source; + this.obj = undefined; + this.key = key; + + if (source && source.isStream) { + source.subscribe(this._didChange, this); + } + } + + KeyStream.prototype = create(Stream.prototype); + + merge(KeyStream.prototype, { + valueFn: function() { + var prevObj = this.obj; + var nextObj = read(this.source); + + if (nextObj !== prevObj) { + if (prevObj && typeof prevObj === 'object') { + removeObserver(prevObj, this.key, this, this._didChange); + } + + if (nextObj && typeof nextObj === 'object') { + addObserver(nextObj, this.key, this, this._didChange); + } + + this.obj = nextObj; + } + + if (nextObj) { + return get(nextObj, this.key); + } + }, + + setValue: function(value) { + if (this.obj) { + set(this.obj, this.key, value); + } + }, + + setSource: function(nextSource) { + Ember.assert("KeyStream error: source must be an object", typeof nextSource === 'object'); + + var prevSource = this.source; + + if (nextSource !== prevSource) { + if (prevSource && prevSource.isStream) { + prevSource.unsubscribe(this._didChange, this); + } + + if (nextSource && nextSource.isStream) { + nextSource.subscribe(this._didChange, this); + } + + this.source = nextSource; + this.notify(); + } + }, + + _didChange: function() { + this.notify(); + }, + + destroy: function() { + if (this.source && this.source.isStream) { + this.source.unsubscribe(this._didChange, this); + } + + if (this.obj && typeof this.obj === 'object') { + removeObserver(this.obj, this.key, this, this._didChange); + } + + this.source = undefined; + this.obj = undefined; + + Stream.prototype.destroy.call(this); + } + }); + + __exports__["default"] = KeyStream; + + // The transpiler does not resolve cycles, so we export + // the `_makeChildStream` method onto `Stream` here. + + Stream.prototype._makeChildStream = function(key) { + return new KeyStream(this, key); + }; + }); +enifed("ember-views/streams/read", + ["ember-metal/core","ember-metal/property_get","ember-metal/path_cache","ember-runtime/system/string","ember-metal/streams/read","ember-views/views/view","ember-runtime/mixins/controller","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) { + "use strict"; + var Ember = __dependency1__["default"]; + var get = __dependency2__.get; + var isGlobal = __dependency3__.isGlobal; + var fmt = __dependency4__.fmt; + var read = __dependency5__.read; + var View = __dependency6__["default"]; + var ControllerMixin = __dependency7__["default"]; + + function readViewFactory(object, container) { + var value = read(object); + var viewClass; + + if (typeof value === 'string') { + if (isGlobal(value)) { + viewClass = get(null, value); + Ember.deprecate('Resolved the view "'+value+'" on the global context. Pass a view name to be looked up on the container instead, such as {{view "select"}}. http://emberjs.com/guides/deprecations#toc_global-lookup-of-views', !viewClass); + } else { + Ember.assert("View requires a container to resolve views not passed in through the context", !!container); + viewClass = container.lookupFactory('view:'+value); + } + } else { + viewClass = value; + } + + Ember.assert(fmt(value+" must be a subclass of Ember.View, not %@", [viewClass]), View.detect(viewClass)); + + return viewClass; + } + + __exports__.readViewFactory = readViewFactory;function readUnwrappedModel(object) { + if (object && object.isStream) { + var result = object.value(); + + // If the path is exactly `controller` then we don't unwrap it. + if (!object._isController) { + while (ControllerMixin.detect(result)) { + result = get(result, 'model'); + } + } + + return result; + } else { + return object; + } + } + + __exports__.readUnwrappedModel = readUnwrappedModel; + }); enifed("ember-views/system/action_manager", ["exports"], function(__exports__) { @@ -38531,7 +39016,7 @@ enifed("ember-views/system/event_dispatcher", var get = __dependency2__.get; var set = __dependency3__.set; - var isNone = __dependency4__.isNone; + var isNone = __dependency4__["default"]; var run = __dependency5__["default"]; var typeOf = __dependency6__.typeOf; var fmt = __dependency7__.fmt; @@ -38756,7 +39241,7 @@ enifed("ember-views/system/event_dispatcher", }, _bubbleEvent: function(view, evt, eventName) { - return run(view, view.handleEvent, eventName, evt); + return run.join(view, view.handleEvent, eventName, evt); }, destroy: function() { @@ -38784,20 +39269,18 @@ enifed("ember-views/system/ext", // Add a new named queue for rendering views that happens // after bindings have synced, and a queue for scheduling actions // that that should occur after view rendering. - var queues = run.queues; run._addQueue('render', 'actions'); run._addQueue('afterRender', 'render'); }); enifed("ember-views/system/jquery", - ["ember-metal/core","ember-runtime/system/string","ember-metal/enumerable_utils","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __exports__) { + ["ember-metal/core","ember-metal/enumerable_utils","exports"], + function(__dependency1__, __dependency2__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; // Ember.assert - var w = __dependency2__.w; // ES6TODO: the functions on EnumerableUtils need their own exports - var forEach = __dependency3__.forEach; + var forEach = __dependency2__.forEach; /** Ember Views @@ -38813,7 +39296,9 @@ enifed("ember-views/system/jquery", jQuery = eriuqer('jquery'); } - Ember.assert("Ember Views require jQuery between 1.7 and 2.1", jQuery && (jQuery().jquery.match(/^((1\.(7|8|9|10|11))|(2\.(0|1)))(\.\d+)?(pre|rc\d?)?/) || Ember.ENV.FORCE_JQUERY)); + Ember.assert("Ember Views require jQuery between 1.7 and 2.1", jQuery && + (jQuery().jquery.match(/^((1\.(7|8|9|10|11))|(2\.(0|1)))(\.\d+)?(pre|rc\d?)?/) || + Ember.ENV.FORCE_JQUERY)); /** @module ember @@ -38821,12 +39306,22 @@ enifed("ember-views/system/jquery", */ if (jQuery) { // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dndevents - var dragEvents = w('dragstart drag dragenter dragleave dragover drop dragend'); + var dragEvents = [ + 'dragstart', + 'drag', + 'dragenter', + 'dragleave', + 'dragover', + 'drop', + 'dragend' + ]; // Copies the `dataTransfer` property from a browser event object onto the // jQuery event object for the specified events forEach(dragEvents, function(eventName) { - jQuery.event.fixHooks[eventName] = { props: ['dataTransfer'] }; + jQuery.event.fixHooks[eventName] = { + props: ['dataTransfer'] + }; }); } @@ -38903,10 +39398,6 @@ enifed("ember-views/system/render_buffer", this.seen[string] = true; this.list.push(string); - }, - - toDOM: function() { - return this.list.join(" "); } }; @@ -39443,25 +39934,12 @@ enifed("ember-views/system/renderer", function EmberRenderer() { this.buffer = renderBuffer(); - Renderer.call(this); + this._super$constructor(); } + EmberRenderer.prototype = create(Renderer.prototype); EmberRenderer.prototype.constructor = EmberRenderer; - - var BAD_TAG_NAME_TEST_REGEXP = /[^a-zA-Z0-9\-]/; - var BAD_TAG_NAME_REPLACE_REGEXP = /[^a-zA-Z0-9\-]/g; - - function stripTagName(tagName) { - if (!tagName) { - return tagName; - } - - if (!BAD_TAG_NAME_TEST_REGEXP.test(tagName)) { - return tagName; - } - - return tagName.replace(BAD_TAG_NAME_REPLACE_REGEXP, ''); - } + EmberRenderer.prototype._super$constructor = Renderer; EmberRenderer.prototype.scheduleRender = function EmberRenderer_scheduleRender(ctx, fn) { @@ -39473,25 +39951,6 @@ enifed("ember-views/system/renderer", run.cancel(id); }; - EmberRenderer.prototype.createChildViewsMorph = - function EmberRenderer_createChildViewsMorph(view, _element) { - if (view.createChildViewsMorph) { - return view.createChildViewsMorph(_element); - } - var element = _element; - if (view.tagName === '') { - if (view._morph) { - view._childViewsMorph = view._morph; - } else { - element = document.createDocumentFragment(); - view._childViewsMorph = this._dom.appendMorph(element); - } - } else { - view._childViewsMorph = this._dom.createMorph(element, element.lastChild, null); - } - return element; - }; - EmberRenderer.prototype.createElement = function EmberRenderer_createElement(view, contextualElement) { // If this is the top-most view, start a new buffer. Otherwise, @@ -39532,10 +39991,6 @@ enifed("ember-views/system/renderer", var element = buffer.element(); - if (view.isContainer) { - this.createChildViewsMorph(view, element); - } - view.buffer = null; if (element && element.nodeType === 1) { // We have hooks, we shouldn't make element observable @@ -39616,11 +40071,55 @@ enifed("ember-views/system/utils", return !modifier && !secondaryClick; } - __exports__.isSimpleClick = isSimpleClick; + __exports__.isSimpleClick = isSimpleClick;/** + @private + @method getViewRange + @param {Ember.View} view + */ + function getViewRange(view) { + var range = document.createRange(); + range.setStartAfter(view._morph.start); + range.setEndBefore(view._morph.end); + return range; + } + + /** + `getViewClientRects` provides information about the position of the border + box edges of a view relative to the viewport. + + It is only intended to be used by development tools like the Ember Inpsector + and may not work on older browsers. + + @private + @method getViewClientRects + @param {Ember.View} view + */ + function getViewClientRects(view) { + var range = getViewRange(view); + return range.getClientRects(); + } + + __exports__.getViewClientRects = getViewClientRects;/** + `getViewBoundingClientRect` provides information about the position of the + bounding border box edges of a view relative to the viewport. + + It is only intended to be used by development tools like the Ember Inpsector + and may not work on older browsers. + + @private + @method getViewBoundingClientRect + @param {Ember.View} view + */ + function getViewBoundingClientRect(view) { + var range = getViewRange(view); + return range.getBoundingClientRect(); + } + + __exports__.getViewBoundingClientRect = getViewBoundingClientRect; }); enifed("ember-views/views/collection_view", - ["ember-metal/core","ember-metal/platform","ember-metal/binding","ember-metal/merge","ember-metal/property_get","ember-metal/property_set","ember-runtime/system/string","ember-views/views/container_view","ember-views/views/core_view","ember-views/views/view","ember-metal/mixin","ember-handlebars/ext","ember-runtime/mixins/array","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __exports__) { + ["ember-metal/core","ember-metal/binding","ember-metal/property_get","ember-metal/property_set","ember-runtime/system/string","ember-views/views/container_view","ember-views/views/core_view","ember-views/views/view","ember-metal/mixin","ember-views/streams/read","ember-runtime/mixins/array","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __exports__) { "use strict"; /** @@ -39630,19 +40129,17 @@ enifed("ember-views/views/collection_view", var Ember = __dependency1__["default"]; // Ember.assert - var create = __dependency2__.create; - var isGlobalPath = __dependency3__.isGlobalPath; - var merge = __dependency4__["default"]; - var get = __dependency5__.get; - var set = __dependency6__.set; - var fmt = __dependency7__.fmt; - var ContainerView = __dependency8__["default"]; - var CoreView = __dependency9__["default"]; - var View = __dependency10__["default"]; - var observer = __dependency11__.observer; - var beforeObserver = __dependency11__.beforeObserver; - var handlebarsGetView = __dependency12__.handlebarsGetView; - var EmberArray = __dependency13__["default"]; + var isGlobalPath = __dependency2__.isGlobalPath; + var get = __dependency3__.get; + var set = __dependency4__.set; + var fmt = __dependency5__.fmt; + var ContainerView = __dependency6__["default"]; + var CoreView = __dependency7__["default"]; + var View = __dependency8__["default"]; + var observer = __dependency9__.observer; + var beforeObserver = __dependency9__.beforeObserver; + var readViewFactory = __dependency10__.readViewFactory; + var EmberArray = __dependency11__["default"]; /** `Ember.CollectionView` is an `Ember.View` descendent responsible for managing @@ -39968,21 +40465,23 @@ enifed("ember-views/views/collection_view", */ arrayDidChange: function(content, start, removed, added) { var addedViews = []; - var view, item, idx, len, itemViewClass, emptyView; + var view, item, idx, len, itemViewClass, emptyView, itemViewProps; len = content ? get(content, 'length') : 0; if (len) { + itemViewProps = this._itemViewProps || {}; itemViewClass = get(this, 'itemViewClass'); - itemViewClass = handlebarsGetView(content, itemViewClass, this.container); + + itemViewClass = readViewFactory(itemViewClass, this.container); for (idx = start; idx < start+added; idx++) { item = content.objectAt(idx); - view = this.createChildView(itemViewClass, { - content: item, - contentIndex: idx - }); + itemViewProps.content = item; + itemViewProps.contentIndex = idx; + + view = this.createChildView(itemViewClass, itemViewProps); addedViews.push(view); } @@ -39996,6 +40495,7 @@ enifed("ember-views/views/collection_view", } emptyView = this.createChildView(emptyView); + addedViews.push(emptyView); set(this, 'emptyView', emptyView); @@ -40072,7 +40572,7 @@ enifed("ember-views/views/component", var get = __dependency5__.get; var set = __dependency6__.set; - var isNone = __dependency7__.isNone; + var isNone = __dependency7__["default"]; var computed = __dependency8__.computed; @@ -40178,7 +40678,6 @@ enifed("ember-views/views/component", init: function() { this._super(); - set(this, 'origContext', get(this, 'context')); set(this, 'context', this); set(this, 'controller', this); }, @@ -40226,12 +40725,8 @@ enifed("ember-views/views/component", */ templateName: null, - // during render, isolate keywords - cloneKeywords: function() { - return { - view: this, - controller: this - }; + _setupKeywords: function() { + this._keywords.view.setSource(this); }, _yield: function(context, options) { @@ -40247,9 +40742,9 @@ enifed("ember-views/views/component", tagName: '', _contextView: parentView, template: template, - context: options.data.insideGroup ? get(this, 'origContext') : get(parentView, 'context'), + context: get(parentView, 'context'), controller: get(parentView, 'controller'), - templateData: { keywords: parentView.cloneKeywords(), insideGroup: options.data.insideGroup } + templateData: { keywords: {} } }); } }, @@ -40372,14 +40867,38 @@ enifed("ember-views/views/component", action: actionName, actionContext: contexts }); + }, + + send: function(actionName) { + var args = [].slice.call(arguments, 1); + var target; + var hasAction = this._actions && this._actions[actionName]; + + if (hasAction) { + if (this._actions[actionName].apply(this, args) === true) { + // handler returned 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); + } else { + if (!hasAction) { + throw new Error(Ember.inspect(this) + ' had no action handler for: ' + actionName); + } + } } }); __exports__["default"] = Component; }); enifed("ember-views/views/container_view", - ["ember-metal/core","ember-metal/merge","ember-runtime/mixins/mutable_array","ember-metal/property_get","ember-metal/property_set","ember-views/views/view","ember-views/views/states","ember-metal/error","ember-metal/enumerable_utils","ember-metal/computed","ember-metal/run_loop","ember-metal/properties","ember-views/system/render_buffer","ember-metal/mixin","ember-runtime/system/native_array","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __exports__) { + ["ember-metal/core","ember-metal/merge","ember-runtime/mixins/mutable_array","ember-metal/property_get","ember-metal/property_set","ember-views/views/view","ember-views/views/states","ember-metal/error","ember-metal/enumerable_utils","ember-metal/computed","ember-metal/run_loop","ember-metal/properties","ember-metal/mixin","ember-runtime/system/native_array","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, Ember.K @@ -40401,10 +40920,9 @@ enifed("ember-views/views/container_view", var computed = __dependency10__.computed; var run = __dependency11__["default"]; var defineProperty = __dependency12__.defineProperty; - var renderBuffer = __dependency13__["default"]; - var observer = __dependency14__.observer; - var beforeObserver = __dependency14__.beforeObserver; - var emberA = __dependency15__.A; + var observer = __dependency13__.observer; + var beforeObserver = __dependency13__.beforeObserver; + var emberA = __dependency14__.A; /** @module ember @@ -40564,7 +41082,6 @@ enifed("ember-views/views/container_view", @extends Ember.View */ var ContainerView = View.extend(MutableArray, { - isContainer: true, _states: states, willWatchProperty: function(prop){ @@ -40578,6 +41095,7 @@ enifed("ember-views/views/container_view", this._super(); var childViews = get(this, 'childViews'); + Ember.deprecate('Setting `childViews` on a Container is deprecated.', Ember.isEmpty(childViews)); // redefine view's childViews property that was obliterated defineProperty(this, 'childViews', View.childViewsProperty); @@ -40643,6 +41161,18 @@ enifed("ember-views/views/container_view", @param {Ember.RenderBuffer} buffer the buffer to render to */ render: function(buffer) { + var element = buffer.element(); + var dom = buffer.dom; + + if (this.tagName === '') { + element = dom.createDocumentFragment(); + buffer._element = element; + this._childViewsMorph = dom.appendMorph(element, this._morph.contextualElement); + } else { + this._childViewsMorph = dom.createMorph(element, element.lastChild, null); + } + + return element; }, instrumentName: 'container', @@ -40752,7 +41282,9 @@ enifed("ember-views/views/container_view", merge(states.hasElement, { childViewsWillChange: function(view, views, start, removed) { for (var i=start; i 0) { - method.apply(target, args); - } else { - method.call(target); - } - }, - - 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, errorRecordedForStack); - } - }, - flush: function() { var queues = this.queues; var queueNames = this.queueNames; @@ -699,85 +705,23 @@ enifed("backburner/deferred-action-queues", 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; while (queueNameIndex < numberOfQueues) { queueName = queueNames[queueNameIndex]; queue = queues[queueName]; - queueItems = queue._queueBeingFlushed = queue._queue.slice(); - queue._queue = []; - queue.targetQueues = Object.create(null); - 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; + var numberOfQueueItems = queue._queue.length; - if (numberOfQueueItems && before) { - before(); - } - - while (queueIndex < numberOfQueueItems) { - 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) { - // - // ** Attention intrepid developer ** - // - // To find out the stack of this task when it was scheduled onto - // the run loop, add the following to your app.js: - // - // Ember.run.backburner.DEBUG = true; // NOTE: This slows your app, don't leave it on in production. - // - // Once that is in place, when you are at a breakpoint and navigate - // here in the stack explorer, you can look at `errorRecordedForStack.stack`, - // which will be the captured stack when this job was scheduled. - // - invoke(target, method, args, onError, errorRecordedForStack); - } - - queueIndex += 4; - } - - queue._queueBeingFlushed = null; - if (numberOfQueueItems && after) { - after(); - } - - if ((priorQueueNameIndex = indexOfPriorQueueWithActions(this, queueNameIndex)) !== -1) { - queueNameIndex = priorQueueNameIndex; - } else { + if (numberOfQueueItems === 0) { queueNameIndex++; + } else { + queue.flush(false /* async */); + queueNameIndex = 0; } } } }; - function indexOfPriorQueueWithActions(daq, currentQueueIndex) { - var queueName, queue; - - for (var i = 0, l = currentQueueIndex; i <= l; i++) { - queueName = daq.queueNames[i]; - queue = daq.queues[queueName]; - if (queue._queue.length) { return i; } - } - - return -1; - } - __exports__["default"] = DeferredActionQueues; }); enifed("backburner/platform", @@ -795,9 +739,11 @@ enifed("backburner/platform", __exports__.needsIETryCatchFix = needsIETryCatchFix; }); enifed("backburner/queue", - ["exports"], - function(__exports__) { + ["./utils","exports"], + function(__dependency1__, __exports__) { "use strict"; + var isString = __dependency1__.isString; + function Queue(name, options, globalOptions) { this.name = name; this.globalOptions = globalOptions || {}; @@ -895,56 +841,89 @@ enifed("backburner/queue", }; }, - // TODO: remove me, only being used for Ember.run.sync - flush: function() { + 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, errorRecordedForStack) { + try { + if (args && args.length > 0) { + method.apply(target, args); + } else { + method.call(target); + } + } catch(error) { + onError(error, errorRecordedForStack); + } + }, + + flush: function(sync) { var queue = this._queue; + var length = queue.length; + + if (length === 0) { + return; + } + 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; + var onError = globalOptions.onError || (globalOptions.onErrorTarget && + globalOptions.onErrorTarget[globalOptions.onErrorMethod]); + var target, method, args, errorRecordedForStack; + var invoke = onError ? this.invokeWithOnError : this.invoke; this.targetQueues = Object.create(null); + var queueItems = this._queueBeingFlushed = this._queue.slice(); + this._queue = []; - if (l && before) { before(); } - for (i = 0; i < l; i += 4) { - target = queue[i]; - method = queue[i+1]; - args = queue[i+2]; - stack = queue[i+3]; // Debugging assistance + if (before) { + before(); + } - // TODO: error handling - if (args && args.length > 0) { - if (onError) { - try { - method.apply(target, args); - } catch (e) { - onError(e); - } - } else { - method.apply(target, args); - } - } else { - if (onError) { - try { - method.call(target); - } catch(e) { - onError(e); - } - } else { - method.call(target); - } + for (var i = 0; i < length; i += 4) { + target = queueItems[i]; + method = queueItems[i+1]; + args = queueItems[i+2]; + errorRecordedForStack = queueItems[i+3]; // Debugging assistance + + if (isString(method)) { + method = target[method]; + } + + // method could have been nullified / canceled during flush + if (method) { + // + // ** Attention intrepid developer ** + // + // To find out the stack of this task when it was scheduled onto + // the run loop, add the following to your app.js: + // + // Ember.run.backburner.DEBUG = true; // NOTE: This slows your app, don't leave it on in production. + // + // Once that is in place, when you are at a breakpoint and navigate + // here in the stack explorer, you can look at `errorRecordedForStack.stack`, + // which will be the captured stack when this job was scheduled. + // + invoke(target, method, args, onError, errorRecordedForStack); } } - if (l && after) { after(); } - // check if new items have been added - if (queue.length > l) { - this._queue = queue.slice(l); - this.flush(); - } else { - this._queue.length = 0; + if (after) { + after(); + } + + this._queueBeingFlushed = undefined; + + if (sync !== false && + this._queue.length > 0) { + // check if new items have been added + this.flush(true); } }, @@ -980,9 +959,11 @@ enifed("backburner/queue", // if not found in current queue // could be in the queue that is being flushed queue = this._queueBeingFlushed; + if (!queue) { return; } + for (i = 0, l = queue.length; i < l; i += 4) { currentTarget = queue[i]; currentMethod = queue[i+1]; @@ -1222,20 +1203,6 @@ enifed("container/container", return container; }, - /** - Sets a key-value pair on the current container. If a parent container, - has the same key, once set on a child, the parent and child will diverge - as expected. - - @method set - @param {Object} object - @param {String} key - @param {any} value - */ - set: function(object, key, value) { - object[key] = value; - }, - /** Registers a factory for later injection. @@ -1485,11 +1452,13 @@ enifed("container/container", /** @method options - @param {String} type + @param {String} fullName @param {Object} options */ - options: function(type, options) { - this.optionsForType(type, options); + options: function(fullName, options) { + options = options || {}; + var normalizedName = this.normalize(fullName); + this._options[normalizedName] = options; }, /** @@ -1533,7 +1502,10 @@ enifed("container/container", var fullNameType = fullName.split(':')[0]; 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.'); + 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); @@ -1596,9 +1568,13 @@ enifed("container/container", var normalizedName = this.normalize(fullName); if (this.cache[normalizedName]) { - throw new Error("Attempted to register an injection for a type that has already been looked up. ('" + normalizedName + "', '" + property + "', '" + injectionName + "')"); + 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); + + addInjection(initRules(this.injections, normalizedName), property, normalizedInjectionName); }, @@ -1704,7 +1680,7 @@ enifed("container/container", 'been looked up. (\'' + normalizedName + '\', \'' + property + '\', \'' + injectionName + '\')'); } - addInjection(this.factoryInjections, normalizedName, property, normalizedInjectionName); + addInjection(initRules(this.factoryInjections, normalizedName), property, normalizedInjectionName); }, /** @@ -1755,7 +1731,7 @@ enifed("container/container", return true; } - return !!container.resolve(fullName); + return container.resolve(fullName) !== undefined; } function lookup(container, fullName, options) { @@ -1791,22 +1767,32 @@ enifed("container/container", if (!injections) { return hash; } - var injection, injectable; + validateInjections(container, injections); + + var injection; for (var i = 0, length = injections.length; i < length; i++) { injection = injections[i]; - injectable = lookup(container, injection.fullName); - - if (injectable !== undefined) { - hash[injection.property] = injectable; - } else { - throw new Error('Attempting to inject an unknown injection: `' + injection.fullName + '`'); - } + hash[injection.property] = lookup(container, injection.fullName); } return hash; } + function validateInjections(container, injections) { + if (!injections) { return; } + + var fullName; + + for (var i = 0, length = injections.length; i < length; i++) { + fullName = injections[i].fullName; + + if (!container.has(fullName)) { + throw new Error('Attempting to inject an unknown injection: `' + fullName + '`'); + } + } + } + function option(container, fullName, optionName) { var options = container._options[fullName]; @@ -1880,8 +1866,22 @@ enifed("container/container", return factoryInjections; } + function normalizeInjectionsHash(hash) { + var injections = []; + + for (var key in hash) { + if (hash.hasOwnProperty(key)) { + + addInjection(injections, key, hash[key]); + } + } + + return injections; + } + function instantiate(container, fullName) { var factory = factoryFor(container, fullName); + var lazyInjections; if (option(container, fullName, 'instantiate') === false) { return factory; @@ -1893,6 +1893,7 @@ enifed("container/container", 'Most likely an improperly defined class or an invalid module export.'); } + if (typeof factory.extend === 'function') { // assume the factory was extendable and is already injected return factory.create(); @@ -1950,8 +1951,11 @@ enifed("container/container", return true; } - function addInjection(rules, factoryName, property, injectionName) { - var injections = rules[factoryName] = rules[factoryName] || []; + function initRules(rules, factoryName) { + return rules[factoryName] || (rules[factoryName] = []); + } + + function addInjection(injections, property, injectionName) { injections.push({ property: property, fullName: injectionName @@ -1960,9 +1964,208 @@ enifed("container/container", __exports__["default"] = Container; }); +enifed("dag-map", + ["exports"], + function(__exports__) { + "use strict"; + function visit(vertex, fn, visited, path) { + var name = vertex.name; + var vertices = vertex.incoming; + var names = vertex.incomingNames; + var len = names.length; + var i; + + if (!visited) { + visited = {}; + } + if (!path) { + path = []; + } + if (visited.hasOwnProperty(name)) { + return; + } + path.push(name); + visited[name] = true; + for (i = 0; i < len; i++) { + visit(vertices[names[i]], fn, visited, path); + } + fn(vertex, path); + path.pop(); + } + + + /** + * DAG stands for Directed acyclic graph. + * + * It is used to build a graph of dependencies checking that there isn't circular + * dependencies. p.e Registering initializers with a certain precedence order. + * + * @class DAG + * @constructor + */ + function DAG() { + this.names = []; + this.vertices = Object.create(null); + } + + /** + * DAG Vertex + * + * @class Vertex + * @constructor + */ + + function Vertex(name) { + this.name = name; + this.incoming = {}; + this.incomingNames = []; + this.hasOutgoing = false; + this.value = null; + } + + /** + * Adds a vertex entry to the graph unless it is already added. + * + * @private + * @method add + * @param {String} name The name of the vertex to add + */ + DAG.prototype.add = function(name) { + if (!name) { + throw new Error("Can't add Vertex without name"); + } + if (this.vertices[name] !== undefined) { + return this.vertices[name]; + } + var vertex = new Vertex(name); + this.vertices[name] = vertex; + this.names.push(name); + return vertex; + }; + + /** + * Adds a vertex to the graph and sets its value. + * + * @private + * @method map + * @param {String} name The name of the vertex. + * @param value The value to put in the vertex. + */ + DAG.prototype.map = function(name, value) { + this.add(name).value = value; + }; + + /** + * Connects the vertices with the given names, adding them to the graph if + * necessary, only if this does not produce is any circular dependency. + * + * @private + * @method addEdge + * @param {String} fromName The name the vertex where the edge starts. + * @param {String} toName The name the vertex where the edge ends. + */ + DAG.prototype.addEdge = function(fromName, toName) { + if (!fromName || !toName || fromName === toName) { + return; + } + var from = this.add(fromName); + var to = this.add(toName); + if (to.incoming.hasOwnProperty(fromName)) { + return; + } + function checkCycle(vertex, path) { + if (vertex.name === toName) { + throw new Error("cycle detected: " + toName + " <- " + path.join(" <- ")); + } + } + visit(from, checkCycle); + from.hasOutgoing = true; + to.incoming[fromName] = from; + to.incomingNames.push(fromName); + }; + + /** + * Visits all the vertex of the graph calling the given function with each one, + * ensuring that the vertices are visited respecting their precedence. + * + * @method topsort + * @param {Function} fn The function to be invoked on each vertex. + */ + DAG.prototype.topsort = function(fn) { + var visited = {}; + var vertices = this.vertices; + var names = this.names; + var len = names.length; + var i, vertex; + + for (i = 0; i < len; i++) { + vertex = vertices[names[i]]; + if (!vertex.hasOutgoing) { + visit(vertex, fn, visited); + } + } + }; + + /** + * Adds a vertex with the given name and value to the graph and joins it with the + * vertices referenced in _before_ and _after_. If there isn't vertices with those + * names, they are added too. + * + * If either _before_ or _after_ are falsy/empty, the added vertex will not have + * an incoming/outgoing edge. + * + * @method addEdges + * @param {String} name The name of the vertex to be added. + * @param value The value of that vertex. + * @param before An string or array of strings with the names of the vertices before + * which this vertex must be visited. + * @param after An string or array of strings with the names of the vertex after + * which this vertex must be visited. + * + */ + DAG.prototype.addEdges = function(name, value, before, after) { + var i; + this.map(name, value); + if (before) { + if (typeof before === 'string') { + this.addEdge(name, before); + } else { + for (i = 0; i < before.length; i++) { + this.addEdge(name, before[i]); + } + } + } + if (after) { + if (typeof after === 'string') { + this.addEdge(after, name); + } else { + for (i = 0; i < after.length; i++) { + this.addEdge(after[i], name); + } + } + } + }; + + __exports__["default"] = DAG; + }); +enifed("dag-map.umd", + ["./dag-map"], + function(__dependency1__) { + "use strict"; + var DAG = __dependency1__["default"]; + + /* global define:true module:true window: true */ + if (typeof enifed === 'function' && enifed.amd) { + enifed(function() { return DAG; }); + } else if (typeof module !== 'undefined' && module.exports) { + module.exports = DAG; + } else if (typeof this !== 'undefined') { + this['DAG'] = DAG; + } + }); enifed("ember-application", - ["ember-metal/core","ember-runtime/system/lazy_load","ember-application/system/dag","ember-application/system/resolver","ember-application/system/application","ember-application/ext/controller"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__) { + ["ember-metal/core","ember-runtime/system/lazy_load","ember-application/system/resolver","ember-application/system/application","ember-application/ext/controller"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) { "use strict"; var Ember = __dependency1__["default"]; var runLoadHooks = __dependency2__.runLoadHooks; @@ -1975,22 +2178,20 @@ enifed("ember-application", @requires ember-views, ember-routing */ - var DAG = __dependency3__["default"]; - var Resolver = __dependency4__.Resolver; - var DefaultResolver = __dependency4__["default"]; - var Application = __dependency5__["default"]; + var Resolver = __dependency3__.Resolver; + var DefaultResolver = __dependency3__["default"]; + var Application = __dependency4__["default"]; // side effect of extending ControllerMixin Ember.Application = Application; - Ember.DAG = DAG; Ember.Resolver = Resolver; Ember.DefaultResolver = DefaultResolver; runLoadHooks('Ember.Application', Application); }); enifed("ember-application/ext/controller", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/error","ember-metal/utils","ember-metal/computed","ember-runtime/mixins/controller","ember-routing/system/controller_for","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) { + ["ember-metal/core","ember-metal/property_get","ember-metal/error","ember-metal/utils","ember-metal/computed","ember-runtime/mixins/controller","ember-routing/system/controller_for","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) { "use strict"; /** @module ember @@ -2000,13 +2201,12 @@ enifed("ember-application/ext/controller", var Ember = __dependency1__["default"]; // Ember.assert var get = __dependency2__.get; - var set = __dependency3__.set; - var EmberError = __dependency4__["default"]; - var inspect = __dependency5__.inspect; - var computed = __dependency6__.computed; - var ControllerMixin = __dependency7__["default"]; - var meta = __dependency5__.meta; - var controllerFor = __dependency8__["default"]; + var EmberError = __dependency3__["default"]; + var inspect = __dependency4__.inspect; + var computed = __dependency5__.computed; + var ControllerMixin = __dependency6__["default"]; + var meta = __dependency4__.meta; + var controllerFor = __dependency7__["default"]; function verifyNeedsDependencies(controller, container, needs) { var dependency, i, l; @@ -2026,7 +2226,8 @@ enifed("ember-application/ext/controller", } } if (missing.length) { - throw new EmberError(inspect(controller) + " needs [ " + missing.join(', ') + " ] but " + (missing.length > 1 ? 'they' : 'it') + " could not be found"); + throw new EmberError(inspect(controller) + " needs [ " + missing.join(', ') + + " ] but " + (missing.length > 1 ? 'they' : 'it') + " could not be found"); } } @@ -2047,7 +2248,12 @@ enifed("ember-application/ext/controller", } } - var errorMessage = inspect(controller) + '#needs does not include `' + controllerName + '`. To access the ' + controllerName + ' controller from ' + inspect(controller) + ', ' + inspect(controller) + ' should have a `needs` property that is an array of the controllers it has access to.'; + var errorMessage = inspect(controller) + '#needs does not include `' + + controllerName + '`. To access the ' + + controllerName + ' controller from ' + + inspect(controller) + ', ' + + inspect(controller) + + ' should have a `needs` property that is an array of the controllers it has access to.'; throw new ReferenceError(errorMessage); }, setUnknownProperty: function (key, value) { @@ -2163,34 +2369,34 @@ enifed("ember-application/ext/controller", __exports__["default"] = ControllerMixin; }); enifed("ember-application/system/application", - ["ember-metal","ember-metal/property_get","ember-metal/property_set","ember-runtime/system/lazy_load","ember-application/system/dag","ember-runtime/system/namespace","ember-runtime/mixins/deferred","ember-application/system/resolver","ember-metal/platform","ember-metal/run_loop","ember-metal/utils","container/container","ember-runtime/controllers/controller","ember-metal/enumerable_utils","ember-runtime/controllers/object_controller","ember-runtime/controllers/array_controller","ember-handlebars/controls/select","ember-views/system/event_dispatcher","ember-views/system/jquery","ember-routing/system/route","ember-routing/system/router","ember-routing/location/hash_location","ember-routing/location/history_location","ember-routing/location/auto_location","ember-routing/location/none_location","ember-routing/system/cache","ember-metal/core","ember-handlebars-compiler","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__, __exports__) { + ["dag-map","container/container","ember-metal","ember-metal/property_get","ember-metal/property_set","ember-runtime/system/lazy_load","ember-runtime/system/namespace","ember-runtime/mixins/deferred","ember-application/system/resolver","ember-metal/platform","ember-metal/run_loop","ember-metal/utils","ember-runtime/controllers/controller","ember-metal/enumerable_utils","ember-runtime/controllers/object_controller","ember-runtime/controllers/array_controller","ember-handlebars/controls/select","ember-views/system/event_dispatcher","ember-views/system/jquery","ember-routing/system/route","ember-routing/system/router","ember-routing/location/hash_location","ember-routing/location/history_location","ember-routing/location/auto_location","ember-routing/location/none_location","ember-routing/system/cache","ember-extension-support/container_debug_adapter","ember-metal/core","ember-handlebars-compiler","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__, __exports__) { "use strict"; /** @module ember @submodule ember-application */ + var DAG = __dependency1__["default"]; + var Container = __dependency2__["default"]; - var Ember = __dependency1__["default"]; + + var Ember = __dependency3__["default"]; // Ember.FEATURES, Ember.deprecate, Ember.assert, Ember.libraries, LOG_VERSION, Namespace, BOOTED - var get = __dependency2__.get; - var set = __dependency3__.set; - var runLoadHooks = __dependency4__.runLoadHooks; - var DAG = __dependency5__["default"]; - var Namespace = __dependency6__["default"]; - var DeferredMixin = __dependency7__["default"]; - var DefaultResolver = __dependency8__["default"]; - var create = __dependency9__.create; - var run = __dependency10__["default"]; - var canInvoke = __dependency11__.canInvoke; - var Container = __dependency12__["default"]; + var get = __dependency4__.get; + var set = __dependency5__.set; + var runLoadHooks = __dependency6__.runLoadHooks; + var Namespace = __dependency7__["default"]; + var DeferredMixin = __dependency8__["default"]; + var DefaultResolver = __dependency9__["default"]; + var create = __dependency10__.create; + var run = __dependency11__["default"]; + var canInvoke = __dependency12__.canInvoke; var Controller = __dependency13__["default"]; var EnumerableUtils = __dependency14__["default"]; var ObjectController = __dependency15__["default"]; var ArrayController = __dependency16__["default"]; var SelectView = __dependency17__["default"]; var EventDispatcher = __dependency18__["default"]; - //import ContainerDebugAdapter from "ember-extension-support/container_debug_adapter"; var jQuery = __dependency19__["default"]; var Route = __dependency20__["default"]; var Router = __dependency21__["default"]; @@ -2200,10 +2406,16 @@ enifed("ember-application/system/application", var NoneLocation = __dependency25__["default"]; var BucketCache = __dependency26__["default"]; - var K = __dependency27__.K; - var EmberHandlebars = __dependency28__["default"]; + // this is technically incorrect (per @wycats) + // it should work properly with: + // `import ContainerDebugAdapter from 'ember-extension-support/container_debug_adapter';` but + // es6-module-transpiler 0.4.0 eagerly grabs the module (which is undefined) + + var ContainerDebugAdapter = __dependency27__["default"]; + + var K = __dependency28__.K; + var EmberHandlebars = __dependency29__["default"]; - var ContainerDebugAdapter; function props(obj) { var properties = []; @@ -2275,10 +2487,10 @@ enifed("ember-application/system/application", names by setting the application's `customEvents` property: ```javascript - App = Ember.Application.create({ + var App = Ember.Application.create({ customEvents: { // add support for the paste event - paste: "paste" + paste: 'paste' } }); ``` @@ -2292,7 +2504,7 @@ enifed("ember-application/system/application", should be delegated, set your application's `rootElement` property: ```javascript - window.App = Ember.Application.create({ + var App = Ember.Application.create({ rootElement: '#ember-app' }); ``` @@ -2335,7 +2547,7 @@ enifed("ember-application/system/application", the `LOG_TRANSITIONS_INTERNAL` flag: ```javascript - window.App = Ember.Application.create({ + var App = Ember.Application.create({ LOG_TRANSITIONS: true, // basic logging of successful transitions LOG_TRANSITIONS_INTERNAL: true // detailed logging of all routing steps }); @@ -2404,10 +2616,10 @@ enifed("ember-application/system/application", corresponding view method name as the value. For example: ```javascript - App = Ember.Application.create({ + var App = Ember.Application.create({ customEvents: { // add support for the paste event - paste: "paste" + paste: 'paste' } }); ``` @@ -2423,7 +2635,9 @@ enifed("ember-application/system/application", _readinessDeferrals: 1, init: function() { - if (!this.$) { this.$ = jQuery; } + if (!this.$) { + this.$ = jQuery; + } this.__container__ = this.buildContainer(); this.Router = this.defaultRouter(); @@ -2532,10 +2746,11 @@ enifed("ember-application/system/application", Example: ```javascript - App = Ember.Application.create(); + var App = Ember.Application.create(); + App.deferReadiness(); - - jQuery.getJSON("/auth-token", function(token) { + // Ember.$ is a reference to the jQuery object/function + Ember.$.getJSON('/auth-token', function(token) { App.token = token; App.advanceReadiness(); }); @@ -2578,7 +2793,8 @@ enifed("ember-application/system/application", ```javascript var App = Ember.Application.create(); - App.Orange = Ember.Object.extend(); + + App.Orange = Ember.Object.extend(); App.register('fruit:favorite', App.Orange); ``` @@ -2589,8 +2805,8 @@ enifed("ember-application/system/application", An example of registering a controller with a non-standard name: ```javascript - var App = Ember.Application.create(), - Session = Ember.Controller.extend(); + var App = Ember.Application.create(); + var Session = Ember.Controller.extend(); App.register('controller:session', Session); @@ -2615,10 +2831,10 @@ enifed("ember-application/system/application", App.Email = Ember.Object.extend(); App.session = Ember.Object.create(); - App.register('model:user', App.Person, {singleton: false }); + App.register('model:user', App.Person, { singleton: false }); App.register('fruit:favorite', App.Orange); - App.register('communication:main', App.Email, {singleton: false}); - App.register('session', App.session, {instantiate: false}); + App.register('communication:main', App.Email, { singleton: false }); + App.register('session', App.session, { instantiate: false }); ``` @method register @@ -2642,8 +2858,8 @@ enifed("ember-application/system/application", An example of providing a session object to all controllers: ```javascript - var App = Ember.Application.create(), - Session = Ember.Object.extend({ isAuthenticated: false }); + var App = Ember.Application.create(); + var Session = Ember.Object.extend({ isAuthenticated: false }); // A factory must be registered before it can be injected App.register('session:main', Session); @@ -2670,7 +2886,7 @@ enifed("ember-application/system/application", directly (via `create` or `new`) bypasses the dependency injection system. - Ember-Data instantiates its models in a unique manner, and consequently + **Note:** Ember-Data instantiates its models in a unique manner, and consequently injections onto models (or all models) will not work as expected. Injections on models can be enabled by setting `Ember.MODEL_FACTORY_INJECTIONS` to `true`. @@ -2741,24 +2957,23 @@ enifed("ember-application/system/application", Typical Example: ```javascript - var App; run(function() { App = Ember.Application.create(); }); - module("acceptance test", { + module('acceptance test', { setup: function() { App.reset(); } }); - test("first test", function() { + test('first test', function() { // App is freshly reset }); - test("first test", function() { + test('second test', function() { // App is again freshly reset }); ``` @@ -2770,14 +2985,13 @@ enifed("ember-application/system/application", to the app becoming ready. ```javascript - var App; run(function() { App = Ember.Application.create(); }); - module("acceptance test", { + module('acceptance test', { setup: function() { run(function() { App.reset(); @@ -2786,12 +3000,13 @@ enifed("ember-application/system/application", } }); - test("first test", function() { + test('first test', function() { ok(true, 'something before app is initialized'); run(function() { App.advanceReadiness(); }); + ok(true, 'something after app is initialized'); }); ``` @@ -2827,7 +3042,7 @@ enifed("ember-application/system/application", var container = this.__container__; var graph = new DAG(); var namespace = this; - var name, initializer; + var initializer; for (var i = 0; i < initializers.length; i++) { initializer = initializersByName[initializers[i]]; @@ -2958,8 +3173,9 @@ enifed("ember-application/system/application", ```javascript Ember.Application.initializer({ name: 'namedInitializer', + initialize: function(container, application) { - Ember.debug("Running namedInitializer!"); + Ember.debug('Running namedInitializer!'); } }); ``` @@ -2973,8 +3189,9 @@ enifed("ember-application/system/application", ```javascript Ember.Application.initializer({ name: 'first', + initialize: function(container, application) { - Ember.debug("First initializer!"); + Ember.debug('First initializer!'); } }); @@ -2990,7 +3207,7 @@ enifed("ember-application/system/application", after: 'first', initialize: function(container, application) { - Ember.debug("Second initializer!"); + Ember.debug('Second initializer!'); } }); @@ -3007,7 +3224,7 @@ enifed("ember-application/system/application", before: 'first', initialize: function(container, application) { - Ember.debug("Pre initializer!"); + Ember.debug('Pre initializer!'); } }); @@ -3025,7 +3242,7 @@ enifed("ember-application/system/application", after: ['first', 'second'], initialize: function(container, application) { - Ember.debug("Post initializer!"); + Ember.debug('Post initializer!'); } }); @@ -3042,10 +3259,11 @@ enifed("ember-application/system/application", ```javascript Ember.Application.initializer({ - name: "preload-data", + name: 'preload-data', initialize: function(container, application) { var store = container.lookup('store:main'); + store.pushPayload(preloadedData); } }); @@ -3077,7 +3295,7 @@ enifed("ember-application/system/application", }); } - + this.initializers[initializer.name] = initializer; }, @@ -3156,8 +3374,6 @@ enifed("ember-application/system/application", container.injection('data-adapter:main', 'containerDebugAdapter', 'container-debug-adapter:main'); // Custom resolver authors may want to register their own ContainerDebugAdapter with this key - // ES6TODO: resolve this via import once ember-application package is ES6'ed - if (!ContainerDebugAdapter) { ContainerDebugAdapter = requireModule('ember-extension-support/container_debug_adapter')['default']; } container.register('container-debug-adapter:main', ContainerDebugAdapter); return container; @@ -3216,192 +3432,6 @@ enifed("ember-application/system/application", __exports__["default"] = Application; }); -enifed("ember-application/system/dag", - ["ember-metal/error","exports"], - function(__dependency1__, __exports__) { - "use strict"; - var EmberError = __dependency1__["default"]; - - function visit(vertex, fn, visited, path) { - var name = vertex.name; - var vertices = vertex.incoming; - var names = vertex.incomingNames; - var len = names.length; - var i; - - if (!visited) { - visited = {}; - } - if (!path) { - path = []; - } - if (visited.hasOwnProperty(name)) { - return; - } - path.push(name); - visited[name] = true; - for (i = 0; i < len; i++) { - visit(vertices[names[i]], fn, visited, path); - } - fn(vertex, path); - path.pop(); - } - - - /** - * DAG stands for Directed acyclic graph. - * - * It is used to build a graph of dependencies checking that there isn't circular - * dependencies. p.e Registering initializers with a certain precedence order. - * - * @class DAG - * @constructor - */ - function DAG() { - this.names = []; - this.vertices = Object.create(null); - } - - /** - * DAG Vertex - * - * @class Vertex - * @constructor - */ - - function Vertex(name) { - this.name = name; - this.incoming = {}; - this.incomingNames = []; - this.hasOutgoing = false; - this.value = null; - } - - /** - * Adds a vertex entry to the graph unless it is already added. - * - * @private - * @method add - * @param {String} name The name of the vertex to add - */ - DAG.prototype.add = function(name) { - if (!name) { - throw new Error("Can't add Vertex without name"); - } - if (this.vertices[name] !== undefined) { - return this.vertices[name]; - } - var vertex = new Vertex(name); - this.vertices[name] = vertex; - this.names.push(name); - return vertex; - }; - - /** - * Adds a vertex to the graph and sets its value. - * - * @private - * @method map - * @param {String} name The name of the vertex. - * @param value The value to put in the vertex. - */ - DAG.prototype.map = function(name, value) { - this.add(name).value = value; - }; - - /** - * Connects the vertices with the given names, adding them to the graph if - * necessary, only if this does not produce is any circular dependency. - * - * @private - * @method addEdge - * @param {String} fromName The name the vertex where the edge starts. - * @param {String} toName The name the vertex where the edge ends. - */ - DAG.prototype.addEdge = function(fromName, toName) { - if (!fromName || !toName || fromName === toName) { - return; - } - var from = this.add(fromName); - var to = this.add(toName); - if (to.incoming.hasOwnProperty(fromName)) { - return; - } - function checkCycle(vertex, path) { - if (vertex.name === toName) { - throw new EmberError("cycle detected: " + toName + " <- " + path.join(" <- ")); - } - } - visit(from, checkCycle); - from.hasOutgoing = true; - to.incoming[fromName] = from; - to.incomingNames.push(fromName); - }; - - /** - * Visits all the vertex of the graph calling the given function with each one, - * ensuring that the vertices are visited respecting their precedence. - * - * @method topsort - * @param {Function} fn The function to be invoked on each vertex. - */ - DAG.prototype.topsort = function(fn) { - var visited = {}; - var vertices = this.vertices; - var names = this.names; - var len = names.length; - var i, vertex; - - for (i = 0; i < len; i++) { - vertex = vertices[names[i]]; - if (!vertex.hasOutgoing) { - visit(vertex, fn, visited); - } - } - }; - - /** - * Adds a vertex with the given name and value to the graph and joins it with the - * vertices referenced in _before_ and _after_. If there isn't vertices with those - * names, they are added too. - * - * If either _before_ or _after_ are falsy/empty, the added vertex will not have - * an incoming/outgoing edge. - * - * @method addEdges - * @param {String} name The name of the vertex to be added. - * @param value The value of that vertex. - * @param before An string or array of strings with the names of the vertices before - * which this vertex must be visited. - * @param after An string or array of strings with the names of the vertex after - * which this vertex must be visited. - * - */ - DAG.prototype.addEdges = function(name, value, before, after) { - var i; - this.map(name, value); - if (before) { - if (typeof before === 'string') { - this.addEdge(name, before); - } else { - for (i = 0; i < before.length; i++) { - this.addEdge(name, before[i]); - } - } - } - if (after) { - if (typeof after === 'string') { - this.addEdge(after, name); - } else { - for (i = 0; i < after.length; i++) { - this.addEdge(after[i], name); - } - } - } - }; - - __exports__["default"] = DAG; - }); enifed("ember-application/system/resolver", ["ember-metal/core","ember-metal/property_get","ember-metal/logger","ember-runtime/system/string","ember-runtime/system/object","ember-runtime/system/namespace","ember-handlebars","ember-metal/dictionary","exports"], function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) { @@ -3483,26 +3513,26 @@ enifed("ember-application/system/resolver", Some examples of how names are resolved: ``` - 'template:post' //=> Ember.TEMPLATES['post'] - 'template:posts/byline' //=> Ember.TEMPLATES['posts/byline'] - 'template:posts.byline' //=> Ember.TEMPLATES['posts/byline'] - 'template:blogPost' //=> Ember.TEMPLATES['blogPost'] - // OR - // Ember.TEMPLATES['blog_post'] - 'controller:post' //=> App.PostController - 'controller:posts.index' //=> App.PostsIndexController - 'controller:blog/post' //=> Blog.PostController - 'controller:basic' //=> Ember.Controller - 'route:post' //=> App.PostRoute - 'route:posts.index' //=> App.PostsIndexRoute - 'route:blog/post' //=> Blog.PostRoute - 'route:basic' //=> Ember.Route - 'view:post' //=> App.PostView - 'view:posts.index' //=> App.PostsIndexView - 'view:blog/post' //=> Blog.PostView - 'view:basic' //=> Ember.View - 'foo:post' //=> App.PostFoo - 'model:post' //=> App.Post + 'template:post' //=> Ember.TEMPLATES['post'] + 'template:posts/byline' //=> Ember.TEMPLATES['posts/byline'] + 'template:posts.byline' //=> Ember.TEMPLATES['posts/byline'] + 'template:blogPost' //=> Ember.TEMPLATES['blogPost'] + // OR + // Ember.TEMPLATES['blog_post'] + 'controller:post' //=> App.PostController + 'controller:posts.index' //=> App.PostsIndexController + 'controller:blog/post' //=> Blog.PostController + 'controller:basic' //=> Ember.Controller + 'route:post' //=> App.PostRoute + 'route:posts.index' //=> App.PostsIndexRoute + 'route:blog/post' //=> Blog.PostRoute + 'route:basic' //=> Ember.Route + 'view:post' //=> App.PostView + 'view:posts.index' //=> App.PostsIndexView + 'view:blog/post' //=> Blog.PostView + 'view:basic' //=> Ember.View + 'foo:post' //=> App.PostFoo + 'model:post' //=> App.Post ``` @class DefaultResolver @@ -3902,7 +3932,7 @@ enifed("ember-extension-support/container_debug_adapter", @return {Array} An array of strings. */ catalogEntriesByType: function(type) { - var namespaces = emberA(Namespace.NAMESPACES), types = emberA(), self = this; + var namespaces = emberA(Namespace.NAMESPACES), types = emberA(); var typeSuffixRegex = new RegExp(classify(type) + "$"); namespaces.forEach(function(namespace) { @@ -4246,8 +4276,7 @@ enifed("ember-extension-support/data_adapter", */ wrapModelType: function(type, name) { var records = this.getRecords(type); - var self = this; - var release, typeToSend; + var typeToSend; typeToSend = { name: name || type.toString(), @@ -4348,8 +4377,6 @@ enifed("ember-extension-support/data_adapter", */ wrapRecord: function(record) { var recordToSend = { object: record }; - var columnValues = {}; - var self = this; recordToSend.columnValues = this.getRecordColumnValues(record); recordToSend.searchKeywords = this.getRecordKeywords(record); @@ -4481,7 +4508,7 @@ enifed("ember-handlebars-compiler", @class Handlebars @namespace Ember */ - var EmberHandlebars = Ember.Handlebars = objectCreate(Handlebars); + var EmberHandlebars = Ember.Handlebars = Handlebars.create(); /** Register a bound helper or custom view helper. @@ -4623,44 +4650,6 @@ enifed("ember-handlebars-compiler", return "data.buffer.push("+string+");"; }; - // Hacks ahead: - // Handlebars presently has a bug where the `blockHelperMissing` hook - // doesn't get passed the name of the missing helper name, but rather - // gets passed the value of that missing helper evaluated on the current - // context, which is most likely `undefined` and totally useless. - // - // So we alter the compiled template function to pass the name of the helper - // instead, as expected. - // - // This can go away once the following is closed: - // https://github.com/wycats/handlebars.js/issues/634 - - var DOT_LOOKUP_REGEX = /helpers\.(.*?)\)/; - var BRACKET_STRING_LOOKUP_REGEX = /helpers\['(.*?)'/; - var INVOCATION_SPLITTING_REGEX = /(.*blockHelperMissing\.call\(.*)(stack[0-9]+)(,.*)/; - - EmberHandlebars.JavaScriptCompiler.stringifyLastBlockHelperMissingInvocation = function(source) { - var helperInvocation = source[source.length - 1]; - var helperName = (DOT_LOOKUP_REGEX.exec(helperInvocation) || BRACKET_STRING_LOOKUP_REGEX.exec(helperInvocation))[1]; - var matches = INVOCATION_SPLITTING_REGEX.exec(helperInvocation); - - source[source.length - 1] = matches[1] + "'" + helperName + "'" + matches[3]; - }; - - var stringifyBlockHelperMissing = EmberHandlebars.JavaScriptCompiler.stringifyLastBlockHelperMissingInvocation; - - var originalBlockValue = EmberHandlebars.JavaScriptCompiler.prototype.blockValue; - EmberHandlebars.JavaScriptCompiler.prototype.blockValue = function() { - originalBlockValue.apply(this, arguments); - stringifyBlockHelperMissing(this.source); - }; - - var originalAmbiguousBlockValue = EmberHandlebars.JavaScriptCompiler.prototype.ambiguousBlockValue; - EmberHandlebars.JavaScriptCompiler.prototype.ambiguousBlockValue = function() { - originalAmbiguousBlockValue.apply(this, arguments); - stringifyBlockHelperMissing(this.source); - }; - /** Rewrite simple mustaches from `{{foo}}` to `{{bind "foo"}}`. This means that all simple mustaches in Ember's Handlebars will also set up an observer to @@ -4750,8 +4739,8 @@ enifed("ember-handlebars-compiler", __exports__["default"] = EmberHandlebars; }); enifed("ember-handlebars", - ["ember-handlebars-compiler","ember-metal/core","ember-runtime/system/lazy_load","ember-handlebars/loader","ember-handlebars/ext","ember-handlebars/string","ember-handlebars/helpers/shared","ember-handlebars/helpers/binding","ember-handlebars/helpers/collection","ember-handlebars/helpers/view","ember-handlebars/helpers/unbound","ember-handlebars/helpers/debug","ember-handlebars/helpers/each","ember-handlebars/helpers/template","ember-handlebars/helpers/partial","ember-handlebars/helpers/yield","ember-handlebars/helpers/loc","ember-handlebars/controls/checkbox","ember-handlebars/controls/select","ember-handlebars/controls/text_area","ember-handlebars/controls/text_field","ember-handlebars/controls/text_support","ember-handlebars/controls","ember-handlebars/component_lookup","ember-handlebars/views/handlebars_bound_view","ember-handlebars/views/metamorph_view","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__, __exports__) { + ["ember-handlebars-compiler","ember-metal/core","ember-runtime/system/lazy_load","ember-handlebars/loader","ember-handlebars/ext","ember-handlebars/string","ember-handlebars/helpers/binding","ember-handlebars/helpers/if_unless","ember-handlebars/helpers/with","ember-handlebars/helpers/bind_attr","ember-handlebars/helpers/collection","ember-handlebars/helpers/view","ember-handlebars/helpers/unbound","ember-handlebars/helpers/debug","ember-handlebars/helpers/each","ember-handlebars/helpers/template","ember-handlebars/helpers/partial","ember-handlebars/helpers/yield","ember-handlebars/helpers/loc","ember-handlebars/controls/checkbox","ember-handlebars/controls/select","ember-handlebars/controls/text_area","ember-handlebars/controls/text_field","ember-handlebars/controls/text_support","ember-handlebars/controls","ember-handlebars/component_lookup","ember-handlebars/views/handlebars_bound_view","ember-handlebars/views/metamorph_view","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__, __exports__) { "use strict"; var EmberHandlebars = __dependency1__["default"]; var Ember = __dependency2__["default"]; @@ -4760,68 +4749,61 @@ enifed("ember-handlebars", var runLoadHooks = __dependency3__.runLoadHooks; var bootstrap = __dependency4__["default"]; - var normalizePath = __dependency5__.normalizePath; - var template = __dependency5__.template; var makeBoundHelper = __dependency5__.makeBoundHelper; var registerBoundHelper = __dependency5__.registerBoundHelper; - var resolveHash = __dependency5__.resolveHash; - var resolveParams = __dependency5__.resolveParams; - var getEscaped = __dependency5__.getEscaped; - var handlebarsGet = __dependency5__.handlebarsGet; - var evaluateUnboundHelper = __dependency5__.evaluateUnboundHelper; var helperMissingHelper = __dependency5__.helperMissingHelper; var blockHelperMissingHelper = __dependency5__.blockHelperMissingHelper; + var handlebarsGet = __dependency5__.handlebarsGet; // side effect of extending StringUtils of htmlSafe - var resolvePaths = __dependency7__["default"]; - var bind = __dependency8__.bind; - var _triageMustacheHelper = __dependency8__._triageMustacheHelper; - var resolveHelper = __dependency8__.resolveHelper; - var bindHelper = __dependency8__.bindHelper; + var bind = __dependency7__.bind; + var _triageMustacheHelper = __dependency7__._triageMustacheHelper; + var resolveHelper = __dependency7__.resolveHelper; + var bindHelper = __dependency7__.bindHelper; + + var ifHelper = __dependency8__.ifHelper; var boundIfHelper = __dependency8__.boundIfHelper; var unboundIfHelper = __dependency8__.unboundIfHelper; - var withHelper = __dependency8__.withHelper; - var ifHelper = __dependency8__.ifHelper; var unlessHelper = __dependency8__.unlessHelper; - var bindAttrHelper = __dependency8__.bindAttrHelper; - var bindAttrHelperDeprecated = __dependency8__.bindAttrHelperDeprecated; - var bindClasses = __dependency8__.bindClasses; - var collectionHelper = __dependency9__["default"]; - var ViewHelper = __dependency10__.ViewHelper; - var viewHelper = __dependency10__.viewHelper; - var unboundHelper = __dependency11__["default"]; - var logHelper = __dependency12__.logHelper; - var debuggerHelper = __dependency12__.debuggerHelper; - var EachView = __dependency13__.EachView; - var GroupedEach = __dependency13__.GroupedEach; - var eachHelper = __dependency13__.eachHelper; - var templateHelper = __dependency14__["default"]; - var partialHelper = __dependency15__["default"]; - var yieldHelper = __dependency16__["default"]; - var locHelper = __dependency17__["default"]; + var withHelper = __dependency9__["default"]; + + var bindAttrHelper = __dependency10__.bindAttrHelper; + var bindAttrHelperDeprecated = __dependency10__.bindAttrHelperDeprecated; + var bindClasses = __dependency10__.bindClasses; + + var collectionHelper = __dependency11__["default"]; + var ViewHelper = __dependency12__.ViewHelper; + var viewHelper = __dependency12__.viewHelper; + var unboundHelper = __dependency13__["default"]; + var logHelper = __dependency14__.logHelper; + var debuggerHelper = __dependency14__.debuggerHelper; + var EachView = __dependency15__.EachView; + var eachHelper = __dependency15__.eachHelper; + var templateHelper = __dependency16__["default"]; + var partialHelper = __dependency17__["default"]; + var yieldHelper = __dependency18__["default"]; + var locHelper = __dependency19__["default"]; - var Checkbox = __dependency18__["default"]; - var Select = __dependency19__.Select; - var SelectOption = __dependency19__.SelectOption; - var SelectOptgroup = __dependency19__.SelectOptgroup; - var TextArea = __dependency20__["default"]; - var TextField = __dependency21__["default"]; - var TextSupport = __dependency22__["default"]; - var inputHelper = __dependency23__.inputHelper; - var textareaHelper = __dependency23__.textareaHelper; + var Checkbox = __dependency20__["default"]; + var Select = __dependency21__.Select; + var SelectOption = __dependency21__.SelectOption; + var SelectOptgroup = __dependency21__.SelectOptgroup; + var TextArea = __dependency22__["default"]; + var TextField = __dependency23__["default"]; + var TextSupport = __dependency24__["default"]; + var inputHelper = __dependency25__.inputHelper; + var textareaHelper = __dependency25__.textareaHelper; - - var ComponentLookup = __dependency24__["default"]; - var _HandlebarsBoundView = __dependency25__._HandlebarsBoundView; - var SimpleHandlebarsView = __dependency25__.SimpleHandlebarsView; - var _wrapMap = __dependency26__._wrapMap; - var _SimpleMetamorphView = __dependency26__._SimpleMetamorphView; - var _MetamorphView = __dependency26__._MetamorphView; - var _Metamorph = __dependency26__._Metamorph; + var ComponentLookup = __dependency26__["default"]; + var _HandlebarsBoundView = __dependency27__._HandlebarsBoundView; + var SimpleHandlebarsView = __dependency27__.SimpleHandlebarsView; + var _MetamorphView = __dependency28__["default"]; + var _SimpleMetamorphView = __dependency28__._SimpleMetamorphView; + var _Metamorph = __dependency28__._Metamorph; /** @@ -4834,33 +4816,24 @@ enifed("ember-handlebars", // Ember.Handlebars.Globals EmberHandlebars.bootstrap = bootstrap; - EmberHandlebars.template = template; EmberHandlebars.makeBoundHelper = makeBoundHelper; EmberHandlebars.registerBoundHelper = registerBoundHelper; - EmberHandlebars.resolveHash = resolveHash; - EmberHandlebars.resolveParams = resolveParams; EmberHandlebars.resolveHelper = resolveHelper; - EmberHandlebars.get = handlebarsGet; - EmberHandlebars.getEscaped = getEscaped; - EmberHandlebars.evaluateUnboundHelper = evaluateUnboundHelper; EmberHandlebars.bind = bind; EmberHandlebars.bindClasses = bindClasses; EmberHandlebars.EachView = EachView; - EmberHandlebars.GroupedEach = GroupedEach; - EmberHandlebars.resolvePaths = resolvePaths; EmberHandlebars.ViewHelper = ViewHelper; - EmberHandlebars.normalizePath = normalizePath; // Ember Globals Ember.Handlebars = EmberHandlebars; + EmberHandlebars.get = handlebarsGet; Ember.ComponentLookup = ComponentLookup; Ember._SimpleHandlebarsView = SimpleHandlebarsView; Ember._HandlebarsBoundView = _HandlebarsBoundView; Ember._SimpleMetamorphView = _SimpleMetamorphView; Ember._MetamorphView = _MetamorphView; Ember._Metamorph = _Metamorph; - Ember._metamorphWrapMap = _wrapMap; Ember.TextSupport = TextSupport; Ember.Checkbox = Checkbox; Ember.Select = Select; @@ -4906,7 +4879,7 @@ enifed("ember-handlebars/component_lookup", "use strict"; var EmberObject = __dependency1__["default"]; - var ComponentLookup = EmberObject.extend({ + __exports__["default"] = EmberObject.extend({ lookupFactory: function(name, container) { container = container || this.container; @@ -4932,12 +4905,10 @@ enifed("ember-handlebars/component_lookup", } } }); - - __exports__["default"] = ComponentLookup; }); enifed("ember-handlebars/controls", - ["ember-handlebars/controls/checkbox","ember-handlebars/controls/text_field","ember-handlebars/controls/text_area","ember-metal/core","ember-handlebars-compiler","ember-handlebars/ext","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) { + ["ember-handlebars/controls/checkbox","ember-handlebars/controls/text_field","ember-handlebars/controls/text_area","ember-metal/core","ember-handlebars-compiler","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) { "use strict"; var Checkbox = __dependency1__["default"]; var TextField = __dependency2__["default"]; @@ -4948,21 +4919,12 @@ enifed("ember-handlebars/controls", // var emberAssert = Ember.assert; var EmberHandlebars = __dependency5__["default"]; - var handlebarsGet = __dependency6__.handlebarsGet; - var helpers = EmberHandlebars.helpers; + /** @module ember @submodule ember-handlebars-compiler */ - function _resolveOption(context, options, key) { - if (options.hashTypes[key] === "ID") { - return handlebarsGet(context, options.hash[key], options); - } else { - return options.hash[key]; - } - } - /** The `{{input}}` helper inserts an HTML `` tag into the template, @@ -5029,10 +4991,12 @@ enifed("ember-handlebars/controls", The action property defines the action which is sent when the user presses the return key. + ```handlebars {{input action="submit"}} ``` + The helper allows some user events to send actions. * `enter` @@ -5046,10 +5010,12 @@ enifed("ember-handlebars/controls", For example, if you desire an action to be sent when the input is blurred, you only need to setup the action name to the event name property. + ```handlebars {{input focus-in="alertMessage"}} ``` + See more about [Text Support Actions](/api/classes/Ember.TextField.html) ## Extension @@ -5141,22 +5107,29 @@ enifed("ember-handlebars/controls", */ function inputHelper(options) { + var view = options.data.view; var hash = options.hash; var types = options.hashTypes; - var inputType = _resolveOption(this, options, 'type'); var onEvent = hash.on; + var inputType; + + if (types.type === 'ID') { + inputType = view.getStream(hash.type).value(); + } else { + inputType = hash.type; + } if (inputType === 'checkbox') { delete hash.type; delete types.type; - return helpers.view.call(this, Checkbox, options); + return EmberHandlebars.helpers.view.call(this, Checkbox, options); } else { delete hash.on; hash.onEvent = onEvent || 'enter'; - return helpers.view.call(this, TextField, options); + return EmberHandlebars.helpers.view.call(this, TextField, options); } } @@ -5347,10 +5320,7 @@ enifed("ember-handlebars/controls", */ function textareaHelper(options) { - var hash = options.hash; - var types = options.hashTypes; - - return helpers.view.call(this, TextArea, options); + return EmberHandlebars.helpers.view.call(this, TextArea, options); } __exports__.textareaHelper = textareaHelper; @@ -5458,7 +5428,6 @@ enifed("ember-handlebars/controls/select", var observer = __dependency11__.observer; var defineProperty = __dependency12__.defineProperty; - var precompileTemplate = EmberHandlebars.compile; var SelectOption = View.extend({ instrumentDisplay: 'Ember.SelectOption', @@ -5770,59 +5739,42 @@ enifed("ember-handlebars/controls/select", tagName: 'select', classNames: ['ember-select'], - defaultTemplate: Ember.Handlebars.template(function anonymous(Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [4,'>= 1.0.0']; - helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {}; - var buffer = '', stack1, escapeExpression=this.escapeExpression, self=this; - - function program1(depth0,data) { - - var buffer = '', stack1; + defaultTemplate: Ember.Handlebars.template({"1":function(depth0,helpers,partials,data) { + var stack1, buffer = ''; data.buffer.push(""); return buffer; - } - - function program3(depth0,data) { - + },"3":function(depth0,helpers,partials,data) { var stack1; - stack1 = helpers.each.call(depth0, "view.groupedContent", {hash:{},hashTypes:{},hashContexts:{},inverse:self.noop,fn:self.program(4, program4, data),contexts:[depth0],types:["ID"],data:data}); - if(stack1 || stack1 === 0) { data.buffer.push(stack1); } + stack1 = helpers.each.call(depth0, "group", "in", "view.groupedContent", {"name":"each","hash":{},"hashTypes":{},"hashContexts":{},"fn":this.program(4, data),"inverse":this.noop,"types":["ID","ID","ID"],"contexts":[depth0,depth0,depth0],"data":data}); + if (stack1 != null) { data.buffer.push(stack1); } else { data.buffer.push(''); } - } - function program4(depth0,data) { - - - data.buffer.push(escapeExpression(helpers.view.call(depth0, "view.groupView", {hash:{ - 'content': ("content"), - 'label': ("label") - },hashTypes:{'content': "ID",'label': "ID"},hashContexts:{'content': depth0,'label': depth0},contexts:[depth0],types:["ID"],data:data}))); - } - - function program6(depth0,data) { - + },"4":function(depth0,helpers,partials,data) { + var escapeExpression=this.escapeExpression; + data.buffer.push(escapeExpression(helpers.view.call(depth0, "view.groupView", {"name":"view","hash":{ + 'label': ("group.label"), + 'content': ("group.content") + },"hashTypes":{'label': "ID",'content': "ID"},"hashContexts":{'label': depth0,'content': depth0},"types":["ID"],"contexts":[depth0],"data":data}))); + },"6":function(depth0,helpers,partials,data) { var stack1; - stack1 = helpers.each.call(depth0, "view.content", {hash:{},hashTypes:{},hashContexts:{},inverse:self.noop,fn:self.program(7, program7, data),contexts:[depth0],types:["ID"],data:data}); - if(stack1 || stack1 === 0) { data.buffer.push(stack1); } + stack1 = helpers.each.call(depth0, "item", "in", "view.content", {"name":"each","hash":{},"hashTypes":{},"hashContexts":{},"fn":this.program(7, data),"inverse":this.noop,"types":["ID","ID","ID"],"contexts":[depth0,depth0,depth0],"data":data}); + if (stack1 != null) { data.buffer.push(stack1); } else { data.buffer.push(''); } - } - function program7(depth0,data) { - - - data.buffer.push(escapeExpression(helpers.view.call(depth0, "view.optionView", {hash:{ - 'content': ("") - },hashTypes:{'content': "ID"},hashContexts:{'content': depth0},contexts:[depth0],types:["ID"],data:data}))); - } - - stack1 = helpers['if'].call(depth0, "view.prompt", {hash:{},hashTypes:{},hashContexts:{},inverse:self.noop,fn:self.program(1, program1, data),contexts:[depth0],types:["ID"],data:data}); - if(stack1 || stack1 === 0) { data.buffer.push(stack1); } - stack1 = helpers['if'].call(depth0, "view.optionGroupPath", {hash:{},hashTypes:{},hashContexts:{},inverse:self.program(6, program6, data),fn:self.program(3, program3, data),contexts:[depth0],types:["ID"],data:data}); - if(stack1 || stack1 === 0) { data.buffer.push(stack1); } + },"7":function(depth0,helpers,partials,data) { + var escapeExpression=this.escapeExpression; + data.buffer.push(escapeExpression(helpers.view.call(depth0, "view.optionView", {"name":"view","hash":{ + 'content': ("item") + },"hashTypes":{'content': "ID"},"hashContexts":{'content': depth0},"types":["ID"],"contexts":[depth0],"data":data}))); + },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { + var stack1, buffer = ''; + stack1 = helpers['if'].call(depth0, "view.prompt", {"name":"if","hash":{},"hashTypes":{},"hashContexts":{},"fn":this.program(1, data),"inverse":this.noop,"types":["ID"],"contexts":[depth0],"data":data}); + if (stack1 != null) { data.buffer.push(stack1); } + stack1 = helpers['if'].call(depth0, "view.optionGroupPath", {"name":"if","hash":{},"hashTypes":{},"hashContexts":{},"fn":this.program(3, data),"inverse":this.program(6, data),"types":["ID"],"contexts":[depth0],"data":data}); + if (stack1 != null) { data.buffer.push(stack1); } return buffer; - - }), + },"useData":true}), attributeBindings: ['multiple', 'disabled', 'tabindex', 'name', 'required', 'autofocus', 'form', 'size'], @@ -6150,7 +6102,16 @@ enifed("ember-handlebars/controls/text_area", classNames: ['ember-text-area'], tagName: "textarea", - attributeBindings: ['rows', 'cols', 'name', 'selectionEnd', 'selectionStart', 'wrap', 'lang', 'dir'], + attributeBindings: [ + 'rows', + 'cols', + 'name', + 'selectionEnd', + 'selectionStart', + 'wrap', + 'lang', + 'dir' + ], rows: null, cols: null, @@ -6170,18 +6131,15 @@ enifed("ember-handlebars/controls/text_area", }); }); enifed("ember-handlebars/controls/text_field", - ["ember-metal/property_get","ember-metal/property_set","ember-views/views/component","ember-handlebars/controls/text_support","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) { + ["ember-views/views/component","ember-handlebars/controls/text_support","exports"], + function(__dependency1__, __dependency2__, __exports__) { "use strict"; /** @module ember @submodule ember-handlebars */ - - var get = __dependency1__.get; - var set = __dependency2__.set; - var Component = __dependency3__["default"]; - var TextSupport = __dependency4__["default"]; + var Component = __dependency1__["default"]; + var TextSupport = __dependency2__["default"]; /** @@ -6206,11 +6164,31 @@ enifed("ember-handlebars/controls/text_field", classNames: ['ember-text-field'], tagName: "input", - attributeBindings: ['type', 'value', 'size', 'pattern', 'name', 'min', 'max', - 'accept', 'autocomplete', 'autosave', 'formaction', - 'formenctype', 'formmethod', 'formnovalidate', 'formtarget', - 'height', 'inputmode', 'list', 'multiple', 'step', 'lang', 'dir', - 'width'], + attributeBindings: [ + 'accept', + 'autocomplete', + 'autosave', + 'dir', + 'formaction', + 'formenctype', + 'formmethod', + 'formnovalidate', + 'formtarget', + 'height', + 'inputmode', + 'lang', + 'list', + 'max', + 'min', + 'multiple', + 'name', + 'pattern', + 'size', + 'step', + 'type', + 'value', + 'width' + ], /** The `value` attribute of the input element. As the user inputs text, this @@ -6296,21 +6274,30 @@ enifed("ember-handlebars/controls/text_support", var TextSupport = Mixin.create(TargetActionSupport, { value: "", - attributeBindings: ['placeholder', 'disabled', 'maxlength', 'tabindex', 'readonly', - 'autofocus', 'form', 'selectionDirection', 'spellcheck', 'required', - 'title', 'autocapitalize', 'autocorrect'], + attributeBindings: [ + 'autocapitalize', + 'autocorrect', + 'autofocus', + 'disabled', + 'form', + 'maxlength', + 'placeholder', + 'readonly', + 'required', + 'selectionDirection', + 'spellcheck', + 'tabindex', + 'title' + ], placeholder: null, disabled: false, maxlength: null, init: function() { this._super(); - this.on("focusOut", this, this._elementValueDidChange); - this.on("change", this, this._elementValueDidChange); this.on("paste", this, this._elementValueDidChange); this.on("cut", this, this._elementValueDidChange); this.on("input", this, this._elementValueDidChange); - this.on("keyUp", this, this.interpretKeyEvents); }, /** @@ -6396,6 +6383,10 @@ enifed("ember-handlebars/controls/text_support", sendAction('escape-press', this, event); }, + change: function(event) { + this._elementValueDidChange(event); + }, + /** Called when the text area is focused. @@ -6417,6 +6408,7 @@ enifed("ember-handlebars/controls/text_support", @param {Event} event */ focusOut: function(event) { + this._elementValueDidChange(event); sendAction('focus-out', this, event); }, @@ -6431,8 +6423,36 @@ enifed("ember-handlebars/controls/text_support", */ keyPress: function(event) { sendAction('key-press', this, event); - } + }, + /** + Called when the browser triggers a `keyup` event on the element. + + Uses sendAction to send the `key-up` action passing the current value + and event as parameters. + + @method keyUp + @param {Event} event + */ + keyUp: function(event) { + this.interpretKeyEvents(event); + + this.sendAction('key-up', get(this, 'value'), event); + }, + + /** + Called when the browser triggers a `keydown` event on the element. + + Uses sendAction to send the `key-down` action passing the current value + and event as parameters. Note that generally in key-down the value is unchanged + (as the key pressing has not completed yet). + + @method keyDown + @param {Event} event + */ + keyDown: function(event) { + this.sendAction('key-down', get(this, 'value'), event); + } }); TextSupport.KEY_EVENTS = { @@ -6467,8 +6487,8 @@ enifed("ember-handlebars/controls/text_support", __exports__["default"] = TextSupport; }); enifed("ember-handlebars/ext", - ["ember-metal/core","ember-runtime/system/string","ember-handlebars-compiler","ember-metal/property_get","ember-metal/error","ember-metal/mixin","ember-views/views/view","ember-handlebars/views/metamorph_view","ember-metal/path_cache","ember-metal/is_empty","ember-metal/cache","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __exports__) { + ["ember-metal/core","ember-runtime/system/string","ember-handlebars-compiler","ember-metal/property_get","ember-metal/error","ember-metal/mixin","ember-views/views/view","ember-metal/path_cache","ember-metal/streams/stream","ember-metal/streams/read","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; // Ember.FEATURES, Ember.assert, Ember.Handlebars, Ember.lookup @@ -6477,76 +6497,22 @@ enifed("ember-handlebars/ext", var fmt = __dependency2__.fmt; var EmberHandlebars = __dependency3__["default"]; - var helpers = EmberHandlebars.helpers; var get = __dependency4__.get; var EmberError = __dependency5__["default"]; var IS_BINDING = __dependency6__.IS_BINDING; var View = __dependency7__["default"]; - var _Metamorph = __dependency8__._Metamorph; - var detectIsGlobal = __dependency9__.isGlobal; + var detectIsGlobal = __dependency8__.isGlobal; // late bound via requireModule because of circular dependencies. var resolveHelper, SimpleHandlebarsView; - var isEmpty = __dependency10__["default"]; + var Stream = __dependency9__["default"]; + var readArray = __dependency10__.readArray; + var readHash = __dependency10__.readHash; var slice = [].slice; - var originalTemplate = EmberHandlebars.template; - - /** - If a path starts with a reserved keyword, returns the root - that should be used. - - @private - @method normalizePath - @for Ember - @param root {Object} - @param path {String} - @param data {Hash} - */ - - var Cache = __dependency11__["default"]; - - var FIRST_SEGMENT_CACHE = new Cache(1000, function(path){ - return path.split('.', 1)[0]; - }); - - function normalizePath(root, path, data) { - var keywords = (data && data.keywords) || {}; - var keyword, isKeyword; - - // Get the first segment of the path. For example, if the - // path is "foo.bar.baz", returns "foo". - keyword = FIRST_SEGMENT_CACHE.get(path); - - // Test to see if the first path is a keyword that has been - // passed along in the view's data hash. If so, we will treat - // that object as the new root. - if (keywords.hasOwnProperty(keyword)) { - // Look up the value in the template's data hash. - root = keywords[keyword]; - isKeyword = true; - - // Handle cases where the entire path is the reserved - // word. In that case, return the object itself. - if (path === keyword) { - path = ''; - } else { - // Strip the keyword from the path and look up - // the remainder from the newly found root. - path = path.substr(keyword.length+1); - } - } - - return { - root: root, - path: path, - isKeyword: isKeyword - }; - } - /** Lookup both on root and on window. If the path starts with @@ -6558,50 +6524,11 @@ enifed("ember-handlebars/ext", @param {Object} root The object to look up the property on @param {String} path The path to be lookedup @param {Object} options The template's option hash + @deprecated */ function handlebarsGet(root, path, options) { - var data = options && options.data; - var normalizedPath = normalizePath(root, path, data); - var value; - - // In cases where the path begins with a keyword, change the - // root to the value represented by that keyword, and ensure - // the path is relative to it. - root = normalizedPath.root; - path = normalizedPath.path; - - // Ember.get with a null root and GlobalPath will fall back to - // Ember.lookup, which is no longer allowed in templates. - // - // But when outputting a primitive, root will be the primitive - // and path a blank string. These primitives should pass through - // to `get`. - if (root || path === '') { - value = get(root, path); - } - - if (detectIsGlobal(path)) { - if (value === undefined && root !== Ember.lookup) { - root = Ember.lookup; - value = get(root, path); - } - if (root === Ember.lookup || root === null) { - } - } - - return value; - } - - function lookupViewInContainer(container, path) { - return container.lookupFactory('view:'+path); - } - - function lookupViewByClassName(path) { - var viewClass; - if (detectIsGlobal(path)) { - viewClass = get(path); - return viewClass; - } + + return options.data.view.getStream(path).value(); } /** @@ -6628,41 +6555,28 @@ enifed("ember-handlebars/ext", @param {Object} context The context of the template being rendered @param {String} path The path to be lookedup @param {Object} container The container - @param {Object} options The options from the template + @param {Object} data The template's data hash */ - function handlebarsGetView(context, path, container, options) { + function handlebarsGetView(context, path, container, data) { var viewClass; - var data; - var pathType; - if (options) { - data = options.data; - pathType = options.types && options.types[0]; - } - if ('string' === typeof path) { - if('STRING' === pathType && container) { - viewClass = lookupViewInContainer(container, path); - + if (!data) { + throw new Error("handlebarsGetView: must pass data"); } - if(!viewClass) { - viewClass = lookupViewByClassName(path); + // Only lookup view class on context if there is a context. If not, + // the global lookup path on get may kick in. + var lazyValue = data.view.getStream(path); + viewClass = lazyValue.value(); + var isGlobal = detectIsGlobal(path); + + if (!viewClass && !isGlobal) { + viewClass = container.lookupFactory('view:'+path); } - - if(!viewClass) { - if (data) { - var normalizedPath = normalizePath(context, path, data); - context = normalizedPath.root; - path = normalizedPath.path; - } - - // Only lookup view class on context if there is a context. If not, - // the global lookup path on get may kick in. - viewClass = context && get(context, path); - - if(!viewClass) { - // try the container once more with the normalized path - viewClass = lookupViewInContainer(container, path); + if (!viewClass && isGlobal) { + var globalViewClass = get(path); + if (globalViewClass) { + viewClass = globalViewClass; } } } else { @@ -6671,80 +6585,28 @@ enifed("ember-handlebars/ext", // Sometimes a view's value is yet another path if ('string' === typeof viewClass && data && data.view) { - viewClass = handlebarsGetView(data.view, viewClass, container, { - data: data, - types: ['ID'] - }); + viewClass = handlebarsGetView(data.view, viewClass, container, data); } return viewClass; } - /** - This method uses `Ember.Handlebars.get` to lookup a value, then ensures - that the value is escaped properly. - - If `unescaped` is a truthy value then the escaping will not be performed. - - @method getEscaped - @for Ember.Handlebars - @param {Object} root The object to look up the property on - @param {String} path The path to be lookedup - @param {Object} options The template's option hash - @since 1.4.0 - */ - function getEscaped(root, path, options) { - var result = handlebarsGet(root, path, options); - - if (result === null || result === undefined) { - result = ""; - } else if (!(result instanceof Handlebars.SafeString)) { - result = String(result); - } - if (!options.hash.unescaped){ - result = Handlebars.Utils.escapeExpression(result); + function stringifyValue(value, shouldEscape) { + if (value === null || value === undefined) { + value = ""; + } else if (!(value instanceof Handlebars.SafeString)) { + value = String(value); } - return result; + if (shouldEscape) { + value = Handlebars.Utils.escapeExpression(value); + } + + return value; } - __exports__.getEscaped = getEscaped;function resolveParams(context, params, options) { - var resolvedParams = [], types = options.types, param, type; - - for (var i=0, l=params.length; i 0) { + var firstParam = params[0]; + // Only bother with subscriptions if the first argument + // is a stream itself, and not a primitive. + if (firstParam && firstParam.isStream) { + var onDependentKeyNotify = function onDependentKeyNotify(stream) { + stream.value(); + lazyValue.notify(); + }; + for (i = 0; i < dependentKeys.length; i++) { + var childParam = firstParam.get(dependentKeys[i]); + childParam.value(); + childParam.subscribe(onDependentKeyNotify); + } + } + } } } - helper._rawFunction = fn; return helper; } - /** - Renders the unbound form of an otherwise bound helper function. - - @private - @method evaluateUnboundHelper - @param {Function} fn - @param {Object} context - @param {Array} normalizedProperties - @param {String} options - */ - function evaluateUnboundHelper(context, fn, normalizedProperties, options) { - var args = []; - var hash = options.hash; - var boundOptions = hash.boundOptions; - var types = slice.call(options.types, 1); - var loc, len, property, propertyType, boundOption; - - for (boundOption in boundOptions) { - if (!boundOptions.hasOwnProperty(boundOption)) { continue; } - hash[boundOption] = handlebarsGet(context, boundOptions[boundOption], options); - } - - for (loc = 0, len = normalizedProperties.length; loc < len; ++loc) { - property = normalizedProperties[loc]; - propertyType = types[loc]; - if (propertyType === "ID") { - args.push(handlebarsGet(property.root, property.path, options)); - } else { - args.push(property.path); - } - } - args.push(options); - return fn.apply(context, args); - } - - /** - Overrides Handlebars.template so that we can distinguish - user-created, top-level templates from inner contexts. - - @private - @method template - @for Ember.Handlebars - @param {String} spec - */ - function template(spec) { - var t = originalTemplate(spec); - t.isTop = true; - return t; - } - - __exports__.template = template;__exports__.normalizePath = normalizePath; __exports__.makeBoundHelper = makeBoundHelper; - __exports__.handlebarsGet = handlebarsGet; __exports__.handlebarsGetView = handlebarsGetView; - __exports__.evaluateUnboundHelper = evaluateUnboundHelper; + __exports__.handlebarsGet = handlebarsGet; }); -enifed("ember-handlebars/helpers/binding", - ["ember-metal/core","ember-handlebars-compiler","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-runtime/system/string","ember-metal/platform","ember-metal/is_none","ember-metal/enumerable_utils","ember-metal/array","ember-views/views/view","ember-metal/run_loop","ember-metal/observer","ember-metal/binding","ember-views/system/jquery","ember-handlebars/ext","ember-metal/keys","ember-metal/cache","ember-handlebars/views/handlebars_bound_view","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __dependency18__, __dependency19__, __exports__) { +enifed("ember-handlebars/helpers/bind_attr", + ["ember-metal/core","ember-handlebars-compiler","ember-metal/utils","ember-runtime/system/string","ember-metal/array","ember-views/views/view","ember-metal/keys","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) { "use strict"; /** @module ember @@ -7139,586 +6912,19 @@ enifed("ember-handlebars/helpers/binding", */ var Ember = __dependency1__["default"]; - // Ember.assert, Ember.warn, uuid - // var emberAssert = Ember.assert, Ember.warn = Ember.warn; - + // Ember.assert var EmberHandlebars = __dependency2__["default"]; - var get = __dependency3__.get; - var set = __dependency4__.set; - var apply = __dependency5__.apply; - var uuid = __dependency5__.uuid; - var fmt = __dependency6__.fmt; - var o_create = __dependency7__.create; - var isNone = __dependency8__["default"]; - var EnumerableUtils = __dependency9__["default"]; - var forEach = __dependency10__.forEach; - var View = __dependency11__["default"]; - var run = __dependency12__["default"]; - var removeObserver = __dependency13__.removeObserver; - var isGlobalPath = __dependency14__.isGlobalPath; - var emberBind = __dependency14__.bind; - var jQuery = __dependency15__["default"]; - var isArray = __dependency5__.isArray; - var handlebarsGetEscaped = __dependency16__.getEscaped; - var keys = __dependency17__["default"]; - var Cache = __dependency18__["default"]; - var _HandlebarsBoundView = __dependency19__._HandlebarsBoundView; - var SimpleHandlebarsView = __dependency19__.SimpleHandlebarsView; - - var normalizePath = __dependency16__.normalizePath; - var handlebarsGet = __dependency16__.handlebarsGet; - var getEscaped = __dependency16__.getEscaped; - - var guidFor = __dependency5__.guidFor; - var typeOf = __dependency5__.typeOf; + var uuid = __dependency3__.uuid; + var fmt = __dependency4__.fmt; + var typeOf = __dependency3__.typeOf; + var forEach = __dependency5__.forEach; + var View = __dependency6__["default"]; + var keys = __dependency7__["default"]; var helpers = EmberHandlebars.helpers; var SafeString = EmberHandlebars.SafeString; - function exists(value) { - return !isNone(value); - } - - var WithView = _HandlebarsBoundView.extend({ - init: function() { - var controller; - - apply(this, this._super, arguments); - - var keywords = this.templateData.keywords; - var keywordName = this.templateHash.keywordName; - var keywordPath = this.templateHash.keywordPath; - var controllerName = this.templateHash.controller; - var preserveContext = this.preserveContext; - - if (controllerName) { - var previousContext = this.previousContext; - controller = this.container.lookupFactory('controller:'+controllerName).create({ - parentController: previousContext, - target: previousContext - }); - - this._generatedController = controller; - - if (!preserveContext) { - this.set('controller', controller); - - this.valueNormalizerFunc = function(result) { - controller.set('model', result); - return controller; - }; - } else { - var controllerPath = jQuery.expando + guidFor(controller); - keywords[controllerPath] = controller; - emberBind(keywords, controllerPath + '.model', keywordPath); - keywordPath = controllerPath; - } - } - - if (preserveContext) { - emberBind(keywords, keywordName, keywordPath); - } - - }, - willDestroy: function() { - this._super(); - - if (this._generatedController) { - this._generatedController.destroy(); - } - } - }); - - // Binds a property into the DOM. This will create a hook in DOM that the - // KVO system will look for and update if the property changes. - function bind(property, options, preserveContext, shouldDisplay, valueNormalizer, childProperties) { - var data = options.data; - var fn = options.fn; - var inverse = options.inverse; - var view = data.view; - var normalized, observer, i; - - // we relied on the behavior of calling without - // context to mean this === window, but when running - // "use strict", it's possible for this to === undefined; - var currentContext = this || window; - - normalized = normalizePath(currentContext, property, data); - - if (data.insideGroup) { - observer = function() { - while (view._contextView) { - view = view._contextView; - } - run.once(view, 'rerender'); - }; - - var template, context; - var result = handlebarsGet(currentContext, property, options); - - result = valueNormalizer ? valueNormalizer(result) : result; - - context = preserveContext ? currentContext : result; - if (shouldDisplay(result)) { - template = fn; - } else if (inverse) { - template = inverse; - } - - template(context, { data: options.data }); - } else { - var viewClass = _HandlebarsBoundView; - var viewOptions = { - preserveContext: preserveContext, - shouldDisplayFunc: shouldDisplay, - valueNormalizerFunc: valueNormalizer, - displayTemplate: fn, - inverseTemplate: inverse, - path: property, - pathRoot: currentContext, - previousContext: currentContext, - isEscaped: !options.hash.unescaped, - templateData: options.data, - templateHash: options.hash, - helperName: options.helperName - }; - - if (options.isWithHelper) { - viewClass = WithView; - } - - // Create the view that will wrap the output of this template/property - // and add it to the nearest view's childViews array. - // See the documentation of Ember._HandlebarsBoundView for more. - var bindView = view.createChildView(viewClass, viewOptions); - - view.appendChild(bindView); - - observer = function() { - run.scheduleOnce('render', bindView, 'rerenderIfNeeded'); - }; - } - - // Observes the given property on the context and - // tells the Ember._HandlebarsBoundView to re-render. If property - // is an empty string, we are printing the current context - // object ({{this}}) so updating it is not our responsibility. - if (typeof this === 'object' && normalized.path !== '') { - view.registerObserver(normalized.root, normalized.path, observer); - if (childProperties) { - for (i=0; i{{user.name}} - -
    -
    {{user.role.label}}
    - {{user.role.id}} - -

    {{user.role.description}}

    -
    - ``` - - `{{with}}` can be our best friend in these cases, - instead of writing `user.role.*` over and over, we use `{{#with user.role}}`. - Now the context within the `{{#with}} .. {{/with}}` block is `user.role` so you can do the following: - - ```handlebars -
    {{user.name}}
    - -
    - {{#with user.role}} -
    {{label}}
    - {{id}} - -

    {{description}}

    - {{/with}} -
    - ``` - - ### `as` operator - - This operator aliases the scope to a new name. It's helpful for semantic clarity and to retain - default scope or to reference from another `{{with}}` block. - - ```handlebars - // posts might not be - {{#with user.posts as blogPosts}} -
    - There are {{blogPosts.length}} blog posts written by {{user.name}}. -
    - - {{#each post in blogPosts}} -
  • {{post.title}}
  • - {{/each}} - {{/with}} - ``` - - Without the `as` operator, it would be impossible to reference `user.name` in the example above. - - NOTE: The alias should not reuse a name from the bound property path. - For example: `{{#with foo.bar as foo}}` is not supported because it attempts to alias using - the first part of the property path, `foo`. Instead, use `{{#with foo.bar as baz}}`. - - ### `controller` option - - Adding `controller='something'` instructs the `{{with}}` helper to create and use an instance of - the specified controller with the new context as its content. - - This is very similar to using an `itemController` option with the `{{each}}` helper. - - ```handlebars - {{#with users.posts controller='userBlogPosts'}} - {{!- The current context is wrapped in our controller instance }} - {{/with}} - ``` - - In the above example, the template provided to the `{{with}}` block is now wrapped in the - `userBlogPost` controller, which provides a very elegant way to decorate the context with custom - functions/properties. - - @method with - @for Ember.Handlebars.helpers - @param {Function} context - @param {Hash} options - @return {String} HTML string - */ - function withHelper(context, options) { - var bindContext, preserveContext, controller; - var helperName = 'with'; - - if (arguments.length === 4) { - var keywordName, path, rootPath, normalized, contextPath; - - options = arguments[3]; - keywordName = arguments[2]; - path = arguments[0]; - - if (path) { - helperName += ' ' + path + ' as ' + keywordName; - } - - - var localizedOptions = o_create(options); - localizedOptions.data = o_create(options.data); - localizedOptions.data.keywords = o_create(options.data.keywords || {}); - - if (isGlobalPath(path)) { - contextPath = path; - } else { - normalized = normalizePath(this, path, options.data); - path = normalized.path; - rootPath = normalized.root; - - // This is a workaround for the fact that you cannot bind separate objects - // together. When we implement that functionality, we should use it here. - var contextKey = jQuery.expando + guidFor(rootPath); - localizedOptions.data.keywords[contextKey] = rootPath; - // if the path is '' ("this"), just bind directly to the current context - contextPath = path ? contextKey + '.' + path : contextKey; - } - - localizedOptions.hash.keywordName = keywordName; - localizedOptions.hash.keywordPath = contextPath; - - bindContext = this; - context = contextPath; - options = localizedOptions; - preserveContext = true; - } else { - - helperName += ' ' + context; - bindContext = options.contexts[0]; - preserveContext = false; - } - - options.helperName = helperName; - options.isWithHelper = true; - - return bind.call(bindContext, context, options, preserveContext, exists); - } - /** - See [boundIf](/api/classes/Ember.Handlebars.helpers.html#method_boundIf) - and [unboundIf](/api/classes/Ember.Handlebars.helpers.html#method_unboundIf) - - @method if - @for Ember.Handlebars.helpers - @param {Function} context - @param {Hash} options - @return {String} HTML string - */ - function ifHelper(context, options) { - - options.helperName = options.helperName || ('if ' + context); - - if (options.data.isUnbound) { - return helpers.unboundIf.call(options.contexts[0], context, options); - } else { - return helpers.boundIf.call(options.contexts[0], context, options); - } - } - - /** - @method unless - @for Ember.Handlebars.helpers - @param {Function} context - @param {Hash} options - @return {String} HTML string - */ - function unlessHelper(context, options) { - - var fn = options.fn; - var inverse = options.inverse; - var helperName = 'unless'; - - if (context) { - helperName += ' ' + context; - } - - options.fn = inverse; - options.inverse = fn; - - options.helperName = options.helperName || helperName; - - if (options.data.isUnbound) { - return helpers.unboundIf.call(options.contexts[0], context, options); - } else { - return helpers.boundIf.call(options.contexts[0], context, options); - } - } - /** `bind-attr` allows you to create a binding between DOM element attributes and Ember objects. For example: @@ -7874,43 +7080,22 @@ enifed("ember-handlebars/helpers/binding", // current value of the property as an attribute. forEach.call(attrKeys, function(attr) { var path = attrs[attr]; - var normalized; - normalized = normalizePath(ctx, path, options.data); - - var value = (path === 'this') ? normalized.root : handlebarsGet(ctx, path, options); + var lazyValue = view.getStream(path); + var value = lazyValue.value(); var type = typeOf(value); - var observer; - - observer = function observer() { - var result = handlebarsGet(ctx, path, options); + lazyValue.subscribe(view._wrapAsScheduled(function applyAttributeBindings() { + var result = lazyValue.value(); var elem = view.$("[data-bindattr-" + dataId + "='" + dataId + "']"); - // If we aren't able to find the element, it means the element - // to which we were bound has been removed from the view. - // In that case, we can assume the template has been re-rendered - // and we need to clean up the observer. - if (!elem || elem.length === 0) { - removeObserver(normalized.root, normalized.path, observer); - return; - } - + View.applyAttributeBindings(elem, attr, result); - }; - - // Add an observer to the view for when the property changes. - // When the observer fires, find the element using the - // unique data id and update the attribute to the new value. - // Note: don't add observer when path is 'this' or path - // is whole keyword e.g. {{#each x in list}} ... {{bind-attr attr="x"}} - if (path !== 'this' && !(normalized.isKeyword && normalized.path === '' )) { - view.registerObserver(normalized.root, normalized.path, observer); - } + })); // if this changes, also change the logic in ember-views/lib/views/view.js if ((type === 'string' || (type === 'number' && !isNaN(value)))) { @@ -7938,7 +7123,8 @@ enifed("ember-handlebars/helpers/binding", @return {String} HTML string */ function bindAttrHelperDeprecated() { - return helpers['bind-attr'].apply(this, arguments); + + return helpers['bind-attr'].apply(this, arguments); } /** @@ -7968,24 +7154,6 @@ enifed("ember-handlebars/helpers/binding", var ret = []; var newClass, value, elem; - // Helper method to retrieve the property from the context and - // determine which class string to return, based on whether it is - // a Boolean or not. - var classStringForPath = function(root, parsedPath, options) { - var val; - var path = parsedPath.path; - - if (path === 'this') { - val = root; - } else if (path === '') { - val = true; - } else { - val = handlebarsGet(root, path, options); - } - - return View._classStringForValue(path, val, parsedPath.className, parsedPath.falsyClassName); - }; - // For each property passed, loop through and setup // an observer. forEach.call(classBindings.split(' '), function(binding) { @@ -7994,31 +7162,25 @@ enifed("ember-handlebars/helpers/binding", // closes over this variable, so it knows which string to remove when // the property changes. var oldClass; - var observer; var parsedPath = View._parsePropertyPath(binding); var path = parsedPath.path; - var pathRoot = context; - var normalized; + var initialValue; - if (path !== '' && path !== 'this') { - normalized = normalizePath(context, path, options.data); + if (path === '') { + initialValue = true; + } else { + var lazyValue = view.getStream(path); + initialValue = lazyValue.value(); - pathRoot = normalized.root; - path = normalized.path; - } + // Set up an observer on the context. If the property changes, toggle the + // class name. + lazyValue.subscribe(view._wrapAsScheduled(function applyClassNameBindings() { + // Get the current value of the property + var value = lazyValue.value(); + newClass = classStringForParsedPath(parsedPath, value); + elem = bindAttrId ? view.$("[data-bindattr-" + bindAttrId + "='" + bindAttrId + "']") : view.$(); - // Set up an observer on the context. If the property changes, toggle the - // class name. - observer = function() { - // Get the current value of the property - newClass = classStringForPath(context, parsedPath, options); - elem = bindAttrId ? view.$("[data-bindattr-" + bindAttrId + "='" + bindAttrId + "']") : view.$(); - - // If we can't find the element anymore, a parent template has been - // re-rendered and we've been nuked. Remove the observer. - if (!elem || elem.length === 0) { - removeObserver(pathRoot, path, observer); - } else { + // If we had previously added a class to the element, remove it. if (oldClass) { elem.removeClass(oldClass); @@ -8032,16 +7194,12 @@ enifed("ember-handlebars/helpers/binding", } else { oldClass = null; } - } - }; - - if (path !== '' && path !== 'this') { - view.registerObserver(pathRoot, path, observer); + })); } // We've already setup the observer; now we just need to figure out the // correct behavior right now on the first pass through. - value = classStringForPath(context, parsedPath, options); + value = classStringForParsedPath(parsedPath, initialValue); if (value) { ret.push(value); @@ -8055,22 +7213,234 @@ enifed("ember-handlebars/helpers/binding", return ret; } - __exports__.bind = bind; - __exports__._triageMustacheHelper = _triageMustacheHelper; - __exports__.resolveHelper = resolveHelper; - __exports__.bindHelper = bindHelper; - __exports__.boundIfHelper = boundIfHelper; - __exports__.unboundIfHelper = unboundIfHelper; - __exports__.withHelper = withHelper; - __exports__.ifHelper = ifHelper; - __exports__.unlessHelper = unlessHelper; + function classStringForParsedPath(parsedPath, value) { + return View._classStringForValue(parsedPath.path, value, parsedPath.className, parsedPath.falsyClassName); + } + + __exports__["default"] = bindAttrHelper; + __exports__.bindAttrHelper = bindAttrHelper; __exports__.bindAttrHelperDeprecated = bindAttrHelperDeprecated; __exports__.bindClasses = bindClasses; }); +enifed("ember-handlebars/helpers/binding", + ["ember-metal/core","ember-handlebars-compiler","ember-metal/is_none","ember-metal/run_loop","ember-metal/cache","ember-metal/streams/simple","ember-handlebars/views/handlebars_bound_view","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) { + "use strict"; + /** + @module ember + @submodule ember-handlebars + */ + + var Ember = __dependency1__["default"]; + // Ember.assert + var EmberHandlebars = __dependency2__["default"]; + + var isNone = __dependency3__["default"]; + var run = __dependency4__["default"]; + var Cache = __dependency5__["default"]; + var SimpleStream = __dependency6__["default"]; + + var _HandlebarsBoundView = __dependency7__._HandlebarsBoundView; + var SimpleHandlebarsView = __dependency7__.SimpleHandlebarsView; + + var helpers = EmberHandlebars.helpers; + + function exists(value) { + return !isNone(value); + } + + // Binds a property into the DOM. This will create a hook in DOM that the + // KVO system will look for and update if the property changes. + function bind(property, options, preserveContext, shouldDisplay, valueNormalizer, childProperties, _viewClass) { + var data = options.data; + var view = data.view; + + // we relied on the behavior of calling without + // context to mean this === window, but when running + // "use strict", it's possible for this to === undefined; + var currentContext = this || window; + + var valueStream = view.getStream(property); + var lazyValue; + + if (childProperties) { + lazyValue = new SimpleStream(valueStream); + + var subscriber = function(childStream) { + childStream.value(); + lazyValue.notify(); + }; + + for (var i = 0; i < childProperties.length; i++) { + var childStream = valueStream.get(childProperties[i]); + childStream.value(); + childStream.subscribe(subscriber); + } + } else { + lazyValue = valueStream; + } + + // Set up observers for observable objects + var viewClass = _viewClass || _HandlebarsBoundView; + var viewOptions = { + preserveContext: preserveContext, + shouldDisplayFunc: shouldDisplay, + valueNormalizerFunc: valueNormalizer, + displayTemplate: options.fn, + inverseTemplate: options.inverse, + lazyValue: lazyValue, + previousContext: currentContext, + isEscaped: !options.hash.unescaped, + templateData: options.data, + templateHash: options.hash, + helperName: options.helperName + }; + + if (options.keywords) { + viewOptions._keywords = options.keywords; + } + + // Create the view that will wrap the output of this template/property + // and add it to the nearest view's childViews array. + // See the documentation of Ember._HandlebarsBoundView for more. + var bindView = view.createChildView(viewClass, viewOptions); + + view.appendChild(bindView); + + lazyValue.subscribe(view._wrapAsScheduled(function() { + run.scheduleOnce('render', bindView, 'rerenderIfNeeded'); + })); + } + + function simpleBind(currentContext, lazyValue, options) { + var data = options.data; + var view = data.view; + + var bindView = new SimpleHandlebarsView( + lazyValue, !options.hash.unescaped + ); + + bindView._parentView = view; + view.appendChild(bindView); + + lazyValue.subscribe(view._wrapAsScheduled(function() { + run.scheduleOnce('render', bindView, 'rerender'); + })); + } + + /** + '_triageMustache' is used internally select between a binding, helper, or component for + the given context. Until this point, it would be hard to determine if the + mustache is a property reference or a regular helper reference. This triage + helper resolves that. + + This would not be typically invoked by directly. + + @private + @method _triageMustache + @for Ember.Handlebars.helpers + @param {String} property Property/helperID to triage + @param {Object} options hash of template/rendering options + @return {String} HTML string + */ + function _triageMustacheHelper(property, options) { + + var helper = EmberHandlebars.resolveHelper(options.data.view.container, property); + if (helper) { + return helper.call(this, options); + } + + return helpers.bind.call(this, property, options); + } + + var ISNT_HELPER_CACHE = new Cache(1000, function(key) { + return key.indexOf('-') === -1; + }); + __exports__.ISNT_HELPER_CACHE = ISNT_HELPER_CACHE; + /** + Used to lookup/resolve handlebars helpers. The lookup order is: + + * Look for a registered helper + * If a dash exists in the name: + * Look for a helper registed in the container + * Use Ember.ComponentLookup to find an Ember.Component that resolves + to the given name + + @private + @method resolveHelper + @param {Container} container + @param {String} name the name of the helper to lookup + @return {Handlebars Helper} + */ + function resolveHelper(container, name) { + if (helpers[name]) { + return helpers[name]; + } + + if (!container || ISNT_HELPER_CACHE.get(name)) { + return; + } + + var helper = container.lookup('helper:' + name); + if (!helper) { + var componentLookup = container.lookup('component-lookup:main'); + + var Component = componentLookup.lookupFactory(name, container); + if (Component) { + helper = EmberHandlebars.makeViewHelper(Component); + container.register('helper:' + name, helper); + } + } + return helper; + } + + + /** + `bind` can be used to display a value, then update that value if it + changes. For example, if you wanted to print the `title` property of + `content`: + + ```handlebars + {{bind "content.title"}} + ``` + + This will return the `title` property as a string, then create a new observer + at the specified path. If it changes, it will update the value in DOM. Note + that if you need to support IE7 and IE8 you must modify the model objects + properties using `Ember.get()` and `Ember.set()` for this to work as it + relies on Ember's KVO system. For all other browsers this will be handled for + you automatically. + + @private + @method bind + @for Ember.Handlebars.helpers + @param {String} property Property to bind + @param {Function} fn Context to provide for rendering + @return {String} HTML string + */ + function bindHelper(property, options) { + + var context = (options.contexts && options.contexts.length) ? options.contexts[0] : this; + + if (!options.fn) { + var lazyValue = options.data.view.getStream(property); + return simpleBind(context, lazyValue, options); + } + + options.helperName = 'bind'; + + return bind.call(context, property, options, false, exists); + } + + __exports__.bind = bind; + __exports__._triageMustacheHelper = _triageMustacheHelper; + __exports__.resolveHelper = resolveHelper; + __exports__.bindHelper = bindHelper; + }); enifed("ember-handlebars/helpers/collection", - ["ember-metal/core","ember-metal/utils","ember-handlebars-compiler","ember-runtime/system/string","ember-metal/property_get","ember-handlebars/ext","ember-handlebars/helpers/view","ember-metal/computed","ember-views/views/collection_view","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __exports__) { + ["ember-metal/core","ember-handlebars-compiler","ember-metal/mixin","ember-runtime/system/string","ember-metal/property_get","ember-metal/streams/simple","ember-handlebars/ext","ember-handlebars/helpers/view","ember-views/views/view","ember-views/views/collection_view","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __exports__) { "use strict"; /** @module ember @@ -8079,23 +7449,21 @@ enifed("ember-handlebars/helpers/collection", var Ember = __dependency1__["default"]; // Ember.assert, Ember.deprecate - var inspect = __dependency2__.inspect; // var emberAssert = Ember.assert; // emberDeprecate = Ember.deprecate; - var EmberHandlebars = __dependency3__["default"]; - var helpers = EmberHandlebars.helpers; + var EmberHandlebars = __dependency2__["default"]; + var IS_BINDING = __dependency3__.IS_BINDING; var fmt = __dependency4__.fmt; var get = __dependency5__.get; - var handlebarsGet = __dependency6__.handlebarsGet; - var handlebarsGetView = __dependency6__.handlebarsGetView; - var ViewHelper = __dependency7__.ViewHelper; - var computed = __dependency8__.computed; - var CollectionView = __dependency9__["default"]; + var SimpleStream = __dependency6__["default"]; + var handlebarsGetView = __dependency7__.handlebarsGetView; + var ViewHelper = __dependency8__.ViewHelper; + var View = __dependency9__["default"]; + var CollectionView = __dependency10__["default"]; - var alias = computed.alias; /** `{{collection}}` is a `Ember.Handlebars` helper for adding instances of `Ember.CollectionView` to a template. See [Ember.CollectionView](/api/classes/Ember.CollectionView.html) @@ -8243,13 +7611,14 @@ enifed("ember-handlebars/helpers/collection", // Otherwise, just default to the standard class. var collectionClass; if (path) { - collectionClass = handlebarsGetView(this, path, container, options); + collectionClass = handlebarsGetView(this, path, container, options.data); } else { collectionClass = CollectionView; } var hash = options.hash; + var hashTypes = options.hashTypes; var itemHash = {}; var match; @@ -8258,28 +7627,44 @@ enifed("ember-handlebars/helpers/collection", var itemViewClass; if (hash.itemView) { - itemViewClass = handlebarsGetView(this, hash.itemView, container, options); + itemViewClass = hash.itemView; } else if (hash.itemViewClass) { - itemViewClass = handlebarsGetView(collectionPrototype, hash.itemViewClass, container, options); + if (hashTypes.itemViewClass === 'ID') { + var itemViewClassStream = view.getStream(hash.itemViewClass); + itemViewClass = itemViewClassStream.value(); + } else { + itemViewClass = hash.itemViewClass; + } } else { - itemViewClass = handlebarsGetView(collectionPrototype, collectionPrototype.itemViewClass, container, options); + itemViewClass = collectionPrototype.itemViewClass; + } + + if (typeof itemViewClass === 'string') { + itemViewClass = container.lookupFactory('view:'+itemViewClass); } delete hash.itemViewClass; delete hash.itemView; + delete hashTypes.itemViewClass; + delete hashTypes.itemView; // Go through options passed to the {{collection}} helper and extract options // that configure item views instead of the collection itself. for (var prop in hash) { + if (prop === 'itemController' || prop === 'itemClassBinding') { + continue; + } if (hash.hasOwnProperty(prop)) { match = prop.match(/^item(.)(.*)$/); + if (match) { + var childProp = match[1].toLowerCase() + match[2]; - if (match && prop !== 'itemController') { - // Convert itemShouldFoo -> shouldFoo - itemHash[match[1].toLowerCase() + match[2]] = hash[prop]; - // Delete from hash as this will end up getting passed to the - // {{view}} helper method. + if (hashTypes[prop] === 'ID' || IS_BINDING.test(prop)) { + itemHash[childProp] = view._getBindingForStream(hash[prop]); + } else { + itemHash[childProp] = hash[prop]; + } delete hash[prop]; } } @@ -8298,29 +7683,47 @@ enifed("ember-handlebars/helpers/collection", tagName: itemHash.tagName }); } else if (hash.emptyViewClass) { - emptyViewClass = handlebarsGetView(this, hash.emptyViewClass, container, options); + emptyViewClass = handlebarsGetView(this, hash.emptyViewClass, container, options.data); } if (emptyViewClass) { hash.emptyView = emptyViewClass; } if (hash.keyword) { - itemHash._context = this; + itemHash._contextBinding = '_parentView.context'; } else { - itemHash._context = alias('content'); + itemHash._contextBinding = 'content'; } var viewOptions = ViewHelper.propertiesFromHTMLOptions({ data: data, hash: itemHash }, this); - hash.itemViewClass = itemViewClass.extend(viewOptions); + + if (hash.itemClassBinding) { + var itemClassBindings = hash.itemClassBinding.split(' '); + + for (var i = 0; i < itemClassBindings.length; i++) { + var parsedPath = View._parsePropertyPath(itemClassBindings[i]); + if (parsedPath.path === '') { + parsedPath.stream = new SimpleStream(true); + } else { + parsedPath.stream = view.getStream(parsedPath.path); + } + itemClassBindings[i] = parsedPath; + } + + viewOptions.classNameBindings = itemClassBindings; + } + + hash.itemViewClass = itemViewClass; + hash._itemViewProps = viewOptions; options.helperName = options.helperName || 'collection'; - return helpers.view.call(this, collectionClass, options); + return EmberHandlebars.helpers.view.call(this, collectionClass, options); } __exports__["default"] = collectionHelper; }); enifed("ember-handlebars/helpers/debug", - ["ember-metal/core","ember-metal/utils","ember-metal/logger","ember-metal/property_get","ember-handlebars/ext","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) { + ["ember-metal/core","ember-metal/utils","ember-metal/logger","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __exports__) { "use strict"; /*jshint debug:true*/ @@ -8333,10 +7736,6 @@ enifed("ember-handlebars/helpers/debug", var inspect = __dependency2__.inspect; var Logger = __dependency3__["default"]; - var get = __dependency4__.get; - var normalizePath = __dependency5__.normalizePath; - var handlebarsGet = __dependency5__.handlebarsGet; - var a_slice = [].slice; /** @@ -8354,22 +7753,14 @@ enifed("ember-handlebars/helpers/debug", function logHelper() { var params = a_slice.call(arguments, 0, -1); var options = arguments[arguments.length - 1]; + var view = options.data.view; var logger = Logger.log; var values = []; - var allowPrimitives = true; for (var i = 0; i < params.length; i++) { - var type = options.types[i]; - - if (type === 'ID' || !allowPrimitives) { - var context = (options.contexts && options.contexts[i]) || this; - var normalized = normalizePath(context, params[i], options.data); - - if (normalized.path === 'this') { - values.push(normalized.root); - } else { - values.push(handlebarsGet(normalized.root, normalized.path, options)); - } + if (options.types[i] === 'ID') { + var stream = view.getStream(params[i]); + values.push(stream.value()); } else { values.push(params[i]); } @@ -8415,6 +7806,7 @@ enifed("ember-handlebars/helpers/debug", function debuggerHelper(options) { // These are helpful values you can inspect while debugging. + /* jshint unused: false */ var templateContext = this; var typeOfTemplateContext = inspect(templateContext); @@ -8425,8 +7817,8 @@ enifed("ember-handlebars/helpers/debug", __exports__.debuggerHelper = debuggerHelper; }); enifed("ember-handlebars/helpers/each", - ["ember-metal/core","ember-handlebars-compiler","ember-runtime/system/string","ember-metal/property_get","ember-metal/property_set","ember-views/views/collection_view","ember-metal/binding","ember-runtime/mixins/controller","ember-runtime/controllers/array_controller","ember-runtime/mixins/array","ember-runtime/copy","ember-metal/run_loop","ember-metal/events","ember-handlebars/ext","ember-metal/computed","ember-metal/observer","ember-handlebars/views/metamorph_view","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __exports__) { + ["ember-metal/core","ember-handlebars-compiler","ember-runtime/system/string","ember-metal/property_get","ember-metal/property_set","ember-views/views/collection_view","ember-metal/binding","ember-runtime/mixins/controller","ember-runtime/controllers/array_controller","ember-runtime/mixins/array","ember-metal/observer","ember-handlebars/views/metamorph_view","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __exports__) { "use strict"; /** @@ -8435,10 +7827,8 @@ enifed("ember-handlebars/helpers/each", */ var Ember = __dependency1__["default"]; // Ember.assert;, Ember.K - var K = Ember.K; var EmberHandlebars = __dependency2__["default"]; - var helpers = EmberHandlebars.helpers; var fmt = __dependency3__.fmt; var get = __dependency4__.get; @@ -8448,19 +7838,14 @@ enifed("ember-handlebars/helpers/each", var ControllerMixin = __dependency8__["default"]; var ArrayController = __dependency9__["default"]; var EmberArray = __dependency10__["default"]; - var copy = __dependency11__["default"]; - var run = __dependency12__["default"]; - var on = __dependency13__.on; - var handlebarsGet = __dependency14__.handlebarsGet; - var computed = __dependency15__.computed; - var addObserver = __dependency16__.addObserver; - var removeObserver = __dependency16__.removeObserver; - var addBeforeObserver = __dependency16__.addBeforeObserver; - var removeBeforeObserver = __dependency16__.removeBeforeObserver; + var addObserver = __dependency11__.addObserver; + var removeObserver = __dependency11__.removeObserver; + var addBeforeObserver = __dependency11__.addBeforeObserver; + var removeBeforeObserver = __dependency11__.removeBeforeObserver; - var _Metamorph = __dependency17__._Metamorph; - var _MetamorphView = __dependency17__._MetamorphView; + var _MetamorphView = __dependency12__["default"]; + var _Metamorph = __dependency12__._Metamorph; var EachView = CollectionView.extend(_Metamorph, { @@ -8513,22 +7898,11 @@ enifed("ember-handlebars/helpers/each", createChildView: function(view, attrs) { view = this._super(view, attrs); - // At the moment, if a container view subclass wants - // to insert keywords, it is responsible for cloning - // the keywords hash. This will be fixed momentarily. - var keyword = get(this, 'keyword'); var content = get(view, 'content'); + var keyword = get(this, 'keyword'); if (keyword) { - var data = get(view, 'templateData'); - - data = copy(data); - data.keywords = view.cloneKeywords(); - set(view, 'templateData', data); - - // In this case, we do not bind, because the `content` of - // a #each item cannot change. - data.keywords[keyword] = content; + view._keywords[keyword] = content; } // If {{#each}} is looping over an array of controllers, @@ -8553,133 +7927,17 @@ enifed("ember-handlebars/helpers/each", } }); - var GroupedEach = EmberHandlebars.GroupedEach = function(context, path, options) { - var self = this; - var normalized = EmberHandlebars.normalizePath(context, path, options.data); - - this.context = context; - this.path = path; - this.options = options; - this.template = options.fn; - this.containingView = options.data.view; - this.normalizedRoot = normalized.root; - this.normalizedPath = normalized.path; - this.content = this.lookupContent(); - - this.addContentObservers(); - this.addArrayObservers(); - - this.containingView.on('willClearRender', function() { - self.destroy(); - }); - }; - - GroupedEach.prototype = { - contentWillChange: function() { - this.removeArrayObservers(); - }, - - contentDidChange: function() { - this.content = this.lookupContent(); - this.addArrayObservers(); - this.rerenderContainingView(); - }, - - contentArrayWillChange: K, - - contentArrayDidChange: function() { - this.rerenderContainingView(); - }, - - lookupContent: function() { - return handlebarsGet(this.normalizedRoot, this.normalizedPath, this.options); - }, - - addArrayObservers: function() { - if (!this.content) { return; } - - this.content.addArrayObserver(this, { - willChange: 'contentArrayWillChange', - didChange: 'contentArrayDidChange' - }); - }, - - removeArrayObservers: function() { - if (!this.content) { return; } - - this.content.removeArrayObserver(this, { - willChange: 'contentArrayWillChange', - didChange: 'contentArrayDidChange' - }); - }, - - addContentObservers: function() { - addBeforeObserver(this.normalizedRoot, this.normalizedPath, this, this.contentWillChange); - addObserver(this.normalizedRoot, this.normalizedPath, this, this.contentDidChange); - }, - - removeContentObservers: function() { - removeBeforeObserver(this.normalizedRoot, this.normalizedPath, this.contentWillChange); - removeObserver(this.normalizedRoot, this.normalizedPath, this.contentDidChange); - }, - - render: function() { - if (!this.content) { return; } - - var content = this.content; - var contentLength = get(content, 'length'); - var options = this.options; - var data = options.data; - var template = this.template; - - data.insideEach = true; - for (var i = 0; i < contentLength; i++) { - var context = content.objectAt(i); - options.data.keywords[options.hash.keyword] = context; - template(context, { data: data }); - } - }, - - rerenderContainingView: function() { - var self = this; - run.scheduleOnce('render', this, function() { - // It's possible it's been destroyed after we enqueued a re-render call. - if (!self.destroyed) { - self.containingView.rerender(); - } - }); - }, - - destroy: function() { - this.removeContentObservers(); - if (this.content) { - this.removeArrayObservers(); - } - this.destroyed = true; - } - }; - /** The `{{#each}}` helper loops over elements in a collection. It is an extension of the base Handlebars `{{#each}}` helper. The default behavior of `{{#each}}` is to yield its inner block once for every - item in an array. Each yield will provide the item as the context of the block. + item in an array. ```javascript var developers = [{name: 'Yehuda'},{name: 'Tom'}, {name: 'Paul'}]; ``` - ```handlebars - {{#each developers}} - {{name}} - {{! `this` is each developer }} - {{/each}} - ``` - - `{{#each}}` supports an alternative syntax with element naming. This preserves - context of the yielded block: - ```handlebars {{#each person in developers}} {{person.name}} @@ -8695,8 +7953,8 @@ enifed("ember-handlebars/helpers/each", ``` ```handlebars - {{#each developerNames}} - {{this}} + {{#each name in developerNames}} + {{name}} {{/each}} ``` @@ -8722,8 +7980,8 @@ enifed("ember-handlebars/helpers/each", ```handlebars
      - {{#each developers itemViewClass="person"}} - {{name}} + {{#each developer in developers itemViewClass="person"}} + {{developer.name}} {{/each}}
    ``` @@ -8754,13 +8012,13 @@ enifed("ember-handlebars/helpers/each", ```javascript App.PersonView = Ember.View.extend({ tagName: 'li', - template: '{{name}}' + template: '{{developer.name}}' }); ``` ```handlebars
      - {{each developers itemViewClass="person"}} + {{each developer in developers itemViewClass="person"}}
    ``` @@ -8778,8 +8036,8 @@ enifed("ember-handlebars/helpers/each", ```handlebars
      - {{#each developers emptyViewClass="no-people"}} -
    • {{name}}
    • + {{#each developer in developers emptyViewClass="no-people"}} +
    • {{developer.name}}
    • {{/each}}
    ``` @@ -8810,47 +8068,6 @@ enifed("ember-handlebars/helpers/each", {{/each}} ``` - ### (Experimental) Grouped Each - - If a list's membership often changes, but properties of items in that - group rarely change, a significant improvement in template rendering - time can be achieved by using the experimental [group helper](https://github.com/emberjs/group-helper). - - ```handlebars - {{#group}} - {{#each people}} - {{firstName}} {{lastName}} - {{/each}} - {{/group}} - ``` - - When the membership of `people` changes, or when any property changes, the entire - `{{#group}}` block will be re-rendered. - - An `{{#each}}` inside the `{{#group}}` helper can opt-out of the special group - behavior by passing the `groupedRows` option. For example: - - ```handlebars - {{#group}} - {{#each dealers}} - {{! uses group's special behavior }} - {{firstName}} {{lastName}} - {{/each}} - - {{#each car in cars groupedRows=true}} - {{! does not use group's special behavior }} - {{car.make}} {{car.model}} {{car.color}} - {{/each}} - {{/group}} - ``` - - Any change to the `dealers` collection will cause the entire group to be re-rendered. - Changes to the `cars` collection will be re-rendered individually, as they are with - normal `{{#each}}` usage. - - `{{#group}}` is implemented with an `itemViewClass`, so specifying an `itemViewClass` - on an `{{#each}}` will also disable the special re-rendering behavior. - @method each @for Ember.Handlebars.helpers @param [name] {String} name for item (used with `in`) @@ -8859,53 +8076,186 @@ enifed("ember-handlebars/helpers/each", @param [options.itemViewClass] {String} a path to a view class used for each item @param [options.emptyViewClass] {String} a path to a view class used for each item @param [options.itemController] {String} name of a controller to be created for each item - @param [options.groupedRows] {boolean} enable normal item-by-item rendering when inside a `#group` helper */ - function eachHelper(path, options) { - var ctx; + function eachHelper(path) { + var options = arguments[arguments.length - 1]; var helperName = 'each'; + var keywordName; if (arguments.length === 4) { - var keywordName = arguments[0]; - - - options = arguments[3]; + keywordName = arguments[0]; path = arguments[2]; helperName += ' ' + keywordName + ' in ' + path; - if (path === '') { path = "this"; } - options.hash.keyword = keywordName; - } else if (arguments.length === 1) { - options = path; - path = 'this'; + path = ''; } else { helperName += ' ' + path; } + + options.hash.emptyViewClass = Ember._MetamorphView; options.hash.dataSourceBinding = path; - // Set up emptyView as a metamorph with no tag - //options.hash.emptyViewClass = Ember._MetamorphView; - - // can't rely on this default behavior when use strict - ctx = this || window; - + options.hashTypes.dataSourceBinding = 'STRING'; options.helperName = options.helperName || helperName; - if (options.data.insideGroup && !options.hash.groupedRows && !options.hash.itemViewClass) { - new GroupedEach(ctx, path, options).render(); - } else { - return helpers.collection.call(ctx, EmberHandlebars.EachView, options); - } + return EmberHandlebars.helpers.collection.call(this, EmberHandlebars.EachView, options); } __exports__.EachView = EachView; - __exports__.GroupedEach = GroupedEach; __exports__.eachHelper = eachHelper; }); +enifed("ember-handlebars/helpers/if_unless", + ["ember-metal/core","ember-handlebars-compiler","ember-handlebars/helpers/binding","ember-metal/property_get","ember-metal/utils","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) { + "use strict"; + /** + @module ember + @submodule ember-handlebars + */ + + var Ember = __dependency1__["default"]; + // Ember.assert + var EmberHandlebars = __dependency2__["default"]; + + var bind = __dependency3__.bind; + + var get = __dependency4__.get; + var isArray = __dependency5__.isArray; + + var helpers = EmberHandlebars.helpers; + + function shouldDisplayIfHelperContent(result) { + var truthy = result && get(result, 'isTruthy'); + if (typeof truthy === 'boolean') { return truthy; } + + if (isArray(result)) { + return get(result, 'length') !== 0; + } else { + return !!result; + } + } + + /** + Use the `boundIf` helper to create a conditional that re-evaluates + whenever the truthiness of the bound value changes. + + ```handlebars + {{#boundIf "content.shouldDisplayTitle"}} + {{content.title}} + {{/boundIf}} + ``` + + @private + @method boundIf + @for Ember.Handlebars.helpers + @param {String} property Property to bind + @param {Function} fn Context to provide for rendering + @return {String} HTML string + */ + function boundIfHelper(property, fn) { + var context = (fn.contexts && fn.contexts.length) ? fn.contexts[0] : this; + + fn.helperName = fn.helperName || 'boundIf'; + + return bind.call(context, property, fn, true, shouldDisplayIfHelperContent, shouldDisplayIfHelperContent, [ + 'isTruthy', + 'length' + ]); + } + + /** + @private + + Use the `unboundIf` helper to create a conditional that evaluates once. + + ```handlebars + {{#unboundIf "content.shouldDisplayTitle"}} + {{content.title}} + {{/unboundIf}} + ``` + + @method unboundIf + @for Ember.Handlebars.helpers + @param {String} property Property to bind + @param {Function} fn Context to provide for rendering + @return {String} HTML string + @since 1.4.0 + */ + function unboundIfHelper(property, fn) { + var context = (fn.contexts && fn.contexts.length) ? fn.contexts[0] : this; + var data = fn.data; + var view = data.view; + var template = fn.fn; + var inverse = fn.inverse; + + var propertyValue = view.getStream(property).value(); + + if (!shouldDisplayIfHelperContent(propertyValue)) { + template = inverse; + } + + template(context, { data: data }); + } + + /** + See [boundIf](/api/classes/Ember.Handlebars.helpers.html#method_boundIf) + and [unboundIf](/api/classes/Ember.Handlebars.helpers.html#method_unboundIf) + + @method if + @for Ember.Handlebars.helpers + @param {Function} context + @param {Hash} options + @return {String} HTML string + */ + function ifHelper(context, options) { + + options.helperName = options.helperName || ('if ' + context); + + if (options.data.isUnbound) { + return helpers.unboundIf.call(options.contexts[0], context, options); + } else { + return helpers.boundIf.call(options.contexts[0], context, options); + } + } + + /** + @method unless + @for Ember.Handlebars.helpers + @param {Function} context + @param {Hash} options + @return {String} HTML string + */ + function unlessHelper(context, options) { + + var fn = options.fn; + var inverse = options.inverse; + var helperName = 'unless'; + + if (context) { + helperName += ' ' + context; + } + + options.fn = inverse; + options.inverse = fn; + + options.helperName = options.helperName || helperName; + + if (options.data.isUnbound) { + return helpers.unboundIf.call(options.contexts[0], context, options); + } else { + return helpers.boundIf.call(options.contexts[0], context, options); + } + } + + __exports__.ifHelper = ifHelper; + __exports__.boundIfHelper = boundIfHelper; + __exports__.unboundIfHelper = unboundIfHelper; + __exports__.unlessHelper = unlessHelper; + }); enifed("ember-handlebars/helpers/loc", ["ember-runtime/system/string","exports"], function(__dependency1__, __exports__) { @@ -8952,16 +8302,15 @@ enifed("ember-handlebars/helpers/loc", __exports__["default"] = loc; }); enifed("ember-handlebars/helpers/partial", - ["ember-metal/core","ember-metal/is_none","ember-handlebars/ext","ember-handlebars/helpers/binding","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) { + ["ember-metal/core","ember-metal/is_none","ember-handlebars/helpers/binding","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; // Ember.assert // var emberAssert = Ember.assert; - var isNone = __dependency2__.isNone; - var handlebarsGet = __dependency3__.handlebarsGet; - var bind = __dependency4__.bind; + var isNone = __dependency2__["default"]; + var bind = __dependency3__.bind; /** @module ember @@ -9002,16 +8351,6 @@ enifed("ember-handlebars/helpers/partial", changes, the partial will be re-rendered using the new template name. - ## Setting the partial's context with `with` - - The `partial` helper can be used in conjunction with the `with` - helper to set a context that will be used by the partial: - - ```handlebars - {{#with currentUser}} - {{partial "user_info"}} - {{/with}} - ``` @method partial @for Ember.Handlebars.helpers @@ -9019,18 +8358,19 @@ enifed("ember-handlebars/helpers/partial", */ __exports__["default"] = function partialHelper(name, options) { + var view = options.data.view; var context = (options.contexts && options.contexts.length) ? options.contexts[0] : this; options.helperName = options.helperName || 'partial'; if (options.types[0] === "ID") { + var partialNameStream = view.getStream(name); // Helper was passed a property path; we need to // create a binding that will re-render whenever // this property changes. options.fn = function(context, fnOptions) { - var partialName = handlebarsGet(context, name, fnOptions); - renderPartial(context, partialName, fnOptions); + renderPartial(context, partialNameStream.value(), fnOptions); }; return bind.call(context, name, options, true, exists); @@ -9058,26 +8398,9 @@ enifed("ember-handlebars/helpers/partial", template = template || deprecatedTemplate; - template(context, { data: options.data }); - } - }); -enifed("ember-handlebars/helpers/shared", - ["ember-handlebars/ext","exports"], - function(__dependency1__, __exports__) { - "use strict"; - var handlebarsGet = __dependency1__.handlebarsGet; - - __exports__["default"] = function resolvePaths(options) { - var ret = []; - var contexts = options.contexts; - var roots = options.roots; - var data = options.data; - - for (var i=0, l=contexts.length; i 2) { - // Unbound helper call. + if (argsLength <= 2) { + return view.getStream(property).value(); + } else { options.data.isUnbound = true; - helper = resolveHelper(container, property) || helpers.helperMissing; - out = helper.apply(ctx, slice.call(arguments, 1)); - delete options.data.isUnbound; - return out; - } + options.types.shift(); - context = (fn.contexts && fn.contexts.length) ? fn.contexts[0] : ctx; - return handlebarsGet(context, property, fn); + var args = new Array(argsLength - 1); + for (var i = 1; i < argsLength; i++) { + args[i - 1] = arguments[i]; + } + + var helper = resolveHelper(container, property) || EmberHandlebars.helpers.helperMissing; + + // Attempt to exec the first field as a helper + options.name = arguments[0]; + + var result = helper.apply(this, args); + + delete options.data.isUnbound; + return result; + } } }); enifed("ember-handlebars/helpers/view", - ["ember-metal/core","ember-runtime/system/object","ember-metal/property_get","ember-metal/property_set","ember-metal/mixin","ember-views/system/jquery","ember-views/views/view","ember-metal/binding","ember-metal/keys","ember-handlebars/ext","ember-runtime/system/string","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __exports__) { + ["ember-metal/core","ember-runtime/system/object","ember-metal/property_get","ember-metal/keys","ember-metal/mixin","ember-views/streams/read","ember-views/views/view","ember-metal/streams/simple","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) { "use strict"; - /*globals Handlebars */ - /** @module ember @submodule ember-handlebars @@ -9182,53 +8506,58 @@ enifed("ember-handlebars/helpers/view", var EmberObject = __dependency2__["default"]; var get = __dependency3__.get; - var set = __dependency4__.set; + var keys = __dependency4__["default"]; var IS_BINDING = __dependency5__.IS_BINDING; - var jQuery = __dependency6__["default"]; + var readViewFactory = __dependency6__.readViewFactory; var View = __dependency7__["default"]; - var isGlobalPath = __dependency8__.isGlobalPath; - var keys = __dependency9__["default"]; - var normalizePath = __dependency10__.normalizePath; - var handlebarsGet = __dependency10__.handlebarsGet; - var handlebarsGetView = __dependency10__.handlebarsGetView; - var EmberString = __dependency11__["default"]; + var SimpleStream = __dependency8__["default"]; - - var LOWERCASE_A_Z = /^[a-z]/; - var VIEW_PREFIX = /^view\./; - - function makeBindings(thisContext, options) { + function makeBindings(options) { var hash = options.hash; - var hashType = options.hashTypes; + var hashTypes = options.hashTypes; + var view = options.data.view; for (var prop in hash) { - if (hashType[prop] === 'ID') { + var hashType = hashTypes[prop]; + var value = hash[prop]; - var value = hash[prop]; + if (IS_BINDING.test(prop)) { + // classBinding is processed separately + if (prop === 'classBinding') { + continue; + } - if (IS_BINDING.test(prop)) { - } else { - hash[prop + 'Binding'] = value; - hashType[prop + 'Binding'] = 'STRING'; + if (hashType === 'ID') { + hash[prop] = view._getBindingForStream(value); + } else if (typeof value === 'string') { + hash[prop] = view._getBindingForStream(value); + } + } else { + if (hashType === 'ID') { + if (prop === 'class') { + hash.classBinding = value; + } else { + hash[prop + 'Binding'] = view._getBindingForStream(value); + } delete hash[prop]; - delete hashType[prop]; + delete hashTypes[prop]; } } } - if (hash.hasOwnProperty('idBinding')) { + if (hash.idBinding) { // id can't be bound, so just perform one-time lookup. - hash.id = handlebarsGet(thisContext, hash.idBinding, options); - hashType.id = 'STRING'; + hash.id = hash.idBinding.value(); + hashTypes.id = 'STRING'; delete hash.idBinding; - delete hashType.idBinding; + delete hashTypes.idBinding; } } var ViewHelper = EmberObject.create({ propertiesFromHTMLOptions: function(options) { + var view = options.data.view; var hash = options.hash; - var data = options.data; var classes = hash['class']; var extensions = { @@ -9266,90 +8595,43 @@ enifed("ember-handlebars/helpers/view", // Set the proper context for all bindings passed to the helper. This applies to regular attribute bindings // as well as class name bindings. If the bindings are local, make them relative to the current context // instead of the view. - var path; + var hashKeys = keys(hash); for (var i = 0, l = hashKeys.length; i < l; i++) { - var prop = hashKeys[i]; - var isBinding = IS_BINDING.test(prop); + var prop = hashKeys[i]; if (prop !== 'classNameBindings') { extensions[prop] = hash[prop]; } - - // Test if the property ends in "Binding" - if (isBinding && typeof extensions[prop] === 'string') { - path = this.contextualizeBindingPath(hash[prop], data); - if (path) { - extensions[prop] = path; - } - } } - if (extensions.classNameBindings) { - // Evaluate the context of class name bindings: - for (var j = 0, k = extensions.classNameBindings.length; j < k; j++) { - var full = extensions.classNameBindings[j]; - - if (typeof full === 'string') { - // Contextualize the path of classNameBinding so this: - // - // classNameBinding="isGreen:green" - // - // is converted to this: - // - // classNameBinding="_parentView.context.isGreen:green" - var parsedPath = View._parsePropertyPath(full); - if (parsedPath.path !== '') { - path = this.contextualizeBindingPath(parsedPath.path, data); - if (path) { - extensions.classNameBindings[j] = path + parsedPath.classNames; - } - } + var classNameBindings = extensions.classNameBindings; + if (classNameBindings) { + for (var j = 0; j < classNameBindings.length; j++) { + var parsedPath = View._parsePropertyPath(classNameBindings[j]); + if (parsedPath.path === '') { + parsedPath.stream = new SimpleStream(true); + } else { + parsedPath.stream = view.getStream(parsedPath.path); } + classNameBindings[j] = parsedPath; } } return extensions; }, - // Transform bindings from the current context to a context that can be evaluated within the view. - // Returns null if the path shouldn't be changed. - // - // TODO: consider the addition of a prefix that would allow this method to return `path`. - contextualizeBindingPath: function(path, data) { - var normalized = normalizePath(null, path, data); - if (normalized.isKeyword) { - return 'templateData.keywords.' + path; - } else if (isGlobalPath(path)) { - return null; - } else if (path === 'this' || path === '') { - return '_parentView.context'; - } else { - return '_parentView.context.' + path; - } - }, - - helper: function(thisContext, path, options) { + helper: function(thisContext, newView, options) { var data = options.data; var fn = options.fn; - var newView; - var newViewProto; - makeBindings(thisContext, options); - - var container = this.container || (data && data.view && data.view.container); - newView = handlebarsGetView(thisContext, path, container, options); - - if (View.detectInstance(newView)) { - newViewProto = newView; - } else { - newViewProto = newView.proto(); - } + makeBindings(options); var viewOptions = this.propertiesFromHTMLOptions(options, thisContext); var currentView = data.view; viewOptions.templateData = data; + var newViewProto = newView.proto(); if (fn) { viewOptions.template = fn; @@ -9368,7 +8650,7 @@ enifed("ember-handlebars/helpers/view", var data = options.data; var fn = options.fn; - makeBindings(thisContext, options); + makeBindings(options); var viewOptions = this.propertiesFromHTMLOptions(options, thisContext); @@ -9381,7 +8663,8 @@ enifed("ember-handlebars/helpers/view", // We only want to override the `_context` computed property if there is // no specified controller. See View#_context for more information. - if (!newView.controller && !newView.controllerBinding && !viewOptions.controller && !viewOptions.controllerBinding) { + if (!newView.controller && !newView.controllerBinding && + !viewOptions.controller && !viewOptions.controllerBinding) { viewOptions._context = thisContext; } @@ -9567,26 +8850,191 @@ enifed("ember-handlebars/helpers/view", @param {Hash} options @return {String} HTML string */ - function viewHelper(path, options) { + function viewHelper(path) { + var options = arguments[arguments.length - 1]; + var types = options.types; + var view = options.data.view; + var container = view.container || view._keywords.view.value().container; + var viewClass; + // If no path is provided, treat path param as options // and get an instance of the registered `view:toplevel` - if (path && path.data && path.data.isRenderData) { - options = path; - if (options.data && options.data.view && options.data.view.container) { - path = options.data.view.container.lookupFactory('view:toplevel'); + if (arguments.length === 1) { + if (container) { + viewClass = container.lookupFactory('view:toplevel'); } else { - path = View; + viewClass = View; } + } else { + var pathStream; + if (typeof path === 'string' && types[0] === 'ID') { + pathStream = view.getStream(path); + } else { + pathStream = path; + } + + viewClass = readViewFactory(pathStream, container); } options.helperName = options.helperName || 'view'; - return ViewHelper.helper(this, path, options); + return ViewHelper.helper(this, viewClass, options); } __exports__.viewHelper = viewHelper; }); +enifed("ember-handlebars/helpers/with", + ["ember-metal/core","ember-metal/property_set","ember-metal/utils","ember-metal/platform","ember-metal/is_none","ember-handlebars/helpers/binding","ember-handlebars/views/handlebars_bound_view","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) { + "use strict"; + /** + @module ember + @submodule ember-handlebars + */ + + var Ember = __dependency1__["default"]; + // Ember.assert + + var set = __dependency2__.set; + var apply = __dependency3__.apply; + var o_create = __dependency4__.create; + var isNone = __dependency5__["default"]; + var bind = __dependency6__.bind; + var _HandlebarsBoundView = __dependency7__._HandlebarsBoundView; + + function exists(value) { + return !isNone(value); + } + + var WithView = _HandlebarsBoundView.extend({ + init: function() { + apply(this, this._super, arguments); + + var keywordName = this.templateHash.keywordName; + var controllerName = this.templateHash.controller; + + if (controllerName) { + var previousContext = this.previousContext; + var controller = this.container.lookupFactory('controller:'+controllerName).create({ + parentController: previousContext, + target: previousContext + }); + + this._generatedController = controller; + + if (this.preserveContext) { + this._keywords[keywordName] = controller; + this.lazyValue.subscribe(function(modelStream) { + set(controller, 'model', modelStream.value()); + }); + } else { + set(this, 'controller', controller); + this.valueNormalizerFunc = function(result) { + controller.set('model', result); + return controller; + }; + } + + set(controller, 'model', this.lazyValue.value()); + } + }, + + willDestroy: function() { + this._super(); + + if (this._generatedController) { + this._generatedController.destroy(); + } + } + }); + + /** + Use the `{{with}}` helper when you want to aliases the to a new name. It's helpful + for semantic clarity and to retain default scope or to reference from another + `{{with}}` block. + + ```handlebars + // posts might not be + {{#with user.posts as blogPosts}} +
    + There are {{blogPosts.length}} blog posts written by {{user.name}}. +
    + + {{#each post in blogPosts}} +
  • {{post.title}}
  • + {{/each}} + {{/with}} + ``` + + Without the `as` operator, it would be impossible to reference `user.name` in the example above. + + NOTE: The alias should not reuse a name from the bound property path. + For example: `{{#with foo.bar as foo}}` is not supported because it attempts to alias using + the first part of the property path, `foo`. Instead, use `{{#with foo.bar as baz}}`. + + ### `controller` option + + Adding `controller='something'` instructs the `{{with}}` helper to create and use an instance of + the specified controller wrapping the aliased keyword. + + This is very similar to using an `itemController` option with the `{{each}}` helper. + + ```handlebars + {{#with users.posts as posts controller='userBlogPosts'}} + {{!- `posts` is wrapped in our controller instance }} + {{/with}} + ``` + + In the above example, the `posts` keyword is now wrapped in the `userBlogPost` controller, + which provides an elegant way to decorate the context with custom + functions/properties. + + @method with + @for Ember.Handlebars.helpers + @param {Function} context + @param {Hash} options + @return {String} HTML string + */ + __exports__["default"] = function withHelper(contextPath) { + var options = arguments[arguments.length - 1]; + var view = options.data.view; + var bindContext, preserveContext; + var helperName = 'with'; + + if (arguments.length === 4) { + + var keywordName = arguments[2]; + + if (contextPath) { + helperName += ' ' + contextPath + ' as ' + keywordName; + } + + + var localizedOptions = o_create(options); + localizedOptions.data = o_create(options.data); + + localizedOptions.keywords = {}; + localizedOptions.keywords[keywordName] = view.getStream(contextPath); + + localizedOptions.hash.keywordName = keywordName; + + bindContext = this; + options = localizedOptions; + preserveContext = true; + } else { + + + helperName += ' ' + contextPath; + bindContext = options.contexts[0]; + preserveContext = false; + } + + options.helperName = helperName; + + return bind.call(bindContext, contextPath, options, preserveContext, exists, undefined, undefined, WithView); + } + }); enifed("ember-handlebars/helpers/yield", ["ember-metal/core","ember-metal/property_get","exports"], function(__dependency1__, __dependency2__, __exports__) { @@ -9818,6 +9266,10 @@ enifed("ember-handlebars/string", @return {Handlebars.SafeString} a string that will not be html escaped by Handlebars */ function htmlSafe(str) { + if (str === null || str === undefined) { + return ""; + } + if (typeof str !== 'string') { str = ''+str; } @@ -9848,10 +9300,9 @@ enifed("ember-handlebars/string", __exports__["default"] = htmlSafe; }); enifed("ember-handlebars/views/handlebars_bound_view", - ["ember-handlebars-compiler","ember-metal/core","ember-metal/error","ember-metal/property_get","ember-metal/property_set","ember-metal/merge","ember-metal/run_loop","ember-views/views/view","ember-handlebars/string","ember-views/views/states","ember-handlebars/views/metamorph_view","ember-handlebars/ext","ember-metal/utils","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __exports__) { + ["ember-handlebars-compiler","ember-metal/core","ember-metal/error","ember-metal/property_get","ember-metal/property_set","ember-metal/merge","ember-metal/run_loop","ember-handlebars/string","ember-views/views/states","ember-handlebars/views/metamorph_view","ember-metal/utils","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __exports__) { "use strict"; - /*globals Handlebars, Metamorph:true */ /*jshint newcap:false*/ @@ -9862,7 +9313,6 @@ enifed("ember-handlebars/views/handlebars_bound_view", var EmberHandlebars = __dependency1__["default"]; // EmberHandlebars.SafeString; - var SafeString = EmberHandlebars.SafeString; var Ember = __dependency2__["default"]; // Ember.K @@ -9873,21 +9323,16 @@ enifed("ember-handlebars/views/handlebars_bound_view", var set = __dependency5__.set; var merge = __dependency6__["default"]; var run = __dependency7__["default"]; - var View = __dependency8__["default"]; - var htmlSafe = __dependency9__["default"]; - var cloneStates = __dependency10__.cloneStates; - var states = __dependency10__.states; - var viewStates = states; + var htmlSafe = __dependency8__["default"]; + var cloneStates = __dependency9__.cloneStates; + var viewStates = __dependency9__.states; - var _MetamorphView = __dependency11__["default"]; - var handlebarsGet = __dependency12__.handlebarsGet; - var uuid = __dependency13__.uuid; + var _MetamorphView = __dependency10__["default"]; + var uuid = __dependency11__.uuid; - function SimpleHandlebarsView(path, pathRoot, isEscaped, templateData) { - this.path = path; - this.pathRoot = pathRoot; + function SimpleHandlebarsView(lazyValue, isEscaped) { + this.lazyValue = lazyValue; this.isEscaped = isEscaped; - this.templateData = templateData; this[Ember.GUID_KEY] = uuid(); this._lastNormalizedValue = undefined; this.state = 'preRender'; @@ -9918,23 +9363,11 @@ enifed("ember-handlebars/views/handlebars_bound_view", propertyDidChange: K, normalizedValue: function() { - var path = this.path; - var pathRoot = this.pathRoot; - var escape = this.isEscaped; - var result, templateData; + var result = this.lazyValue.value(); - // Use the pathRoot as the result if no path is provided. This - // happens if the path is `this`, which gets normalized into - // a `pathRoot` of the current Handlebars context and a path - // of `''`. - if (path === '') { - result = pathRoot; - } else { - templateData = this.templateData; - result = handlebarsGet(pathRoot, path, { data: templateData }); - } - - if (!escape && !(result instanceof SafeString)) { + if (result === null || result === undefined) { + result = ""; + } else if (!this.isEscaped && !(result instanceof EmberHandlebars.SafeString)) { result = htmlSafe(result); } @@ -9965,7 +9398,7 @@ enifed("ember-handlebars/views/handlebars_bound_view", update: function () { this.updateId = null; var value = this.normalizedValue(); - // doesn't diff SafeString instances + // doesn't diff EmberHandlebars.SafeString instances if (value !== this._lastNormalizedValue) { this._lastNormalizedValue = value; this._morph.update(value); @@ -9977,7 +9410,7 @@ enifed("ember-handlebars/views/handlebars_bound_view", } }; - states = cloneStates(viewStates); + var states = cloneStates(viewStates); merge(states._default, { rerenderIfNeeded: K @@ -10065,49 +9498,12 @@ enifed("ember-handlebars/views/handlebars_bound_view", */ inverseTemplate: null, - - /** - The path to look up on `pathRoot` that is passed to - `shouldDisplayFunc` to determine which template to render. - - In addition, if `preserveContext` is `false,` the object at this path will - be passed to the template when rendering. - - @property path - @type String - @default null - */ - path: null, - - /** - The object from which the `path` will be looked up. Sometimes this is the - same as the `previousContext`, but in cases where this view has been - generated for paths that start with a keyword such as `view` or - `controller`, the path root will be that resolved object. - - @property pathRoot - @type Object - */ - pathRoot: null, + lazyValue: null, normalizedValue: function() { - var path = get(this, 'path'); - var pathRoot = get(this, 'pathRoot'); + var value = this.lazyValue.value(); var valueNormalizer = get(this, 'valueNormalizerFunc'); - var result, templateData; - - // Use the pathRoot as the result if no path is provided. This - // happens if the path is `this`, which gets normalized into - // a `pathRoot` of the current Handlebars context and a path - // of `''`. - if (path === '') { - result = pathRoot; - } else { - templateData = get(this, 'templateData'); - result = handlebarsGet(pathRoot, path, { data: templateData }); - } - - return valueNormalizer ? valueNormalizer(result) : result; + return valueNormalizer ? valueNormalizer(value) : value; }, rerenderIfNeeded: function() { @@ -10166,7 +9562,7 @@ enifed("ember-handlebars/views/handlebars_bound_view", // expression to the render context and return. if (result === null || result === undefined) { result = ""; - } else if (!(result instanceof SafeString)) { + } else if (!(result instanceof EmberHandlebars.SafeString)) { result = String(result); } @@ -10195,11 +9591,9 @@ enifed("ember-handlebars/views/handlebars_bound_view", __exports__.SimpleHandlebarsView = SimpleHandlebarsView; }); enifed("ember-handlebars/views/metamorph_view", - ["ember-metal/core","ember-views/views/core_view","ember-views/views/view","ember-metal/mixin","ember-metal/run_loop","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) { + ["ember-metal/core","ember-views/views/core_view","ember-views/views/view","ember-metal/mixin","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) { "use strict"; - /* global Metamorph:true */ - /*jshint newcap:false*/ var Ember = __dependency1__["default"]; // Ember.deprecate @@ -10207,17 +9601,12 @@ enifed("ember-handlebars/views/metamorph_view", var CoreView = __dependency2__["default"]; var View = __dependency3__["default"]; var Mixin = __dependency4__.Mixin; - var run = __dependency5__["default"]; /** @module ember @submodule ember-handlebars */ - function notifyMutationListeners() { - run.once(View, 'notifyMutationListeners'); - } - // The `morph` and `outerHTML` properties are internal only // and not observable. @@ -10244,8 +9633,8 @@ enifed("ember-handlebars/views/metamorph_view", @uses Ember._Metamorph @private */ - var _MetamorphView = View.extend(_Metamorph); - __exports__._MetamorphView = _MetamorphView; + __exports__["default"] = View.extend(_Metamorph); + /** @class _SimpleMetamorphView @namespace Ember @@ -10254,7 +9643,7 @@ enifed("ember-handlebars/views/metamorph_view", @private */ var _SimpleMetamorphView = CoreView.extend(_Metamorph); - __exports__._SimpleMetamorphView = _SimpleMetamorphView;__exports__["default"] = View.extend(_Metamorph); + __exports__._SimpleMetamorphView = _SimpleMetamorphView; }); enifed("ember-metal-views", ["ember-metal-views/renderer","exports"], @@ -10305,7 +9694,7 @@ enifed("ember-metal-views/renderer", var level = 0; var view = _view; - var children, i, l, child; + var children, i, child; while (length) { elements[level] = element; if (!view._morph) { @@ -10378,7 +9767,7 @@ enifed("ember-metal-views/renderer", this.insertElement(view, _parentView, element, insertAt); - for (i=total-1;i>=0;i--) { + for (i=total-1; i>=0; i--) { if (willInsert) { views[i]._elementInserted = true; this.didInsertElement(views[i]); @@ -10404,7 +9793,7 @@ enifed("ember-metal-views/renderer", } view._morph = morph; var viewId = this.uuid(view); - this._inserts[viewId] = this.scheduleRender(this, function() { + this._inserts[viewId] = this.scheduleRender(this, function scheduledRenderTree() { this._inserts[viewId] = null; this.renderTree(view); }); @@ -10437,8 +9826,7 @@ enifed("ember-metal-views/renderer", var removeQueue = []; var destroyQueue = []; var morph = _view._morph; - var idx, len, view, staticChildren, queue, - childViews, i, l, parentView; + var idx, len, view, queue, childViews, i, l; removeQueue.push(_view); @@ -10568,30 +9956,30 @@ enifed("ember-metal", var Ember = __dependency1__["default"]; var merge = __dependency2__["default"]; var instrument = __dependency3__.instrument; + var reset = __dependency3__.reset; var subscribe = __dependency3__.subscribe; var unsubscribe = __dependency3__.unsubscribe; - var reset = __dependency3__.reset; - var generateGuid = __dependency4__.generateGuid; - var GUID_KEY = __dependency4__.GUID_KEY; - var guidFor = __dependency4__.guidFor; - var META_DESC = __dependency4__.META_DESC; var EMPTY_META = __dependency4__.EMPTY_META; - var meta = __dependency4__.meta; - var getMeta = __dependency4__.getMeta; - var setMeta = __dependency4__.setMeta; - var metaPath = __dependency4__.metaPath; - var inspect = __dependency4__.inspect; - var typeOf = __dependency4__.typeOf; - var tryCatchFinally = __dependency4__.tryCatchFinally; - var isArray = __dependency4__.isArray; - var makeArray = __dependency4__.makeArray; - var canInvoke = __dependency4__.canInvoke; - var tryInvoke = __dependency4__.tryInvoke; - var tryFinally = __dependency4__.tryFinally; - var wrap = __dependency4__.wrap; + var GUID_KEY = __dependency4__.GUID_KEY; + var META_DESC = __dependency4__.META_DESC; var apply = __dependency4__.apply; var applyStr = __dependency4__.applyStr; + var canInvoke = __dependency4__.canInvoke; + var generateGuid = __dependency4__.generateGuid; + var getMeta = __dependency4__.getMeta; + var guidFor = __dependency4__.guidFor; + var inspect = __dependency4__.inspect; + var isArray = __dependency4__.isArray; + var makeArray = __dependency4__.makeArray; + var meta = __dependency4__.meta; + var metaPath = __dependency4__.metaPath; + var setMeta = __dependency4__.setMeta; + var tryCatchFinally = __dependency4__.tryCatchFinally; + var tryFinally = __dependency4__.tryFinally; + var tryInvoke = __dependency4__.tryInvoke; + var typeOf = __dependency4__.typeOf; var uuid = __dependency4__.uuid; + var wrap = __dependency4__.wrap; var EmberError = __dependency5__["default"]; var EnumerableUtils = __dependency6__["default"]; var Cache = __dependency7__["default"]; @@ -10603,55 +9991,55 @@ enifed("ember-metal", var map = __dependency9__.map; var Logger = __dependency10__["default"]; + var _getPath = __dependency11__._getPath; var get = __dependency11__.get; var getWithDefault = __dependency11__.getWithDefault; var normalizeTuple = __dependency11__.normalizeTuple; - var _getPath = __dependency11__._getPath; - var on = __dependency12__.on; var addListener = __dependency12__.addListener; + var hasListeners = __dependency12__.hasListeners; + var listenersDiff = __dependency12__.listenersDiff; + var listenersFor = __dependency12__.listenersFor; + var listenersUnion = __dependency12__.listenersUnion; + var on = __dependency12__.on; var removeListener = __dependency12__.removeListener; + var sendEvent = __dependency12__.sendEvent; 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 ObserverSet = __dependency13__["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 endPropertyChanges = __dependency14__.endPropertyChanges; + var overrideChains = __dependency14__.overrideChains; + var propertyDidChange = __dependency14__.propertyDidChange; + var propertyWillChange = __dependency14__.propertyWillChange; var Descriptor = __dependency15__.Descriptor; var defineProperty = __dependency15__.defineProperty; var set = __dependency16__.set; var trySet = __dependency16__.trySet; - var OrderedSet = __dependency17__.OrderedSet; var Map = __dependency17__.Map; var MapWithDefault = __dependency17__.MapWithDefault; + var OrderedSet = __dependency17__.OrderedSet; 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 flushPendingChains = __dependency21__.flushPendingChains; + var removeChainWatcher = __dependency21__.removeChainWatcher; 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 isWatching = __dependency23__.isWatching; + var rewatch = __dependency23__.rewatch; + var unwatch = __dependency23__.unwatch; + var watch = __dependency23__.watch; var expandProperties = __dependency24__["default"]; var ComputedProperty = __dependency25__.ComputedProperty; var computed = __dependency25__.computed; @@ -10659,34 +10047,32 @@ enifed("ember-metal", // side effect of defining the computed.* macros - 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 _suspendObserver = __dependency27__._suspendObserver; var _suspendObservers = __dependency27__._suspendObservers; + var addBeforeObserver = __dependency27__.addBeforeObserver; + var addObserver = __dependency27__.addObserver; var beforeObserversFor = __dependency27__.beforeObserversFor; + var observersFor = __dependency27__.observersFor; var removeBeforeObserver = __dependency27__.removeBeforeObserver; + var removeObserver = __dependency27__.removeObserver; 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 immediateObserver = __dependency28__.immediateObserver; + var mixin = __dependency28__.mixin; + var observer = __dependency28__.observer; + var required = __dependency28__.required; var Binding = __dependency29__.Binding; - var isGlobalPath = __dependency29__.isGlobalPath; var bind = __dependency29__.bind; + var isGlobalPath = __dependency29__.isGlobalPath; 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 isNone = __dependency32__["default"]; + var isEmpty = __dependency33__["default"]; var isBlank = __dependency34__["default"]; var isPresent = __dependency35__["default"]; var keys = __dependency36__["default"]; @@ -10839,11 +10225,7 @@ enifed("ember-metal", Ember.libraries.registerCoreLibrary('Ember', Ember.VERSION); Ember.isNone = isNone; - Ember.none = none; - Ember.isEmpty = isEmpty; - Ember.empty = empty; - Ember.isBlank = isBlank; @@ -10884,26 +10266,28 @@ enifed("ember-metal", __exports__["default"] = Ember; }); enifed("ember-metal/alias", - ["ember-metal/property_get","ember-metal/property_set","ember-metal/error","ember-metal/properties","ember-metal/computed","ember-metal/platform","ember-metal/utils","ember-metal/dependent_keys","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) { + ["ember-metal/property_get","ember-metal/property_set","ember-metal/core","ember-metal/error","ember-metal/properties","ember-metal/computed","ember-metal/platform","ember-metal/utils","ember-metal/dependent_keys","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __exports__) { "use strict"; var get = __dependency1__.get; var set = __dependency2__.set; - var EmberError = __dependency3__["default"]; - var Descriptor = __dependency4__.Descriptor; - var defineProperty = __dependency4__.defineProperty; - var ComputedProperty = __dependency5__.ComputedProperty; - var create = __dependency6__.create; - var meta = __dependency7__.meta; - var inspect = __dependency7__.inspect; - var addDependentKeys = __dependency8__.addDependentKeys; - var removeDependentKeys = __dependency8__.removeDependentKeys; + var Ember = __dependency3__["default"]; + // Ember.assert + var EmberError = __dependency4__["default"]; + var Descriptor = __dependency5__.Descriptor; + var defineProperty = __dependency5__.defineProperty; + var ComputedProperty = __dependency6__.ComputedProperty; + var create = __dependency7__.create; + var meta = __dependency8__.meta; + var inspect = __dependency8__.inspect; + var addDependentKeys = __dependency9__.addDependentKeys; + var removeDependentKeys = __dependency9__.removeDependentKeys; - function alias(altKey) { + __exports__["default"] = function alias(altKey) { return new AliasedProperty(altKey); } - __exports__.alias = alias;function AliasedProperty(altKey) { + function AliasedProperty(altKey) { this.altKey = altKey; this._dependentKeys = [ altKey ]; } @@ -10927,7 +10311,7 @@ enifed("ember-metal/alias", }; AliasedProperty.prototype.setup = function(obj, keyName) { - var m = meta(obj); + var m = meta(obj); if (m.watching[keyName]) { addDependentKeys(this, obj, keyName, m); } @@ -11101,7 +10485,6 @@ enifed("ember-metal/binding", var Ember = __dependency1__["default"]; // Ember.Logger, Ember.LOG_BINDINGS, assert var get = __dependency2__.get; - var set = __dependency3__.set; var trySet = __dependency3__.trySet; var guidFor = __dependency4__.guidFor; var addObserver = __dependency5__.addObserver; @@ -11263,7 +10646,9 @@ enifed("ember-metal/binding", addObserver(obj, fromPath, this, this.fromDidChange); // if the binding is a two-way binding, also set up an observer on the target - if (!this._oneWay) { addObserver(obj, toPath, this, this.toDidChange); } + if (!this._oneWay) { + addObserver(obj, toPath, this, this.toDidChange); + } this._readyToSync = true; @@ -11287,7 +10672,9 @@ enifed("ember-metal/binding", removeObserver(obj, this._from, this, this.fromDidChange); // if the binding is two-way, remove the observer from the target as well - if (twoWay) { removeObserver(obj, this._to, this, this.toDidChange); } + if (twoWay) { + removeObserver(obj, this._to, this, this.toDidChange); + } this._readyToSync = false; // disable scheduled syncs... return this; @@ -11601,10 +10988,7 @@ enifed("ember-metal/cache", this.func = func; } - var FALSE = function() { }; - var ZERO = function() { }; var UNDEFINED = function() { }; - var NULL = function() { }; Cache.prototype = { set: function(key, value) { @@ -11653,12 +11037,11 @@ enifed("ember-metal/chains", // warn, assert, etc; var get = __dependency2__.get; var normalizeTuple = __dependency2__.normalizeTuple; - var meta = __dependency3__.meta; + var metaFor = __dependency3__.meta; var forEach = __dependency4__.forEach; var watchKey = __dependency5__.watchKey; var unwatchKey = __dependency5__.unwatchKey; - var metaFor = meta; var warn = Ember.warn; var FIRST_KEY = /^([^\.]+)/; @@ -11677,9 +11060,12 @@ enifed("ember-metal/chains", var queue = pendingQueue; pendingQueue = []; - forEach.call(queue, function(q) { q[0].add(q[1]); }); + forEach.call(queue, function(q) { + q[0].add(q[1]); + }); - warn('Watching an undefined global, Ember expects watched globals to be setup by the time the run loop is flushed, check for typos', pendingQueue.length === 0); + warn('Watching an undefined global, Ember expects watched globals to be' + + ' setup by the time the run loop is flushed, check for typos', pendingQueue.length === 0); } __exports__.flushPendingChains = flushPendingChains;function addChainWatcher(obj, keyName, node) { @@ -11692,7 +11078,9 @@ enifed("ember-metal/chains", nodes = m.chainWatchers = {}; } - if (!nodes[keyName]) { nodes[keyName] = []; } + if (!nodes[keyName]) { + nodes[keyName] = []; + } nodes[keyName].push(node); watchKey(obj, keyName, m); } @@ -11736,7 +11124,9 @@ enifed("ember-metal/chains", this._paths = {}; if (this._watching) { this._object = parent.value(); - if (this._object) { addChainWatcher(this._object, this._key, this); } + if (this._object) { + addChainWatcher(this._object, this._key, this); + } } // Special-case: the EachProxy relies on immediate evaluation to @@ -11756,9 +11146,13 @@ enifed("ember-metal/chains", var meta = obj['__ember_meta__']; // check if object meant only to be a prototype - if (meta && meta.proto === obj) return undefined; + if (meta && meta.proto === obj) { + return undefined; + } - if (key === "@each") return get(obj, key); + if (key === "@each") { + return get(obj, key); + } // if a CP only return cached value var desc = meta && meta.descs[key]; @@ -11784,7 +11178,9 @@ enifed("ember-metal/chains", ChainNodePrototype.destroy = function() { if (this._watching) { var obj = this._object; - if (obj) { removeChainWatcher(obj, this._key, this); } + if (obj) { + removeChainWatcher(obj, this._key, this); + } this._watching = false; // so future calls do nothing } }; @@ -11796,7 +11192,10 @@ enifed("ember-metal/chains", var path; for (path in paths) { - if (paths[path] <= 0) { continue; } // this check will also catch non-number vals. + // this check will also catch non-number vals. + if (paths[path] <= 0) { + continue; + } ret.add(path); } return ret; @@ -11843,7 +11242,9 @@ enifed("ember-metal/chains", var obj, tuple, key, src, paths; paths = this._paths; - if (paths[path] > 0) { paths[path]--; } + if (paths[path] > 0) { + paths[path]--; + } obj = this.value(); tuple = normalizeTuple(obj, path); @@ -11866,10 +11267,14 @@ enifed("ember-metal/chains", ChainNodePrototype.chain = function(key, path, src) { var chains = this._chains; var node; - if (!chains) { chains = this._chains = {}; } + if (!chains) { + chains = this._chains = {}; + } node = chains[key]; - if (!node) { node = chains[key] = new ChainNode(this, key, src); } + if (!node) { + node = chains[key] = new ChainNode(this, key, src); + } node.count++; // count chains... // chain rest of path if there is one @@ -11885,10 +11290,10 @@ enifed("ember-metal/chains", var node = chains[key]; // unchain rest of path first... - if (path && path.length>1) { - key = firstKey(path); - path = path.slice(key.length+1); - node.unchain(key, path); + if (path && path.length > 1) { + var nextKey = firstKey(path); + var nextPath = path.slice(nextKey.length + 1); + node.unchain(nextKey, nextPath); } // delete node if needed. @@ -11904,16 +11309,22 @@ enifed("ember-metal/chains", var chains = this._chains; if (chains) { for(var key in chains) { - if (!chains.hasOwnProperty(key)) { continue; } + if (!chains.hasOwnProperty(key)) { + continue; + } chains[key].willChange(events); } } - if (this._parent) { this._parent.chainWillChange(this, this._key, 1, events); } + if (this._parent) { + this._parent.chainWillChange(this, this._key, 1, events); + } }; ChainNodePrototype.chainWillChange = function(chain, path, depth, events) { - if (this._key) { path = this._key + '.' + path; } + if (this._key) { + path = this._key + '.' + path; + } if (this._parent) { this._parent.chainWillChange(this, path, depth+1, events); @@ -11929,7 +11340,10 @@ enifed("ember-metal/chains", }; ChainNodePrototype.chainDidChange = function(chain, path, depth, events) { - if (this._key) { path = this._key + '.' + path; } + if (this._key) { + path = this._key + '.' + path; + } + if (this._parent) { this._parent.chainDidChange(this, path, depth+1, events); } else { @@ -11956,8 +11370,9 @@ enifed("ember-metal/chains", // Special-case: the EachProxy relies on immediate evaluation to // establish its observers. - if (this._parent && this._parent._key === '@each') + if (this._parent && this._parent._key === '@each') { this.value(); + } } // then notify chains... @@ -11970,22 +11385,30 @@ enifed("ember-metal/chains", } // if no events are passed in then we only care about the above wiring update - if (events === null) { return; } + if (events === null) { + return; + } // and finally tell parent about my path changing... - if (this._parent) { this._parent.chainDidChange(this, this._key, 1, events); } + if (this._parent) { + this._parent.chainDidChange(this, this._key, 1, events); + } }; function finishChains(obj) { // We only create meta if we really have to - var m = obj['__ember_meta__'], - chains, chainWatchers, chainNodes; + var m = obj['__ember_meta__']; + var chains, chainWatchers, chainNodes; + if (m) { // finish any current chains node watchers that reference obj chainWatchers = m.chainWatchers; if (chainWatchers) { for(var key in chainWatchers) { - if (!chainWatchers.hasOwnProperty(key)) { continue; } + if (!chainWatchers.hasOwnProperty(key)) { + continue; + } + chainNodes = chainWatchers[key]; if (chainNodes) { for (var i=0,l=chainNodes.length;i 0) { - mixin.mixins = a_map.call(args, function(x) { - if (x instanceof Mixin) { return x; } - - // Note: Manually setup a primitive mixin here. This is the only - // way to actually get a primitive mixin. This way normal creation - // of mixins will give you combined mixins... - var mixin = new Mixin(); - mixin.properties = x; - return mixin; - }); - } - return mixin; - } - function isMethod(obj) { return 'function' === typeof obj && obj.isMethod !== false && - obj !== Boolean && obj !== Object && obj !== Number && obj !== Array && obj !== Date && obj !== String; + obj !== Boolean && + obj !== Object && + obj !== Number && + obj !== Array && + obj !== Date && + obj !== String; } var CONTINUE = {}; @@ -15886,6 +15350,10 @@ enifed("ember-metal/mixin", return property; } + var sourceAvailable = (function() { + return this; + }).toString().indexOf('return this;') > -1; + function giveMethodSuper(obj, key, method, values, descs) { var superMethod; @@ -15904,7 +15372,21 @@ enifed("ember-metal/mixin", return method; } - return wrap(method, superMethod); + var hasSuper; + if (sourceAvailable) { + hasSuper = method.__hasSuper; + + if (hasSuper === undefined) { + hasSuper = method.toString().indexOf('_super') > -1; + method.__hasSuper = hasSuper; + } + } + + if (sourceAvailable === false || hasSuper) { + return wrap(method, superMethod); + } else { + return method; + } } function applyConcatenatedProperties(obj, key, value, values) { @@ -15912,7 +15394,11 @@ enifed("ember-metal/mixin", if (baseValue) { if ('function' === typeof baseValue.concat) { - return baseValue.concat(value); + if (value === null || value === undefined) { + return baseValue; + } else { + return baseValue.concat(value); + } } else { return makeArray(baseValue).concat(value); } @@ -16027,6 +15513,31 @@ enifed("ember-metal/mixin", } } + function connectStreamBinding(obj, key, stream) { + var onNotify = function(stream) { + _suspendObserver(obj, key, null, didChange, function() { + trySet(obj, key, stream.value()); + }); + }; + + var didChange = function() { + stream.setValue(get(obj, key), onNotify); + }; + + // Initialize value + set(obj, key, stream.value()); + + addObserver(obj, key, null, didChange); + + stream.subscribe(onNotify); + + if (obj._streamBindingSubscriptions === undefined) { + obj._streamBindingSubscriptions = o_create(null); + } + + obj._streamBindingSubscriptions[key] = onNotify; + } + function connectBindings(obj, m) { // TODO Mixin.apply(instance) should disconnect binding if exists var bindings = m.bindings; @@ -16036,7 +15547,10 @@ enifed("ember-metal/mixin", binding = bindings[key]; if (binding) { to = key.slice(0, -7); // strip Binding off end - if (binding instanceof Binding) { + if (binding.isStream) { + connectStreamBinding(obj, to, binding); + continue; + } else if (binding instanceof Binding) { binding = binding.copy(); // copy prototypes' instance binding.to(to); } else { // binding is string path @@ -16214,12 +15728,29 @@ enifed("ember-metal/mixin", @namespace Ember */ __exports__["default"] = Mixin; - function Mixin() { return initMixin(this, arguments); } - Mixin.prototype = { - properties: null, - mixins: null, - ownerConstructor: null - }; + function Mixin(args, properties) { + this.properties = properties; + + var length = args && args.length; + + if (length > 0) { + var m = new Array(length); + + for (var i = 0; i < length; i++) { + var x = args[i]; + if (x instanceof Mixin) { + m[i] = x; + } else { + m[i] = new Mixin(undefined, x); + } + } + + this.mixins = m; + } else { + this.mixins = undefined; + } + this.ownerConstructor = undefined; + } Mixin._apply = applyMixin; @@ -16242,7 +15773,12 @@ enifed("ember-metal/mixin", // ES6TODO: this relies on a global state? Ember.anyUnprocessedMixins = true; var M = this; - return initMixin(new M(), arguments); + var length = arguments.length; + var args = new Array(length); + for (var i = 0; i < length; i++) { + args[i] = arguments[i]; + } + return new M(args, undefined); }; var MixinPrototype = Mixin.prototype; @@ -16252,12 +15788,11 @@ enifed("ember-metal/mixin", @param arguments* */ MixinPrototype.reopen = function() { - var mixin, tmp; + var mixin; if (this.properties) { - mixin = Mixin.create(); - mixin.properties = this.properties; - delete this.properties; + mixin = new Mixin(undefined, this.properties); + this.properties = undefined; this.mixins = [mixin]; } else if (!this.mixins) { this.mixins = []; @@ -16273,9 +15808,7 @@ enifed("ember-metal/mixin", if (mixin instanceof Mixin) { mixins.push(mixin); } else { - tmp = Mixin.create(); - tmp.properties = mixin; - mixins.push(tmp); + mixins.push(new Mixin(undefined, mixin)); } } @@ -16327,7 +15860,7 @@ enifed("ember-metal/mixin", }; MixinPrototype.without = function() { - var ret = new Mixin(this); + var ret = new Mixin([this]); ret._without = a_slice.call(arguments); return ret; }; @@ -16352,7 +15885,9 @@ enifed("ember-metal/mixin", var ret = []; _keys(keys, this, seen); for(var key in keys) { - if (keys.hasOwnProperty(key)) { ret.push(key); } + if (keys.hasOwnProperty(key)) { + ret.push(key); + } } return ret; }; @@ -16632,12 +16167,12 @@ enifed("ember-metal/observer", @for Ember @param obj @param {String} path - @param {Object|Function} targetOrMethod + @param {Object|Function} target @param {Function|String} [method] */ - function removeObserver(obj, _path, target, method) { - unwatch(obj, _path); - removeListener(obj, changeEvent(_path), target, method); + function removeObserver(obj, path, target, method) { + unwatch(obj, path); + removeListener(obj, changeEvent(path), target, method); return this; } @@ -16647,12 +16182,12 @@ enifed("ember-metal/observer", @for Ember @param obj @param {String} path - @param {Object|Function} targetOrMethod + @param {Object|Function} target @param {Function|String} [method] */ - function addBeforeObserver(obj, _path, target, method) { - addListener(obj, beforeEvent(_path), target, method); - watch(obj, _path); + function addBeforeObserver(obj, path, target, method) { + addListener(obj, beforeEvent(path), target, method); + watch(obj, path); return this; } @@ -16688,12 +16223,12 @@ enifed("ember-metal/observer", @for Ember @param obj @param {String} path - @param {Object|Function} targetOrMethod + @param {Object|Function} target @param {Function|String} [method] */ - function removeBeforeObserver(obj, _path, target, method) { - unwatch(obj, _path); - removeListener(obj, beforeEvent(_path), target, method); + function removeBeforeObserver(obj, path, target, method) { + unwatch(obj, path); + removeListener(obj, beforeEvent(path), target, method); return this; } @@ -16781,16 +16316,34 @@ enifed("ember-metal/path_cache", 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 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 firstDotIndexCache = new Cache(1000, function(key) { return key.indexOf('.'); }); + + var firstKeyCache = new Cache(1000, function(path) { + var index = firstDotIndexCache.get(path); + if (index === -1) { + return path; + } else { + return path.slice(0, index); + } + }); + + var tailPathCache = new Cache(1000, function(path) { + var index = firstDotIndexCache.get(path); + if (index !== -1) { + return path.slice(index + 1); + } + }); var caches = { - isGlobalCache: isGlobalCache, - isGlobalPathCache: isGlobalPathCache, - hasThisCache: hasThisCache, - isPathCache: isPathCache + isGlobalCache: isGlobalCache, + isGlobalPathCache: isGlobalPathCache, + hasThisCache: hasThisCache, + firstDotIndexCache: firstDotIndexCache, + firstKeyCache: firstKeyCache, + tailPathCache: tailPathCache }; __exports__.caches = caches; function isGlobal(path) { @@ -16806,10 +16359,18 @@ enifed("ember-metal/path_cache", } __exports__.hasThis = hasThis;function isPath(path) { - return isPathCache.get(path); + return firstDotIndexCache.get(path) !== -1; } - __exports__.isPath = isPath; + __exports__.isPath = isPath;function getFirstKey(path) { + return firstKeyCache.get(path); + } + + __exports__.getFirstKey = getFirstKey;function getTailPath(path) { + return tailPathCache.get(path); + } + + __exports__.getTailPath = getTailPath; }); enifed("ember-metal/platform", ["ember-metal/platform/define_property","ember-metal/platform/define_properties","ember-metal/platform/create","exports"], @@ -17221,6 +16782,7 @@ enifed("ember-metal/properties", return this; } + __exports__.defineProperty = defineProperty; }); enifed("ember-metal/property_events", @@ -17263,9 +16825,18 @@ enifed("ember-metal/property_events", var proto = m && m.proto; var desc = m && m.descs[keyName]; - if (!watching) { return; } - if (proto === obj) { return; } - if (desc && desc.willChange) { desc.willChange(obj, keyName); } + if (!watching) { + return; + } + + if (proto === obj) { + return; + } + + if (desc && desc.willChange) { + desc.willChange(obj, keyName); + } + dependentKeysWillChange(obj, keyName, m); chainsWillChange(obj, keyName, m); notifyBeforeObservers(obj, keyName); @@ -17292,11 +16863,18 @@ enifed("ember-metal/property_events", var proto = m && m.proto; var desc = m && m.descs[keyName]; - if (proto === obj) { return; } + if (proto === obj) { + return; + } // shouldn't this mean that we're watching this key? - if (desc && desc.didChange) { desc.didChange(obj, keyName); } - if (!watching && keyName !== 'length') { return; } + if (desc && desc.didChange) { + desc.didChange(obj, keyName); + } + + if (!watching && keyName !== 'length') { + return; + } if (m && m.deps && m.deps[keyName]) { dependentKeysDidChange(obj, keyName, m); @@ -17315,9 +16893,16 @@ enifed("ember-metal/property_events", if (meta && meta.deps && (deps = meta.deps[depKey])) { var seen = WILL_SEEN; var top = !seen; - if (top) { seen = WILL_SEEN = {}; } + + if (top) { + seen = WILL_SEEN = {}; + } + iterDeps(propertyWillChange, obj, deps, depKey, seen, meta); - if (top) { WILL_SEEN = null; } + + if (top) { + WILL_SEEN = null; + } } } @@ -17329,15 +16914,26 @@ enifed("ember-metal/property_events", if (meta && meta.deps && (deps = meta.deps[depKey])) { var seen = DID_SEEN; var top = !seen; - if (top) { seen = DID_SEEN = {}; } + + if (top) { + seen = DID_SEEN = {}; + } + iterDeps(propertyDidChange, obj, deps, depKey, seen, meta); - if (top) { DID_SEEN = null; } + + if (top) { + DID_SEEN = null; + } } } function keysOf(obj) { var keys = []; - for (var key in obj) keys.push(key); + + for (var key in obj) { + keys.push(key); + } + return keys; } @@ -17345,8 +16941,15 @@ enifed("ember-metal/property_events", var keys, key, i, desc; var guid = guidFor(obj); var current = seen[guid]; - if (!current) current = seen[guid] = {}; - if (current[depKey]) return; + + if (!current) { + current = seen[guid] = {}; + } + + if (current[depKey]) { + return; + } + current[depKey] = true; if (deps) { @@ -17355,7 +16958,11 @@ enifed("ember-metal/property_events", for (i=0; i

    My great app

    {{render "navigation"}} @@ -21165,10 +21045,9 @@ enifed("ember-routing-handlebars/helpers/render", */ __exports__["default"] = function renderHelper(name, contextString, options) { var length = arguments.length; - var contextProvided = length === 3; - var container, router, controller, view, context, lookupOptions; + var container, router, controller, view, initialContext; - container = (options || contextString).data.keywords.controller.container; + container = (options || contextString).data.view._keywords.controller.value().container; router = container.lookup('router:main'); if (length === 2) { @@ -21177,7 +21056,7 @@ enifed("ember-routing-handlebars/helpers/render", contextString = undefined; } else if (length === 3) { // create a new controller - context = handlebarsGet(options.contexts[1], contextString, options); + initialContext = options.data.view.getStream(contextString).value(); } else { throw new EmberError("You must pass a templateName to render"); } @@ -21197,15 +21076,15 @@ enifed("ember-routing-handlebars/helpers/render", if (options.hash.controller) { } - var parentController = options.data.keywords.controller; + var parentController = options.data.view._keywords.controller.value(); // choose name if (length > 2) { var factory = container.lookupFactory(controllerFullName) || - generateControllerFactory(container, controllerName, context); + generateControllerFactory(container, controllerName, initialContext); controller = factory.create({ - model: context, + modelBinding: options.data.view._getBindingForStream(contextString), parentController: parentController, target: parentController }); @@ -21223,14 +21102,6 @@ enifed("ember-routing-handlebars/helpers/render", }); } - var root = options.contexts[1]; - - if (root) { - view.registerObserver(root, contextString, function() { - controller.set('model', handlebarsGet(root, contextString, options)); - }); - } - options.hash.viewName = camelize(name); var templateName = 'template:' + name; @@ -21238,7 +21109,7 @@ enifed("ember-routing-handlebars/helpers/render", options.hash.controller = controller; - if (router && !context) { + if (router && !initialContext) { router._connectActiveView(name, view); } @@ -21247,102 +21118,9 @@ enifed("ember-routing-handlebars/helpers/render", ViewHelper.instanceHelper(this, view, options); } }); -enifed("ember-routing-handlebars/helpers/shared", - ["ember-metal/property_get","ember-metal/array","ember-runtime/mixins/controller","ember-handlebars/ext","ember-metal/utils","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) { - "use strict"; - var get = __dependency1__.get; - var map = __dependency2__.map; - var ControllerMixin = __dependency3__["default"]; - var handlebarsResolve = __dependency4__.resolveParams; - var handlebarsGet = __dependency4__.handlebarsGet; - var typeOf = __dependency5__.typeOf; - var get = __dependency1__.get; - - function routeArgs(targetRouteName, models, queryParams) { - var args = []; - if (typeOf(targetRouteName) === 'string') { - args.push('' + targetRouteName); - } - args.push.apply(args, models); - args.push({ queryParams: queryParams }); - return args; - } - - __exports__.routeArgs = routeArgs;function getActiveTargetName(router) { - var handlerInfos = router.activeTransition ? - router.activeTransition.state.handlerInfos : - router.state.handlerInfos; - return handlerInfos[handlerInfos.length - 1].name; - } - - __exports__.getActiveTargetName = getActiveTargetName;function resolveParams(context, params, options) { - return map.call(resolvePaths(context, params, options), function(path, i) { - if (null === path) { - // Param was string/number, not a path, so just return raw string/number. - return params[i]; - } else { - return handlebarsGet(context, path, options); - } - }); - } - - __exports__.resolveParams = resolveParams;function stashParamNames(router, handlerInfos) { - if (handlerInfos._namesStashed) { return; } - - // This helper exists because router.js/route-recognizer.js awkwardly - // keeps separate a handlerInfo's list of parameter names depending - // on whether a URL transition or named transition is happening. - // Hopefully we can remove this in the future. - var targetRouteName = handlerInfos[handlerInfos.length-1].name; - var recogHandlers = router.router.recognizer.handlersFor(targetRouteName); - var dynamicParent = null; - - for (var i = 0, len = handlerInfos.length; i < len; ++i) { - var handlerInfo = handlerInfos[i]; - var names = recogHandlers[i].names; - - if (names.length) { - dynamicParent = handlerInfo; - } - - handlerInfo._names = names; - - var route = handlerInfo.handler; - route._stashNames(handlerInfo, dynamicParent); - } - - handlerInfos._namesStashed = true; - } - - __exports__.stashParamNames = stashParamNames;function resolvePaths(context, params, options) { - var resolved = handlebarsResolve(context, params, options); - var types = options.types; - - return map.call(resolved, function(object, i) { - if (types[i] === 'ID') { - return unwrap(object, params[i]); - } else { - return null; - } - }); - - function unwrap(object, path) { - if (path === 'controller') { return path; } - - if (ControllerMixin.detect(object)) { - return unwrap(get(object, 'model'), path ? path + '.model' : 'model'); - } else { - return path; - } - } - } - - __exports__.resolvePaths = resolvePaths; - }); enifed("ember-routing", - ["ember-handlebars","ember-metal/core","ember-routing/ext/run_loop","ember-routing/ext/controller","ember-routing/ext/view","ember-routing/location/api","ember-routing/location/none_location","ember-routing/location/hash_location","ember-routing/location/history_location","ember-routing/location/auto_location","ember-routing/system/generate_controller","ember-routing/system/controller_for","ember-routing/system/dsl","ember-routing/system/router","ember-routing/system/route","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __exports__) { + ["ember-metal/core","ember-routing/ext/run_loop","ember-routing/ext/controller","ember-routing/ext/view","ember-routing/location/api","ember-routing/location/none_location","ember-routing/location/hash_location","ember-routing/location/history_location","ember-routing/location/auto_location","ember-routing/system/generate_controller","ember-routing/system/controller_for","ember-routing/system/dsl","ember-routing/system/router","ember-routing/system/route","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __exports__) { "use strict"; /** Ember Routing @@ -21352,23 +21130,22 @@ enifed("ember-routing", @requires ember-views */ - var EmberHandlebars = __dependency1__["default"]; - var Ember = __dependency2__["default"]; + var Ember = __dependency1__["default"]; // ES6TODO: Cleanup modules with side-effects below - var EmberLocation = __dependency6__["default"]; - var NoneLocation = __dependency7__["default"]; - var HashLocation = __dependency8__["default"]; - var HistoryLocation = __dependency9__["default"]; - var AutoLocation = __dependency10__["default"]; + var EmberLocation = __dependency5__["default"]; + var NoneLocation = __dependency6__["default"]; + var HashLocation = __dependency7__["default"]; + var HistoryLocation = __dependency8__["default"]; + var AutoLocation = __dependency9__["default"]; - var generateControllerFactory = __dependency11__.generateControllerFactory; - var generateController = __dependency11__["default"]; - var controllerFor = __dependency12__["default"]; - var RouterDSL = __dependency13__["default"]; - var Router = __dependency14__["default"]; - var Route = __dependency15__["default"]; + var generateControllerFactory = __dependency10__.generateControllerFactory; + var generateController = __dependency10__["default"]; + var controllerFor = __dependency11__["default"]; + var RouterDSL = __dependency12__["default"]; + var Router = __dependency13__["default"]; + var Route = __dependency14__["default"]; Ember.Location = EmberLocation; Ember.AutoLocation = AutoLocation; @@ -21386,8 +21163,8 @@ enifed("ember-routing", __exports__["default"] = Ember; }); enifed("ember-routing/ext/controller", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/computed","ember-metal/utils","ember-metal/merge","ember-metal/enumerable_utils","ember-runtime/mixins/controller","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) { + ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/computed","ember-metal/utils","ember-metal/merge","ember-runtime/mixins/controller","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; // FEATURES, deprecate @@ -21397,9 +21174,8 @@ enifed("ember-routing/ext/controller", var typeOf = __dependency5__.typeOf; var meta = __dependency5__.meta; var merge = __dependency6__["default"]; - var map = __dependency7__.map; - var ControllerMixin = __dependency8__["default"]; + var ControllerMixin = __dependency7__["default"]; /** @module ember @@ -21415,6 +21191,11 @@ enifed("ember-routing/ext/controller", }, /** + Defines which query parameters the controller accepts. + If you give the names ['category','page'] it will bind + the values of these query parameters to the variables + `this.category` and `this.page` + @property queryParams @public */ @@ -21739,8 +21520,6 @@ enifed("ember-routing/ext/run_loop", // resolve), which is used in router transitions to prevent unnecessary // loading state entry if all context promises resolve on the // 'actions' queue first. - - var queues = run.queues; run._addQueue('routerTransitions', 'actions'); }); enifed("ember-routing/ext/view", @@ -21765,7 +21544,7 @@ enifed("ember-routing/ext/view", @method init */ init: function() { - set(this, '_outlets', {}); + this._outlets = {}; this._super(); }, @@ -21901,13 +21680,11 @@ enifed("ember-routing/ext/view", __exports__["default"] = EmberView; }); enifed("ember-routing/location/api", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __exports__) { + ["ember-metal/core","exports"], + function(__dependency1__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; // deprecate, assert - var get = __dependency2__.get; - var set = __dependency3__.set; /** @module ember @@ -22110,18 +21887,17 @@ enifed("ember-routing/location/api", }; }); enifed("ember-routing/location/auto_location", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-routing/location/api","ember-routing/location/history_location","ember-routing/location/hash_location","ember-routing/location/none_location","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) { + ["ember-metal/core","ember-metal/property_set","ember-routing/location/api","ember-routing/location/history_location","ember-routing/location/hash_location","ember-routing/location/none_location","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; // FEATURES - var get = __dependency2__.get; - var set = __dependency3__.set; + var set = __dependency2__.set; - var EmberLocation = __dependency4__["default"]; - var HistoryLocation = __dependency5__["default"]; - var HashLocation = __dependency6__["default"]; - var NoneLocation = __dependency7__["default"]; + var EmberLocation = __dependency3__["default"]; + var HistoryLocation = __dependency4__["default"]; + var HashLocation = __dependency5__["default"]; + var NoneLocation = __dependency6__["default"]; /** @module ember @@ -22546,14 +22322,33 @@ enifed("ember-routing/location/hash_location", getHash: EmberLocation._getHash, /** - Returns the current `location.hash`, minus the '#' at the front. + Returns the normalized URL, constructed from `location.hash`. + + e.g. `#/foo` => `/foo` as well as `#/foo#bar` => `/foo#bar`. + + By convention, hashed paths must begin with a forward slash, otherwise they + are not treated as a path so we can distinguish intent. @private @method getURL */ getURL: function() { - var path = this.getHash().substr(1); - return path; + var originalPath = this.getHash().substr(1); + var outPath = originalPath; + + if (outPath.charAt(0) !== '/') { + outPath = '/'; + + // Only add the # if the path isn't empty. + // We do NOT want `/#` since the ampersand + // is only included (conventionally) when + // the location.hash has a value + if (originalPath) { + outPath += '#' + originalPath; + } + } + + return outPath; }, /** @@ -22637,16 +22432,15 @@ enifed("ember-routing/location/hash_location", }); }); enifed("ember-routing/location/history_location", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-runtime/system/object","ember-views/system/jquery","exports"], + ["ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-runtime/system/object","ember-routing/location/api","ember-views/system/jquery","exports"], function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) { "use strict"; - var Ember = __dependency1__["default"]; - // FEATURES - var get = __dependency2__.get; - var set = __dependency3__.set; - var guidFor = __dependency4__.guidFor; + var get = __dependency1__.get; + var set = __dependency2__.set; + var guidFor = __dependency3__.guidFor; - var EmberObject = __dependency5__["default"]; + var EmberObject = __dependency4__["default"]; + var EmberLocation = __dependency5__["default"]; var jQuery = __dependency6__["default"]; /** @@ -22712,6 +22506,7 @@ enifed("ember-routing/location/history_location", var search = location.search || ''; url += search; + url += this.getHash(); return url; }, @@ -22793,7 +22588,6 @@ enifed("ember-routing/location/history_location", */ replaceState: function(path) { var state = { path: path }; - get(this, 'history').replaceState(state, null, path); // store state if browser doesn't support `history.state` @@ -22859,7 +22653,16 @@ enifed("ember-routing/location/history_location", var guid = guidFor(this); jQuery(window).off('popstate.ember-location-'+guid); - } + }, + + /** + @private + + Returns normalized location.hash + + @method getHash + */ + getHash: EmberLocation._getHash }); }); enifed("ember-routing/location/none_location", @@ -23044,28 +22847,20 @@ enifed("ember-routing/system/dsl", var type = options.resetNamespace === true ? 'resource' : 'route'; - - if (typeof options.path !== 'string') { - options.path = "/" + name; - } - - if (canNest(this) && options.resetNamespace !== true) { - name = this.parent + "." + name; - } - + if (callback) { - var dsl = new DSL(name); - route(dsl, 'loading'); - route(dsl, 'error', { path: "/_unused_dummy_error_path_route_" + name + "/:error" }); + var fullName = getFullName(this, name, options.resetNamespace); + var dsl = new DSL(fullName); + createRoute(dsl, 'loading'); + createRoute(dsl, 'error', { path: "/_unused_dummy_error_path_route_" + name + "/:error" }); - if (callback) { callback.call(dsl); } + callback.call(dsl); - this.push(options.path, name, dsl.generate()); + createRoute(this, name, options, dsl.generate()); } else { - this.push(options.path, name, null); + createRoute(this, name, options); } - - }, + }, push: function(url, name, callback) { var parts = name.split('.'); @@ -23092,13 +22887,13 @@ enifed("ember-routing/system/dsl", var dslMatches = this.matches; if (!this.explicitIndex) { - route(this, "index", { path: "/" }); + this.route("index", { path: "/" }); } return function(match) { for (var i=0, l=dslMatches.length; i1) args = a_slice.call(arguments, 1); + var ret = Ember.A(); + var args; + + if (arguments.length > 1) { + args = a_slice.call(arguments, 1); + } this.forEach(function(x, idx) { var method = x && x[methodName]; + if ('function' === typeof method) { ret[idx] = args ? apply(x, method, args) : x[methodName](); } @@ -31067,23 +31137,29 @@ enifed("ember-runtime/mixins/enumerable", */ toArray: function() { var ret = Ember.A(); - this.forEach(function(o, idx) { ret[idx] = o; }); + + this.forEach(function(o, idx) { + ret[idx] = o; + }); + return ret; }, /** - Returns a copy of the array with all null and undefined elements removed. + Returns a copy of the array with all `null` and `undefined` elements removed. ```javascript - var arr = ["a", null, "c", undefined]; - arr.compact(); // ["a", "c"] + var arr = ['a', null, 'c', undefined]; + arr.compact(); // ['a', 'c'] ``` @method compact @return {Array} the array without null and undefined elements. */ compact: function() { - return this.filter(function(value) { return value != null; }); + return this.filter(function(value) { + return value != null; + }); }, /** @@ -31092,8 +31168,8 @@ enifed("ember-runtime/mixins/enumerable", the receiver does not contain the value. ```javascript - var arr = ["a", "b", "a", "c"]; - arr.without("a"); // ["b", "c"] + var arr = ['a', 'b', 'a', 'c']; + arr.without('a'); // ['b', 'c'] ``` @method without @@ -31101,12 +31177,19 @@ enifed("ember-runtime/mixins/enumerable", @return {Ember.Enumerable} */ without: function(value) { - if (!this.contains(value)) return this; // nothing to do + if (!this.contains(value)) { + return this; // nothing to do + } + var ret = Ember.A(); + this.forEach(function(k) { - if (k !== value) ret[ret.length] = k; - }) ; - return ret ; + if (k !== value) { + ret[ret.length] = k; + } + }); + + return ret; }, /** @@ -31114,18 +31197,24 @@ enifed("ember-runtime/mixins/enumerable", implementation returns an array regardless of the receiver type. ```javascript - var arr = ["a", "a", "b", "b"]; - arr.uniq(); // ["a", "b"] + var arr = ['a', 'a', 'b', 'b']; + arr.uniq(); // ['a', 'b'] ``` + This only works on primitive data types, e.g. Strings, Numbers, etc. + @method uniq @return {Ember.Enumerable} */ uniq: function() { var ret = Ember.A(); + this.forEach(function(k) { - if (indexOf(ret, k)<0) ret.push(k); + if (indexOf(ret, k) < 0) { + ret.push(k); + } }); + return ret; }, @@ -31163,10 +31252,17 @@ enifed("ember-runtime/mixins/enumerable", var didChange = (opts && opts.didChange) || 'enumerableDidChange'; var hasObservers = get(this, 'hasEnumerableObservers'); - if (!hasObservers) propertyWillChange(this, 'hasEnumerableObservers'); + if (!hasObservers) { + propertyWillChange(this, 'hasEnumerableObservers'); + } + addListener(this, '@enumerable:before', target, willChange); addListener(this, '@enumerable:change', target, didChange); - if (!hasObservers) propertyDidChange(this, 'hasEnumerableObservers'); + + if (!hasObservers) { + propertyDidChange(this, 'hasEnumerableObservers'); + } + return this; }, @@ -31181,12 +31277,19 @@ enifed("ember-runtime/mixins/enumerable", removeEnumerableObserver: function(target, opts) { var willChange = (opts && opts.willChange) || 'enumerableWillChange'; var didChange = (opts && opts.didChange) || 'enumerableDidChange'; - var hasObservers = get(this, 'hasEnumerableObservers'); - if (hasObservers) propertyWillChange(this, 'hasEnumerableObservers'); + + if (hasObservers) { + propertyWillChange(this, 'hasEnumerableObservers'); + } + removeListener(this, '@enumerable:before', target, willChange); removeListener(this, '@enumerable:change', target, didChange); - if (hasObservers) propertyDidChange(this, 'hasEnumerableObservers'); + + if (hasObservers) { + propertyDidChange(this, 'hasEnumerableObservers'); + } + return this; }, @@ -31215,24 +31318,40 @@ enifed("ember-runtime/mixins/enumerable", @chainable */ enumerableContentWillChange: function(removing, adding) { - var removeCnt, addCnt, hasDelta; - if ('number' === typeof removing) removeCnt = removing; - else if (removing) removeCnt = get(removing, 'length'); - else removeCnt = removing = -1; + if ('number' === typeof removing) { + removeCnt = removing; + } else if (removing) { + removeCnt = get(removing, 'length'); + } else { + removeCnt = removing = -1; + } - if ('number' === typeof adding) addCnt = adding; - else if (adding) addCnt = get(adding,'length'); - else addCnt = adding = -1; + if ('number' === typeof adding) { + addCnt = adding; + } else if (adding) { + addCnt = get(adding,'length'); + } else { + addCnt = adding = -1; + } - hasDelta = addCnt<0 || removeCnt<0 || addCnt-removeCnt!==0; + hasDelta = addCnt < 0 || removeCnt < 0 || addCnt - removeCnt !== 0; - if (removing === -1) removing = null; - if (adding === -1) adding = null; + if (removing === -1) { + removing = null; + } + + if (adding === -1) { + adding = null; + } propertyWillChange(this, '[]'); - if (hasDelta) propertyWillChange(this, 'length'); + + if (hasDelta) { + propertyWillChange(this, 'length'); + } + sendEvent(this, '@enumerable:before', [this, removing, adding]); return this; @@ -31255,21 +31374,38 @@ enifed("ember-runtime/mixins/enumerable", enumerableContentDidChange: function(removing, adding) { var removeCnt, addCnt, hasDelta; - if ('number' === typeof removing) removeCnt = removing; - else if (removing) removeCnt = get(removing, 'length'); - else removeCnt = removing = -1; + if ('number' === typeof removing) { + removeCnt = removing; + } else if (removing) { + removeCnt = get(removing, 'length'); + } else { + removeCnt = removing = -1; + } - if ('number' === typeof adding) addCnt = adding; - else if (adding) addCnt = get(adding, 'length'); - else addCnt = adding = -1; + if ('number' === typeof adding) { + addCnt = adding; + } else if (adding) { + addCnt = get(adding, 'length'); + } else { + addCnt = adding = -1; + } - hasDelta = addCnt<0 || removeCnt<0 || addCnt-removeCnt!==0; + hasDelta = addCnt < 0 || removeCnt < 0 || addCnt - removeCnt !== 0; - if (removing === -1) removing = null; - if (adding === -1) adding = null; + if (removing === -1) { + removing = null; + } + + if (adding === -1) { + adding = null; + } sendEvent(this, '@enumerable:change', [this, removing, adding]); - if (hasDelta) propertyDidChange(this, 'length'); + + if (hasDelta) { + propertyDidChange(this, 'length'); + } + propertyDidChange(this, '[]'); return this ; @@ -31288,6 +31424,7 @@ enifed("ember-runtime/mixins/enumerable", */ sortBy: function() { var sortKeys = arguments; + return this.toArray().sort(function(a, b){ for(var i = 0; i < sortKeys.length; i++) { var key = sortKeys[i]; @@ -31295,7 +31432,10 @@ enifed("ember-runtime/mixins/enumerable", var propB = get(b, key); // return 1 or -1 else continue to the next sortKey var compareValue = compare(propA, propB); - if (compareValue) { return compareValue; } + + if (compareValue) { + return compareValue; + } } return 0; }); @@ -31558,8 +31698,8 @@ enifed("ember-runtime/mixins/freezable", __exports__.FROZEN_ERROR = FROZEN_ERROR; }); enifed("ember-runtime/mixins/mutable_array", - ["ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/error","ember-metal/mixin","ember-runtime/mixins/array","ember-runtime/mixins/mutable_enumerable","ember-runtime/mixins/enumerable","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) { + ["ember-metal/property_get","ember-metal/utils","ember-metal/error","ember-metal/mixin","ember-runtime/mixins/array","ember-runtime/mixins/mutable_enumerable","ember-runtime/mixins/enumerable","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) { "use strict"; /** @module ember @@ -31582,14 +31722,13 @@ enifed("ember-runtime/mixins/mutable_array", // var get = __dependency1__.get; - var set = __dependency2__.set; - var isArray = __dependency3__.isArray; - var EmberError = __dependency4__["default"]; - var Mixin = __dependency5__.Mixin; - var required = __dependency5__.required; - var EmberArray = __dependency6__["default"]; - var MutableEnumerable = __dependency7__["default"]; - var Enumerable = __dependency8__["default"]; + var isArray = __dependency2__.isArray; + var EmberError = __dependency3__["default"]; + var Mixin = __dependency4__.Mixin; + var required = __dependency4__.required; + var EmberArray = __dependency5__["default"]; + var MutableEnumerable = __dependency6__["default"]; + var Enumerable = __dependency7__["default"]; /** This mixin defines the API for modifying array-like objects. These methods can be applied only to a collection that keeps its items in an ordered set. @@ -31868,7 +32007,7 @@ enifed("ember-runtime/mixins/mutable_array", // /** - Remove all occurances of an object in the array. + Remove all occurrences of an object in the array. ```javascript var cities = ["Chicago", "Berlin", "Lima", "Chicago"]; @@ -32060,7 +32199,7 @@ enifed("ember-runtime/mixins/observable", var removeObserver = __dependency10__.removeObserver; var observersFor = __dependency10__.observersFor; var cacheFor = __dependency11__.cacheFor; - var isNone = __dependency12__.isNone; + var isNone = __dependency12__["default"]; var slice = Array.prototype.slice; @@ -32755,8 +32894,8 @@ enifed("ember-runtime/mixins/promise_proxy", } }); enifed("ember-runtime/mixins/sortable", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/enumerable_utils","ember-metal/mixin","ember-runtime/mixins/mutable_enumerable","ember-runtime/compare","ember-metal/observer","ember-metal/computed","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __exports__) { + ["ember-metal/core","ember-metal/property_get","ember-metal/enumerable_utils","ember-metal/mixin","ember-runtime/mixins/mutable_enumerable","ember-runtime/compare","ember-metal/observer","ember-metal/computed","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) { "use strict"; /** @module ember @@ -32767,23 +32906,22 @@ enifed("ember-runtime/mixins/sortable", // Ember.assert, Ember.A var get = __dependency2__.get; - var set = __dependency3__.set; - var forEach = __dependency4__.forEach; - var Mixin = __dependency5__.Mixin; - var MutableEnumerable = __dependency6__["default"]; - var compare = __dependency7__["default"]; - var addObserver = __dependency8__.addObserver; - var removeObserver = __dependency8__.removeObserver; - var computed = __dependency9__.computed; - var beforeObserver = __dependency5__.beforeObserver; - var observer = __dependency5__.observer; - //ES6TODO: should we access these directly from their package or from how thier exposed in ember-metal? + var forEach = __dependency3__.forEach; + var Mixin = __dependency4__.Mixin; + var MutableEnumerable = __dependency5__["default"]; + var compare = __dependency6__["default"]; + var addObserver = __dependency7__.addObserver; + var removeObserver = __dependency7__.removeObserver; + var computed = __dependency8__.computed; + var beforeObserver = __dependency4__.beforeObserver; + var observer = __dependency4__.observer; + //ES6TODO: should we access these directly from their package or from how their exposed in ember-metal? /** `Ember.SortableMixin` provides a standard interface for array proxies to specify a sort order and maintain this sorting when objects are added, removed, or updated without changing the implicit order of their underlying - modelarray: + model array: ```javascript songs = [ @@ -32815,8 +32953,8 @@ enifed("ember-runtime/mixins/sortable", songsController.get('firstObject'); // {trackNumber: 4, title: 'Ob-La-Di, Ob-La-Da'} ``` - SortableMixin works by sorting the arrangedContent array, which is the array that - arrayProxy displays. Due to the fact that the underlying 'content' array is not changed, that + `SortableMixin` works by sorting the `arrangedContent` array, which is the array that + `ArrayProxy` displays. Due to the fact that the underlying 'content' array is not changed, that array will not display the sorted list: ```javascript @@ -32824,8 +32962,8 @@ enifed("ember-runtime/mixins/sortable", songsController.get('firstObject'); // Returns the sorted content. ``` - Although the sorted content can also be accessed through the arrangedContent property, - it is preferable to use the proxied class and not the arrangedContent array directly. + Although the sorted content can also be accessed through the `arrangedContent` property, + it is preferable to use the proxied class and not the `arrangedContent` array directly. @class SortableMixin @namespace Ember @@ -32834,7 +32972,7 @@ enifed("ember-runtime/mixins/sortable", __exports__["default"] = Mixin.create(MutableEnumerable, { /** - Specifies which properties dictate the arrangedContent's sort order. + Specifies which properties dictate the `arrangedContent`'s sort order. When specifying multiple properties the sorting will use properties from the `sortProperties` array prioritized from first to last. @@ -32844,7 +32982,7 @@ enifed("ember-runtime/mixins/sortable", sortProperties: null, /** - Specifies the arrangedContent's sort direction. + Specifies the `arrangedContent`'s sort direction. Sorts the content in ascending order by default. Set to `false` to use descending order. @@ -32856,13 +32994,14 @@ enifed("ember-runtime/mixins/sortable", /** The function used to compare two values. You can override this if you want to do custom comparisons. Functions must be of the type expected by - Array#sort, i.e. - return 0 if the two parameters are equal, - return a negative value if the first parameter is smaller than the second or - return a positive value otherwise: + Array#sort, i.e., + + * return 0 if the two parameters are equal, + * return a negative value if the first parameter is smaller than the second or + * return a positive value otherwise: ```javascript - function(x,y) { // These are assumed to be integers + function(x, y) { // These are assumed to be integers if (x === y) return 0; return x < y ? -1 : 1; @@ -32912,12 +33051,11 @@ enifed("ember-runtime/mixins/sortable", isSorted: computed.notEmpty('sortProperties'), /** - Overrides the default arrangedContent from arrayProxy in order to sort by sortFunction. - Also sets up observers for each sortProperty on each item in the content Array. + Overrides the default `arrangedContent` from `ArrayProxy` in order to sort by `sortFunction`. + Also sets up observers for each `sortProperty` on each item in the content Array. @property arrangedContent */ - arrangedContent: computed('content', 'sortProperties.@each', function(key, value) { var content = get(this, 'content'); var isSorted = get(this, 'isSorted'); @@ -33060,8 +33198,8 @@ enifed("ember-runtime/mixins/sortable", }); }); enifed("ember-runtime/mixins/target_action_support", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/mixin","ember-metal/computed","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) { + ["ember-metal/core","ember-metal/property_get","ember-metal/utils","ember-metal/mixin","ember-metal/computed","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) { "use strict"; /** @module ember @@ -33071,10 +33209,9 @@ enifed("ember-runtime/mixins/target_action_support", // Ember.lookup, Ember.assert var get = __dependency2__.get; - var set = __dependency3__.set; - var typeOf = __dependency4__.typeOf; - var Mixin = __dependency5__.Mixin; - var computed = __dependency6__.computed; + var typeOf = __dependency3__.typeOf; + var Mixin = __dependency4__.Mixin; + var computed = __dependency5__.computed; /** `Ember.TargetActionSupport` is a mixin that can be included in a class @@ -33217,25 +33354,25 @@ enifed("ember-runtime/system/application", __exports__["default"] = Namespace.extend(); }); enifed("ember-runtime/system/array_proxy", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/computed","ember-metal/mixin","ember-metal/property_events","ember-metal/error","ember-runtime/system/object","ember-runtime/mixins/mutable_array","ember-runtime/mixins/enumerable","ember-runtime/system/string","exports"], + ["ember-metal/core","ember-metal/property_get","ember-metal/utils","ember-metal/computed","ember-metal/mixin","ember-metal/property_events","ember-metal/error","ember-runtime/system/object","ember-runtime/mixins/mutable_array","ember-runtime/mixins/enumerable","ember-runtime/system/string","ember-metal/alias","exports"], function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; // Ember.K, Ember.assert var get = __dependency2__.get; - var set = __dependency3__.set; - var isArray = __dependency4__.isArray; - var apply = __dependency4__.apply; - var computed = __dependency5__.computed; - var beforeObserver = __dependency6__.beforeObserver; - var observer = __dependency6__.observer; - var beginPropertyChanges = __dependency7__.beginPropertyChanges; - var endPropertyChanges = __dependency7__.endPropertyChanges; - var EmberError = __dependency8__["default"]; - var EmberObject = __dependency9__["default"]; - var MutableArray = __dependency10__["default"]; - var Enumerable = __dependency11__["default"]; - var fmt = __dependency12__.fmt; + var isArray = __dependency3__.isArray; + var apply = __dependency3__.apply; + var computed = __dependency4__.computed; + var beforeObserver = __dependency5__.beforeObserver; + var observer = __dependency5__.observer; + var beginPropertyChanges = __dependency6__.beginPropertyChanges; + var endPropertyChanges = __dependency6__.endPropertyChanges; + var EmberError = __dependency7__["default"]; + var EmberObject = __dependency8__["default"]; + var MutableArray = __dependency9__["default"]; + var Enumerable = __dependency10__["default"]; + var fmt = __dependency11__.fmt; + var alias = __dependency12__["default"]; /** @module ember @@ -33244,7 +33381,6 @@ enifed("ember-runtime/system/array_proxy", var OUT_OF_RANGE_EXCEPTION = "Index out of range"; var EMPTY = []; - var alias = computed.alias; var K = Ember.K; /** @@ -33586,18 +33722,18 @@ enifed("ember-runtime/system/array_proxy", __exports__["default"] = ArrayProxy; }); enifed("ember-runtime/system/container", - ["ember-metal/property_set","exports"], - function(__dependency1__, __exports__) { + ["ember-metal/property_set","container","exports"], + function(__dependency1__, __dependency2__, __exports__) { "use strict"; - var set = __dependency1__["default"]; + var set = __dependency1__.set; + var Container = __dependency2__["default"]; - var Container = requireModule('container')["default"]; Container.set = set; __exports__["default"] = Container; }); enifed("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-metal/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/utils","ember-metal/platform","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/injected_property","ember-metal/run_loop","ember-metal/watching","exports"], function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __dependency16__, __dependency17__, __exports__) { // Remove "use strict"; from transpiled module until // https://bugs.webkit.org/show_bug.cgi?id=138038 is fixed @@ -33615,32 +33751,32 @@ enifed("ember-runtime/system/core_object", // NOTE: this object should never be included directly. Instead use `Ember.Object`. // We only define this separately so that `Ember.Set` can depend on it. var get = __dependency2__.get; - var set = __dependency3__.set; - var guidFor = __dependency4__.guidFor; - var apply = __dependency4__.apply; - var o_create = __dependency5__.create; - var generateGuid = __dependency4__.generateGuid; - var GUID_KEY = __dependency4__.GUID_KEY; - var meta = __dependency4__.meta; - var makeArray = __dependency4__.makeArray; - var rewatch = __dependency6__.rewatch; - var finishChains = __dependency7__.finishChains; - var sendEvent = __dependency8__.sendEvent; - var IS_BINDING = __dependency9__.IS_BINDING; - var Mixin = __dependency9__.Mixin; - var required = __dependency9__.required; - var indexOf = __dependency10__.indexOf; - var EmberError = __dependency11__["default"]; - var o_defineProperty = __dependency5__.defineProperty; - var keys = __dependency12__["default"]; - var ActionHandler = __dependency13__["default"]; - var defineProperty = __dependency14__.defineProperty; - var Binding = __dependency15__.Binding; - var ComputedProperty = __dependency16__.ComputedProperty; - var run = __dependency17__["default"]; - var destroy = __dependency6__.destroy; + var guidFor = __dependency3__.guidFor; + var apply = __dependency3__.apply; + var o_create = __dependency4__.create; + var generateGuid = __dependency3__.generateGuid; + var GUID_KEY = __dependency3__.GUID_KEY; + var meta = __dependency3__.meta; + var makeArray = __dependency3__.makeArray; + var finishChains = __dependency5__.finishChains; + var sendEvent = __dependency6__.sendEvent; + var IS_BINDING = __dependency7__.IS_BINDING; + var Mixin = __dependency7__.Mixin; + var required = __dependency7__.required; + var indexOf = __dependency8__.indexOf; + var EmberError = __dependency9__["default"]; + var o_defineProperty = __dependency4__.defineProperty; + var keys = __dependency10__["default"]; + var ActionHandler = __dependency11__["default"]; + var defineProperty = __dependency12__.defineProperty; + var Binding = __dependency13__.Binding; + var ComputedProperty = __dependency14__.ComputedProperty; + var computed = __dependency14__.computed; + var InjectedProperty = __dependency15__["default"]; + var run = __dependency16__["default"]; + var destroy = __dependency17__.destroy; var K = __dependency1__.K; - var hasPropertyAccessors = __dependency5__.hasPropertyAccessors; + var hasPropertyAccessors = __dependency4__.hasPropertyAccessors; var schedule = run.schedule; var applyMixin = Mixin._apply; @@ -33707,8 +33843,6 @@ enifed("ember-runtime/system/core_object", for (var j = 0, ll = keyNames.length; j < ll; j++) { var keyName = keyNames[j]; - if (!properties.hasOwnProperty(keyName)) { continue; } - var value = properties[keyName]; if (IS_BINDING.test(keyName)) { @@ -33724,7 +33858,9 @@ enifed("ember-runtime/system/core_object", var desc = m.descs[keyName]; - if (concatenatedProperties && indexOf(concatenatedProperties, keyName) >= 0) { + if (concatenatedProperties && + concatenatedProperties.length > 0 && + indexOf(concatenatedProperties, keyName) >= 0) { var baseValue = this[keyName]; if (baseValue) { @@ -33782,7 +33918,6 @@ enifed("ember-runtime/system/core_object", if (!wasApplied) { wasApplied = true; Class.PrototypeMixin.applyPartial(Class.prototype); - rewatch(Class.prototype); } return this.prototype; @@ -34035,7 +34170,7 @@ enifed("ember-runtime/system/core_object", CoreObject.__super__ = null; - var ClassMixin = Mixin.create({ + var ClassMixinProps = { ClassMixin: required(), @@ -34379,7 +34514,7 @@ enifed("ember-runtime/system/core_object", return desc._meta || {}; }, - _computedProperties: Ember.computed(function() { + _computedProperties: computed(function() { hasCachedComputedProperties = true; var proto = this.proto(); var descs = meta(proto).descs; @@ -34419,7 +34554,10 @@ enifed("ember-runtime/system/core_object", callback.call(binding || this, property.name, property.meta || empty); } } - }); + }; + + + var ClassMixin = Mixin.create(ClassMixinProps); ClassMixin.ownerConstructor = CoreObject; @@ -34447,13 +34585,12 @@ enifed("ember-runtime/system/core_object", __exports__["default"] = CoreObject; }); enifed("ember-runtime/system/deferred", - ["ember-metal/core","ember-runtime/mixins/deferred","ember-metal/property_get","ember-runtime/system/object","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) { + ["ember-metal/core","ember-runtime/mixins/deferred","ember-runtime/system/object","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; var DeferredMixin = __dependency2__["default"]; - var get = __dependency3__.get; - var EmberObject = __dependency4__["default"]; + var EmberObject = __dependency3__["default"]; var Deferred = EmberObject.extend(DeferredMixin, { init: function() { @@ -34472,8 +34609,8 @@ enifed("ember-runtime/system/deferred", __exports__["default"] = Deferred; }); enifed("ember-runtime/system/each_proxy", - ["ember-metal/core","ember-metal/property_get","ember-metal/property_set","ember-metal/utils","ember-metal/enumerable_utils","ember-metal/array","ember-runtime/mixins/array","ember-runtime/system/object","ember-metal/computed","ember-metal/observer","ember-metal/events","ember-metal/properties","ember-metal/property_events","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __exports__) { + ["ember-metal/core","ember-metal/property_get","ember-metal/utils","ember-metal/enumerable_utils","ember-metal/array","ember-runtime/mixins/array","ember-runtime/system/object","ember-metal/computed","ember-metal/observer","ember-metal/events","ember-metal/properties","ember-metal/property_events","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __exports__) { "use strict"; /** @module ember @@ -34484,26 +34621,25 @@ enifed("ember-runtime/system/each_proxy", // Ember.assert var get = __dependency2__.get; - var set = __dependency3__.set; - var guidFor = __dependency4__.guidFor; - var forEach = __dependency5__.forEach; - var indexOf = __dependency6__.indexOf; - var EmberArray = __dependency7__["default"]; + var guidFor = __dependency3__.guidFor; + var forEach = __dependency4__.forEach; + var indexOf = __dependency5__.indexOf; + var EmberArray = __dependency6__["default"]; // ES6TODO: WAT? Circular dep? - var EmberObject = __dependency8__["default"]; - var computed = __dependency9__.computed; - var addObserver = __dependency10__.addObserver; - var addBeforeObserver = __dependency10__.addBeforeObserver; - var removeBeforeObserver = __dependency10__.removeBeforeObserver; - var removeObserver = __dependency10__.removeObserver; - var typeOf = __dependency4__.typeOf; - var watchedEvents = __dependency11__.watchedEvents; - var defineProperty = __dependency12__.defineProperty; - var beginPropertyChanges = __dependency13__.beginPropertyChanges; - var propertyDidChange = __dependency13__.propertyDidChange; - var propertyWillChange = __dependency13__.propertyWillChange; - var endPropertyChanges = __dependency13__.endPropertyChanges; - var changeProperties = __dependency13__.changeProperties; + var EmberObject = __dependency7__["default"]; + var computed = __dependency8__.computed; + var addObserver = __dependency9__.addObserver; + var addBeforeObserver = __dependency9__.addBeforeObserver; + var removeBeforeObserver = __dependency9__.removeBeforeObserver; + var removeObserver = __dependency9__.removeObserver; + var typeOf = __dependency3__.typeOf; + var watchedEvents = __dependency10__.watchedEvents; + var defineProperty = __dependency11__.defineProperty; + var beginPropertyChanges = __dependency12__.beginPropertyChanges; + var propertyDidChange = __dependency12__.propertyDidChange; + var propertyWillChange = __dependency12__.propertyWillChange; + var endPropertyChanges = __dependency12__.endPropertyChanges; + var changeProperties = __dependency12__.changeProperties; var EachArray = EmberObject.extend(EmberArray, { @@ -34915,7 +35051,7 @@ enifed("ember-runtime/system/namespace", function findNamespaces() { var lookup = Ember.lookup; - var obj, isNamespace; + var obj; if (Namespace.PROCESSED) { return; } @@ -35002,8 +35138,8 @@ enifed("ember-runtime/system/namespace", __exports__["default"] = Namespace; }); enifed("ember-runtime/system/native_array", - ["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__) { + ["ember-metal/core","ember-metal/property_get","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__, __exports__) { "use strict"; /** @module ember @@ -35014,18 +35150,17 @@ enifed("ember-runtime/system/native_array", // Ember.EXTEND_PROTOTYPES var get = __dependency2__.get; - var set = __dependency3__.set; - var replace = __dependency4__._replace; - var forEach = __dependency4__.forEach; - var Mixin = __dependency5__.Mixin; - 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"]; + var replace = __dependency3__._replace; + var forEach = __dependency3__.forEach; + var Mixin = __dependency4__.Mixin; + var indexOf = __dependency5__.indexOf; + var lastIndexOf = __dependency5__.lastIndexOf; + 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"]; // Add Ember.Array to Array.prototype. Remove methods with native // implementations and supply some more optimized versions of generic methods @@ -35180,16 +35315,19 @@ enifed("ember-runtime/system/native_array", __exports__["default"] = NativeArray; }); enifed("ember-runtime/system/object", - ["ember-runtime/system/core_object","ember-runtime/mixins/observable","exports"], - function(__dependency1__, __dependency2__, __exports__) { + ["ember-metal/core","ember-runtime/system/core_object","ember-runtime/mixins/observable","ember-runtime/inject","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) { "use strict"; /** @module ember @submodule ember-runtime */ - var CoreObject = __dependency1__["default"]; - var Observable = __dependency2__["default"]; + var Ember = __dependency1__["default"]; + // Ember.assert + var CoreObject = __dependency2__["default"]; + var Observable = __dependency3__["default"]; + var validatePropertyInjections = __dependency4__.validatePropertyInjections; /** `Ember.Object` is the main base class for all Ember objects. It is a subclass @@ -35206,6 +35344,12 @@ enifed("ember-runtime/system/object", return "Ember.Object"; }; + function injectedPropertyAssertion(props) { + // Injection validations are a debugging aid only, so ensure that they are + // not performed in production builds by invoking from an assertion + } + + __exports__["default"] = EmberObject; }); enifed("ember-runtime/system/object_proxy", @@ -35286,6 +35430,18 @@ enifed("ember-runtime/system/object_proxy", __exports__["default"] = EmberObject.extend(_ProxyMixin); }); +enifed("ember-runtime/system/service", + ["ember-runtime/system/object","ember-runtime/inject","exports"], + function(__dependency1__, __dependency2__, __exports__) { + "use strict"; + var Object = __dependency1__["default"]; + var createInjectionHelper = __dependency2__.createInjectionHelper; + + var Service; + + + __exports__["default"] = Service; + }); enifed("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__) { @@ -35300,7 +35456,7 @@ enifed("ember-runtime/system/set", var get = __dependency2__.get; var set = __dependency3__.set; var guidFor = __dependency4__.guidFor; - var isNone = __dependency5__.isNone; + var isNone = __dependency5__["default"]; var fmt = __dependency6__.fmt; var CoreObject = __dependency7__["default"]; var MutableEnumerable = __dependency8__["default"]; @@ -35410,6 +35566,7 @@ enifed("ember-runtime/system/set", @uses Ember.Copyable @uses Ember.Freezable @since Ember 0.9 + @deprecated */ __exports__["default"] = CoreObject.extend(MutableEnumerable, Copyable, Freezable, { @@ -36073,12 +36230,11 @@ enifed("ember-runtime/system/string", __exports__.capitalize = capitalize; }); enifed("ember-runtime/system/subarray", - ["ember-metal/property_get","ember-metal/error","ember-metal/enumerable_utils","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __exports__) { + ["ember-metal/error","ember-metal/enumerable_utils","exports"], + function(__dependency1__, __dependency2__, __exports__) { "use strict"; - var get = __dependency1__.get; - var EmberError = __dependency2__["default"]; - var EnumerableUtils = __dependency3__["default"]; + var EmberError = __dependency1__["default"]; + var EnumerableUtils = __dependency2__["default"]; var RETAIN = 'r'; var FILTER = 'f'; @@ -36310,7 +36466,7 @@ enifed("ember-runtime/system/tracked_array", var arrayOperation = match.operation; var arrayOperationIndex = match.index; var arrayOperationRangeStart = match.rangeStart; - var composeIndex, splitIndex, splitItems, splitArrayOperation, newArrayOperation; + var composeIndex, newArrayOperation; newArrayOperation = new ArrayOperation(INSERT, count, newItems); @@ -36343,7 +36499,6 @@ enifed("ember-runtime/system/tracked_array", if (count < 1) { return; } var match = this._findArrayOperation(index); - var arrayOperation = match.operation; var arrayOperationIndex = match.index; var arrayOperationRangeStart = match.rangeStart; var newArrayOperation, composeIndex; @@ -36603,6 +36758,8 @@ enifed("ember-views", var Ember = __dependency1__["default"]; var jQuery = __dependency2__["default"]; var isSimpleClick = __dependency3__.isSimpleClick; + var getViewClientRects = __dependency3__.getViewClientRects; + var getViewBoundingClientRect = __dependency3__.getViewBoundingClientRect; var RenderBuffer = __dependency4__["default"]; // for the side effect of extending Ember.run.queues var cloneStates = __dependency6__.cloneStates; @@ -36633,6 +36790,8 @@ enifed("ember-views", var ViewUtils = Ember.ViewUtils = {}; ViewUtils.isSimpleClick = isSimpleClick; + ViewUtils.getViewClientRects = getViewClientRects; + ViewUtils.getViewBoundingClientRect = getViewBoundingClientRect; Ember.CoreView = CoreView; Ember.View = View; @@ -36715,15 +36874,12 @@ enifed("ember-views/mixins/component_template_deprecation", }); }); enifed("ember-views/mixins/view_target_action_support", - ["ember-metal/mixin","ember-runtime/mixins/target_action_support","ember-metal/computed","exports"], + ["ember-metal/mixin","ember-runtime/mixins/target_action_support","ember-metal/alias","exports"], function(__dependency1__, __dependency2__, __dependency3__, __exports__) { "use strict"; var Mixin = __dependency1__.Mixin; var TargetActionSupport = __dependency2__["default"]; - - // ES6TODO: computed should have its own export path so you can do import {defaultTo} from computed - var computed = __dependency3__.computed; - var alias = computed.alias; + var alias = __dependency3__["default"]; /** `Ember.ViewTargetActionSupport` is a mixin that can be included in a @@ -36777,6 +36933,205 @@ enifed("ember-views/mixins/view_target_action_support", actionContext: alias('context') }); }); +enifed("ember-views/streams/context_stream", + ["ember-metal/core","ember-metal/merge","ember-metal/platform","ember-metal/path_cache","ember-metal/streams/stream","ember-metal/streams/simple","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __exports__) { + "use strict"; + var Ember = __dependency1__["default"]; + + var merge = __dependency2__["default"]; + var create = __dependency3__.create; + var isGlobal = __dependency4__.isGlobal; + var Stream = __dependency5__["default"]; + var SimpleStream = __dependency6__["default"]; + + function ContextStream(view) { + this.view = view; + } + + ContextStream.prototype = create(Stream.prototype); + + merge(ContextStream.prototype, { + value: function() {}, + + _makeChildStream: function(key, _fullPath) { + var stream; + + if (key === '' || key === 'this') { + stream = this.view._baseContext; + } else if (isGlobal(key) && Ember.lookup[key]) { + stream = new SimpleStream(Ember.lookup[key]); + stream._isGlobal = true; + } else if (key in this.view._keywords) { + stream = new SimpleStream(this.view._keywords[key]); + } else { + stream = new SimpleStream(this.view._baseContext.get(key)); + } + + stream._isRoot = true; + + if (key === 'controller') { + stream._isController = true; + } + + return stream; + } + }); + + __exports__["default"] = ContextStream; + }); +enifed("ember-views/streams/key_stream", + ["ember-metal/core","ember-metal/merge","ember-metal/platform","ember-metal/property_get","ember-metal/property_set","ember-metal/observer","ember-metal/streams/stream","ember-metal/streams/read","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) { + "use strict"; + var Ember = __dependency1__["default"]; + + var merge = __dependency2__["default"]; + var create = __dependency3__.create; + var get = __dependency4__.get; + var set = __dependency5__.set; + var addObserver = __dependency6__.addObserver; + var removeObserver = __dependency6__.removeObserver; + var Stream = __dependency7__["default"]; + var read = __dependency8__.read; + + function KeyStream(source, key) { + + this.source = source; + this.obj = undefined; + this.key = key; + + if (source && source.isStream) { + source.subscribe(this._didChange, this); + } + } + + KeyStream.prototype = create(Stream.prototype); + + merge(KeyStream.prototype, { + valueFn: function() { + var prevObj = this.obj; + var nextObj = read(this.source); + + if (nextObj !== prevObj) { + if (prevObj && typeof prevObj === 'object') { + removeObserver(prevObj, this.key, this, this._didChange); + } + + if (nextObj && typeof nextObj === 'object') { + addObserver(nextObj, this.key, this, this._didChange); + } + + this.obj = nextObj; + } + + if (nextObj) { + return get(nextObj, this.key); + } + }, + + setValue: function(value) { + if (this.obj) { + set(this.obj, this.key, value); + } + }, + + setSource: function(nextSource) { + + var prevSource = this.source; + + if (nextSource !== prevSource) { + if (prevSource && prevSource.isStream) { + prevSource.unsubscribe(this._didChange, this); + } + + if (nextSource && nextSource.isStream) { + nextSource.subscribe(this._didChange, this); + } + + this.source = nextSource; + this.notify(); + } + }, + + _didChange: function() { + this.notify(); + }, + + destroy: function() { + if (this.source && this.source.isStream) { + this.source.unsubscribe(this._didChange, this); + } + + if (this.obj && typeof this.obj === 'object') { + removeObserver(this.obj, this.key, this, this._didChange); + } + + this.source = undefined; + this.obj = undefined; + + Stream.prototype.destroy.call(this); + } + }); + + __exports__["default"] = KeyStream; + + // The transpiler does not resolve cycles, so we export + // the `_makeChildStream` method onto `Stream` here. + + Stream.prototype._makeChildStream = function(key) { + return new KeyStream(this, key); + }; + }); +enifed("ember-views/streams/read", + ["ember-metal/core","ember-metal/property_get","ember-metal/path_cache","ember-runtime/system/string","ember-metal/streams/read","ember-views/views/view","ember-runtime/mixins/controller","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) { + "use strict"; + var Ember = __dependency1__["default"]; + var get = __dependency2__.get; + var isGlobal = __dependency3__.isGlobal; + var fmt = __dependency4__.fmt; + var read = __dependency5__.read; + var View = __dependency6__["default"]; + var ControllerMixin = __dependency7__["default"]; + + function readViewFactory(object, container) { + var value = read(object); + var viewClass; + + if (typeof value === 'string') { + if (isGlobal(value)) { + viewClass = get(null, value); + } else { + viewClass = container.lookupFactory('view:'+value); + } + } else { + viewClass = value; + } + + + return viewClass; + } + + __exports__.readViewFactory = readViewFactory;function readUnwrappedModel(object) { + if (object && object.isStream) { + var result = object.value(); + + // If the path is exactly `controller` then we don't unwrap it. + if (!object._isController) { + while (ControllerMixin.detect(result)) { + result = get(result, 'model'); + } + } + + return result; + } else { + return object; + } + } + + __exports__.readUnwrappedModel = readUnwrappedModel; + }); enifed("ember-views/system/action_manager", ["exports"], function(__exports__) { @@ -36812,7 +37167,7 @@ enifed("ember-views/system/event_dispatcher", var get = __dependency2__.get; var set = __dependency3__.set; - var isNone = __dependency4__.isNone; + var isNone = __dependency4__["default"]; var run = __dependency5__["default"]; var typeOf = __dependency6__.typeOf; var fmt = __dependency7__.fmt; @@ -37033,7 +37388,7 @@ enifed("ember-views/system/event_dispatcher", }, _bubbleEvent: function(view, evt, eventName) { - return run(view, view.handleEvent, eventName, evt); + return run.join(view, view.handleEvent, eventName, evt); }, destroy: function() { @@ -37061,20 +37416,18 @@ enifed("ember-views/system/ext", // Add a new named queue for rendering views that happens // after bindings have synced, and a queue for scheduling actions // that that should occur after view rendering. - var queues = run.queues; run._addQueue('render', 'actions'); run._addQueue('afterRender', 'render'); }); enifed("ember-views/system/jquery", - ["ember-metal/core","ember-runtime/system/string","ember-metal/enumerable_utils","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __exports__) { + ["ember-metal/core","ember-metal/enumerable_utils","exports"], + function(__dependency1__, __dependency2__, __exports__) { "use strict"; var Ember = __dependency1__["default"]; // Ember.assert - var w = __dependency2__.w; // ES6TODO: the functions on EnumerableUtils need their own exports - var forEach = __dependency3__.forEach; + var forEach = __dependency2__.forEach; /** Ember Views @@ -37097,12 +37450,22 @@ enifed("ember-views/system/jquery", */ if (jQuery) { // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dndevents - var dragEvents = w('dragstart drag dragenter dragleave dragover drop dragend'); + var dragEvents = [ + 'dragstart', + 'drag', + 'dragenter', + 'dragleave', + 'dragover', + 'drop', + 'dragend' + ]; // Copies the `dataTransfer` property from a browser event object onto the // jQuery event object for the specified events forEach(dragEvents, function(eventName) { - jQuery.event.fixHooks[eventName] = { props: ['dataTransfer'] }; + jQuery.event.fixHooks[eventName] = { + props: ['dataTransfer'] + }; }); } @@ -37179,10 +37542,6 @@ enifed("ember-views/system/render_buffer", this.seen[string] = true; this.list.push(string); - }, - - toDOM: function() { - return this.list.join(" "); } }; @@ -37710,25 +38069,12 @@ enifed("ember-views/system/renderer", function EmberRenderer() { this.buffer = renderBuffer(); - Renderer.call(this); + this._super$constructor(); } + EmberRenderer.prototype = create(Renderer.prototype); EmberRenderer.prototype.constructor = EmberRenderer; - - var BAD_TAG_NAME_TEST_REGEXP = /[^a-zA-Z0-9\-]/; - var BAD_TAG_NAME_REPLACE_REGEXP = /[^a-zA-Z0-9\-]/g; - - function stripTagName(tagName) { - if (!tagName) { - return tagName; - } - - if (!BAD_TAG_NAME_TEST_REGEXP.test(tagName)) { - return tagName; - } - - return tagName.replace(BAD_TAG_NAME_REPLACE_REGEXP, ''); - } + EmberRenderer.prototype._super$constructor = Renderer; EmberRenderer.prototype.scheduleRender = function EmberRenderer_scheduleRender(ctx, fn) { @@ -37740,25 +38086,6 @@ enifed("ember-views/system/renderer", run.cancel(id); }; - EmberRenderer.prototype.createChildViewsMorph = - function EmberRenderer_createChildViewsMorph(view, _element) { - if (view.createChildViewsMorph) { - return view.createChildViewsMorph(_element); - } - var element = _element; - if (view.tagName === '') { - if (view._morph) { - view._childViewsMorph = view._morph; - } else { - element = document.createDocumentFragment(); - view._childViewsMorph = this._dom.appendMorph(element); - } - } else { - view._childViewsMorph = this._dom.createMorph(element, element.lastChild, null); - } - return element; - }; - EmberRenderer.prototype.createElement = function EmberRenderer_createElement(view, contextualElement) { // If this is the top-most view, start a new buffer. Otherwise, @@ -37798,10 +38125,6 @@ enifed("ember-views/system/renderer", var element = buffer.element(); - if (view.isContainer) { - this.createChildViewsMorph(view, element); - } - view.buffer = null; if (element && element.nodeType === 1) { // We have hooks, we shouldn't make element observable @@ -37882,11 +38205,55 @@ enifed("ember-views/system/utils", return !modifier && !secondaryClick; } - __exports__.isSimpleClick = isSimpleClick; + __exports__.isSimpleClick = isSimpleClick;/** + @private + @method getViewRange + @param {Ember.View} view + */ + function getViewRange(view) { + var range = document.createRange(); + range.setStartAfter(view._morph.start); + range.setEndBefore(view._morph.end); + return range; + } + + /** + `getViewClientRects` provides information about the position of the border + box edges of a view relative to the viewport. + + It is only intended to be used by development tools like the Ember Inpsector + and may not work on older browsers. + + @private + @method getViewClientRects + @param {Ember.View} view + */ + function getViewClientRects(view) { + var range = getViewRange(view); + return range.getClientRects(); + } + + __exports__.getViewClientRects = getViewClientRects;/** + `getViewBoundingClientRect` provides information about the position of the + bounding border box edges of a view relative to the viewport. + + It is only intended to be used by development tools like the Ember Inpsector + and may not work on older browsers. + + @private + @method getViewBoundingClientRect + @param {Ember.View} view + */ + function getViewBoundingClientRect(view) { + var range = getViewRange(view); + return range.getBoundingClientRect(); + } + + __exports__.getViewBoundingClientRect = getViewBoundingClientRect; }); enifed("ember-views/views/collection_view", - ["ember-metal/core","ember-metal/platform","ember-metal/binding","ember-metal/merge","ember-metal/property_get","ember-metal/property_set","ember-runtime/system/string","ember-views/views/container_view","ember-views/views/core_view","ember-views/views/view","ember-metal/mixin","ember-handlebars/ext","ember-runtime/mixins/array","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __exports__) { + ["ember-metal/core","ember-metal/binding","ember-metal/property_get","ember-metal/property_set","ember-runtime/system/string","ember-views/views/container_view","ember-views/views/core_view","ember-views/views/view","ember-metal/mixin","ember-views/streams/read","ember-runtime/mixins/array","exports"], + function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __exports__) { "use strict"; /** @@ -37896,19 +38263,17 @@ enifed("ember-views/views/collection_view", var Ember = __dependency1__["default"]; // Ember.assert - var create = __dependency2__.create; - var isGlobalPath = __dependency3__.isGlobalPath; - var merge = __dependency4__["default"]; - var get = __dependency5__.get; - var set = __dependency6__.set; - var fmt = __dependency7__.fmt; - var ContainerView = __dependency8__["default"]; - var CoreView = __dependency9__["default"]; - var View = __dependency10__["default"]; - var observer = __dependency11__.observer; - var beforeObserver = __dependency11__.beforeObserver; - var handlebarsGetView = __dependency12__.handlebarsGetView; - var EmberArray = __dependency13__["default"]; + var isGlobalPath = __dependency2__.isGlobalPath; + var get = __dependency3__.get; + var set = __dependency4__.set; + var fmt = __dependency5__.fmt; + var ContainerView = __dependency6__["default"]; + var CoreView = __dependency7__["default"]; + var View = __dependency8__["default"]; + var observer = __dependency9__.observer; + var beforeObserver = __dependency9__.beforeObserver; + var readViewFactory = __dependency10__.readViewFactory; + var EmberArray = __dependency11__["default"]; /** `Ember.CollectionView` is an `Ember.View` descendent responsible for managing @@ -38233,21 +38598,23 @@ enifed("ember-views/views/collection_view", */ arrayDidChange: function(content, start, removed, added) { var addedViews = []; - var view, item, idx, len, itemViewClass, emptyView; + var view, item, idx, len, itemViewClass, emptyView, itemViewProps; len = content ? get(content, 'length') : 0; if (len) { + itemViewProps = this._itemViewProps || {}; itemViewClass = get(this, 'itemViewClass'); - itemViewClass = handlebarsGetView(content, itemViewClass, this.container); + + itemViewClass = readViewFactory(itemViewClass, this.container); for (idx = start; idx < start+added; idx++) { item = content.objectAt(idx); - view = this.createChildView(itemViewClass, { - content: item, - contentIndex: idx - }); + itemViewProps.content = item; + itemViewProps.contentIndex = idx; + + view = this.createChildView(itemViewClass, itemViewProps); addedViews.push(view); } @@ -38261,6 +38628,7 @@ enifed("ember-views/views/collection_view", } emptyView = this.createChildView(emptyView); + addedViews.push(emptyView); set(this, 'emptyView', emptyView); @@ -38337,7 +38705,7 @@ enifed("ember-views/views/component", var get = __dependency5__.get; var set = __dependency6__.set; - var isNone = __dependency7__.isNone; + var isNone = __dependency7__["default"]; var computed = __dependency8__.computed; @@ -38443,7 +38811,6 @@ enifed("ember-views/views/component", init: function() { this._super(); - set(this, 'origContext', get(this, 'context')); set(this, 'context', this); set(this, 'controller', this); }, @@ -38490,12 +38857,8 @@ enifed("ember-views/views/component", */ templateName: null, - // during render, isolate keywords - cloneKeywords: function() { - return { - view: this, - controller: this - }; + _setupKeywords: function() { + this._keywords.view.setSource(this); }, _yield: function(context, options) { @@ -38510,9 +38873,9 @@ enifed("ember-views/views/component", tagName: '', _contextView: parentView, template: template, - context: options.data.insideGroup ? get(this, 'origContext') : get(parentView, 'context'), + context: get(parentView, 'context'), controller: get(parentView, 'controller'), - templateData: { keywords: parentView.cloneKeywords(), insideGroup: options.data.insideGroup } + templateData: { keywords: {} } }); } }, @@ -38628,14 +38991,36 @@ enifed("ember-views/views/component", action: actionName, actionContext: contexts }); + }, + + send: function(actionName) { + var args = [].slice.call(arguments, 1); + var target; + var hasAction = this._actions && this._actions[actionName]; + + if (hasAction) { + if (this._actions[actionName].apply(this, args) === true) { + // handler returned true, so this action will bubble + } else { + return; + } + } + + if (target = get(this, 'target')) { + target.send.apply(target, arguments); + } else { + if (!hasAction) { + throw new Error(Ember.inspect(this) + ' had no action handler for: ' + actionName); + } + } } }); __exports__["default"] = Component; }); enifed("ember-views/views/container_view", - ["ember-metal/core","ember-metal/merge","ember-runtime/mixins/mutable_array","ember-metal/property_get","ember-metal/property_set","ember-views/views/view","ember-views/views/states","ember-metal/error","ember-metal/enumerable_utils","ember-metal/computed","ember-metal/run_loop","ember-metal/properties","ember-views/system/render_buffer","ember-metal/mixin","ember-runtime/system/native_array","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __dependency14__, __dependency15__, __exports__) { + ["ember-metal/core","ember-metal/merge","ember-runtime/mixins/mutable_array","ember-metal/property_get","ember-metal/property_set","ember-views/views/view","ember-views/views/states","ember-metal/error","ember-metal/enumerable_utils","ember-metal/computed","ember-metal/run_loop","ember-metal/properties","ember-metal/mixin","ember-runtime/system/native_array","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, Ember.K @@ -38657,10 +39042,9 @@ enifed("ember-views/views/container_view", var computed = __dependency10__.computed; var run = __dependency11__["default"]; var defineProperty = __dependency12__.defineProperty; - var renderBuffer = __dependency13__["default"]; - var observer = __dependency14__.observer; - var beforeObserver = __dependency14__.beforeObserver; - var emberA = __dependency15__.A; + var observer = __dependency13__.observer; + var beforeObserver = __dependency13__.beforeObserver; + var emberA = __dependency14__.A; /** @module ember @@ -38820,7 +39204,6 @@ enifed("ember-views/views/container_view", @extends Ember.View */ var ContainerView = View.extend(MutableArray, { - isContainer: true, _states: states, willWatchProperty: function(prop){ @@ -38830,7 +39213,7 @@ enifed("ember-views/views/container_view", this._super(); var childViews = get(this, 'childViews'); - + // redefine view's childViews property that was obliterated defineProperty(this, 'childViews', View.childViewsProperty); @@ -38894,6 +39277,18 @@ enifed("ember-views/views/container_view", @param {Ember.RenderBuffer} buffer the buffer to render to */ render: function(buffer) { + var element = buffer.element(); + var dom = buffer.dom; + + if (this.tagName === '') { + element = dom.createDocumentFragment(); + buffer._element = element; + this._childViewsMorph = dom.appendMorph(element, this._morph.contextualElement); + } else { + this._childViewsMorph = dom.createMorph(element, element.lastChild, null); + } + + return element; }, instrumentName: 'container', @@ -39002,7 +39397,9 @@ enifed("ember-views/views/container_view", merge(states.hasElement, { childViewsWillChange: function(view, views, start, removed) { for (var i=start; i"'`]/; function escapeChar(chr) { - return escape[chr] || "&"; + return escape[chr]; } - function extend(obj, value) { - for(var key in value) { - if(Object.prototype.hasOwnProperty.call(value, key)) { - obj[key] = value[key]; + function extend(obj /* , ...source */) { + for (var i = 1; i < arguments.length; i++) { + for (var key in arguments[i]) { + if (Object.prototype.hasOwnProperty.call(arguments[i], key)) { + obj[key] = arguments[i][key]; + } } } + + return obj; } __exports__.extend = extend;var toString = Object.prototype.toString; @@ -82,6 +94,7 @@ var __module3__ = (function(__dependency1__) { return typeof value === 'function'; }; // fallback for older versions of Chrome and Safari + /* istanbul ignore next */ if (isFunction(/x/)) { isFunction = function(value) { return typeof value === 'function' && toString.call(value) === '[object Function]'; @@ -89,6 +102,7 @@ var __module3__ = (function(__dependency1__) { } var isFunction; __exports__.isFunction = isFunction; + /* istanbul ignore next */ var isArray = Array.isArray || function(value) { return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false; }; @@ -98,8 +112,10 @@ var __module3__ = (function(__dependency1__) { // don't escape SafeStrings, since they're already safe if (string instanceof SafeString) { return string.toString(); - } else if (!string && string !== 0) { + } else if (string == null) { return ""; + } else if (!string) { + return string + ''; } // Force a string conversion as this will be done by the append regardless and @@ -121,7 +137,11 @@ var __module3__ = (function(__dependency1__) { } } - __exports__.isEmpty = isEmpty; + __exports__.isEmpty = isEmpty;function appendContextPath(contextPath, id) { + return (contextPath ? contextPath + '.' : '') + id; + } + + __exports__.appendContextPath = appendContextPath; return __exports__; })(__module4__); @@ -132,13 +152,25 @@ var __module5__ = (function() { var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack']; - function Exception(/* message */) { - var tmp = Error.prototype.constructor.apply(this, arguments); + function Exception(message, node) { + var line; + if (node && node.firstLine) { + line = node.firstLine; + + message += ' - ' + line + ':' + node.firstColumn; + } + + var tmp = Error.prototype.constructor.call(this, message); // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work. for (var idx = 0; idx < errorProps.length; idx++) { this[errorProps[idx]] = tmp[errorProps[idx]]; } + + if (line) { + this.lineNumber = line; + this.column = node.firstColumn; + } } Exception.prototype = new Error(); @@ -154,14 +186,16 @@ var __module2__ = (function(__dependency1__, __dependency2__) { var Utils = __dependency1__; var Exception = __dependency2__; - var VERSION = "1.2.1"; - __exports__.VERSION = VERSION;var COMPILER_REVISION = 4; + var VERSION = "2.0.0"; + __exports__.VERSION = VERSION;var COMPILER_REVISION = 6; __exports__.COMPILER_REVISION = COMPILER_REVISION; var REVISION_CHANGES = { 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it 2: '== 1.0.0-rc.3', 3: '== 1.0.0-rc.4', - 4: '>= 1.0.0' + 4: '== 1.x.x', + 5: '== 2.0.0-alpha.x', + 6: '>= 2.0.0-beta.1' }; __exports__.REVISION_CHANGES = REVISION_CHANGES; var isArray = Utils.isArray, @@ -182,38 +216,44 @@ var __module2__ = (function(__dependency1__, __dependency2__) { logger: logger, log: log, - registerHelper: function(name, fn, inverse) { + registerHelper: function(name, fn) { if (toString.call(name) === objectType) { - if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); } + if (fn) { throw new Exception('Arg not supported with multiple helpers'); } Utils.extend(this.helpers, name); } else { - if (inverse) { fn.not = inverse; } this.helpers[name] = fn; } }, + unregisterHelper: function(name) { + delete this.helpers[name]; + }, - registerPartial: function(name, str) { + registerPartial: function(name, partial) { if (toString.call(name) === objectType) { Utils.extend(this.partials, name); } else { - this.partials[name] = str; + this.partials[name] = partial; } + }, + unregisterPartial: function(name) { + delete this.partials[name]; } }; function registerDefaultHelpers(instance) { - instance.registerHelper('helperMissing', function(arg) { - if(arguments.length === 2) { + instance.registerHelper('helperMissing', function(/* [args, ]options */) { + if(arguments.length === 1) { + // A missing field in a {{foo}} constuct. return undefined; } else { - throw new Error("Missing helper: '" + arg + "'"); + // Someone is actually trying to call something, blow up. + throw new Exception("Missing helper: '" + arguments[arguments.length-1].name + "'"); } }); instance.registerHelper('blockHelperMissing', function(context, options) { - var inverse = options.inverse || function() {}, fn = options.fn; - - if (isFunction(context)) { context = context.call(this); } + var inverse = options.inverse, + fn = options.fn; if(context === true) { return fn(this); @@ -221,19 +261,38 @@ var __module2__ = (function(__dependency1__, __dependency2__) { return inverse(this); } else if (isArray(context)) { if(context.length > 0) { + if (options.ids) { + options.ids = [options.name]; + } + return instance.helpers.each(context, options); } else { return inverse(this); } } else { - return fn(context); + if (options.data && options.ids) { + var data = createFrame(options.data); + data.contextPath = Utils.appendContextPath(options.data.contextPath, options.name); + options = {data: data}; + } + + return fn(context, options); } }); instance.registerHelper('each', function(context, options) { + if (!options) { + throw new Exception('Must pass iterator to #each'); + } + var fn = options.fn, inverse = options.inverse; var i = 0, ret = "", data; + var contextPath; + if (options.data && options.ids) { + contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.'; + } + if (isFunction(context)) { context = context.call(this); } if (options.data) { @@ -247,16 +306,24 @@ var __module2__ = (function(__dependency1__, __dependency2__) { data.index = i; data.first = (i === 0); data.last = (i === (context.length-1)); + + if (contextPath) { + data.contextPath = contextPath + i; + } } ret = ret + fn(context[i], { data: data }); } } else { for(var key in context) { if(context.hasOwnProperty(key)) { - if(data) { - data.key = key; + if(data) { + data.key = key; data.index = i; data.first = (i === 0); + + if (contextPath) { + data.contextPath = contextPath + key; + } } ret = ret + fn(context[key], {data: data}); i++; @@ -292,12 +359,28 @@ var __module2__ = (function(__dependency1__, __dependency2__) { instance.registerHelper('with', function(context, options) { if (isFunction(context)) { context = context.call(this); } - if (!Utils.isEmpty(context)) return options.fn(context); + var fn = options.fn; + + if (!Utils.isEmpty(context)) { + if (options.data && options.ids) { + var data = createFrame(options.data); + data.contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]); + options = {data:data}; + } + + return fn(context, options); + } else { + return options.inverse(this); + } }); - instance.registerHelper('log', function(context, options) { + instance.registerHelper('log', function(message, options) { var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1; - instance.log(level, context); + instance.log(level, message); + }); + + instance.registerHelper('lookup', function(obj, field) { + return obj && obj[field]; }); } @@ -312,22 +395,22 @@ var __module2__ = (function(__dependency1__, __dependency2__) { level: 3, // can be overridden in the host environment - log: function(level, obj) { + log: function(level, message) { if (logger.level <= level) { var method = logger.methodMap[level]; if (typeof console !== 'undefined' && console[method]) { - console[method].call(console, obj); + console[method].call(console, message); } } } }; __exports__.logger = logger; - function log(level, obj) { logger.log(level, obj); } - - __exports__.log = log;var createFrame = function(object) { - var obj = {}; - Utils.extend(obj, object); - return obj; + var log = logger.log; + __exports__.log = log; + var createFrame = function(object) { + var frame = Utils.extend({}, object); + frame._parent = object; + return frame; }; __exports__.createFrame = createFrame; return __exports__; @@ -341,6 +424,7 @@ var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) { var Exception = __dependency2__; var COMPILER_REVISION = __dependency3__.COMPILER_REVISION; var REVISION_CHANGES = __dependency3__.REVISION_CHANGES; + var createFrame = __dependency3__.createFrame; function checkRevision(compilerInfo) { var compilerRevision = compilerInfo && compilerInfo[0] || 1, @@ -350,11 +434,11 @@ var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) { if (compilerRevision < currentRevision) { var runtimeVersions = REVISION_CHANGES[currentRevision], compilerVersions = REVISION_CHANGES[compilerRevision]; - throw new Error("Template was precompiled with an older version of Handlebars than the current runtime. "+ + throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+ "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+")."); } else { // Use the embedded version info since the runtime doesn't know about this revision yet - throw new Error("Template was precompiled with a newer version of Handlebars than the current runtime. "+ + throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+ "Please update your runtime to a newer version ("+compilerInfo[1]+")."); } } @@ -363,20 +447,43 @@ var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) { __exports__.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial function template(templateSpec, env) { + /* istanbul ignore next */ if (!env) { - throw new Error("No environment passed to template"); + throw new Exception("No environment passed to template"); + } + if (!templateSpec || !templateSpec.main) { + throw new Exception('Unknown template object: ' + typeof templateSpec); } // Note: Using env.VM references rather than local var references throughout this section to allow // for external users to override these as psuedo-supported APIs. - var invokePartialWrapper = function(partial, name, context, helpers, partials, data) { - var result = env.VM.invokePartial.apply(this, arguments); - if (result != null) { return result; } + env.VM.checkRevision(templateSpec.compiler); - if (env.compile) { - var options = { helpers: helpers, partials: partials, data: data }; - partials[name] = env.compile(partial, { data: data !== undefined }, env); - return partials[name](context, options); + var invokePartialWrapper = function(partial, indent, name, context, hash, helpers, partials, data, depths) { + if (hash) { + context = Utils.extend({}, context, hash); + } + + var result = env.VM.invokePartial.call(this, partial, name, context, helpers, partials, data, depths); + + if (result == null && env.compile) { + var options = { helpers: helpers, partials: partials, data: data, depths: depths }; + partials[name] = env.compile(partial, { data: data !== undefined, compat: templateSpec.compat }, env); + result = partials[name](context, options); + } + if (result != null) { + if (indent) { + var lines = result.split('\n'); + for (var i = 0, l = lines.length; i < l; i++) { + if (!lines[i] && i + 1 === l) { + break; + } + + lines[i] = indent + lines[i]; + } + result = lines.join('\n'); + } + return result; } else { throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode"); } @@ -384,84 +491,110 @@ var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) { // Just add water var container = { + lookup: function(depths, name) { + var len = depths.length; + for (var i = 0; i < len; i++) { + if (depths[i] && depths[i][name] != null) { + return depths[i][name]; + } + } + }, + lambda: function(current, context) { + return typeof current === 'function' ? current.call(context) : current; + }, + escapeExpression: Utils.escapeExpression, invokePartial: invokePartialWrapper, + + fn: function(i) { + return templateSpec[i]; + }, + programs: [], - program: function(i, fn, data) { - var programWrapper = this.programs[i]; - if(data) { - programWrapper = program(i, fn, data); + program: function(i, data, depths) { + var programWrapper = this.programs[i], + fn = this.fn(i); + if (data || depths) { + programWrapper = program(this, i, fn, data, depths); } else if (!programWrapper) { - programWrapper = this.programs[i] = program(i, fn); + programWrapper = this.programs[i] = program(this, i, fn); } return programWrapper; }, + + data: function(data, depth) { + while (data && depth--) { + data = data._parent; + } + return data; + }, merge: function(param, common) { var ret = param || common; if (param && common && (param !== common)) { - ret = {}; - Utils.extend(ret, common); - Utils.extend(ret, param); + ret = Utils.extend({}, common, param); } + return ret; }, - programWithDepth: env.VM.programWithDepth, + noop: env.VM.noop, - compilerInfo: null + compilerInfo: templateSpec.compiler }; - return function(context, options) { + var ret = function(context, options) { options = options || {}; - var namespace = options.partial ? options : env, - helpers, - partials; + var data = options.data; - if (!options.partial) { - helpers = options.helpers; - partials = options.partials; + ret._setup(options); + if (!options.partial && templateSpec.useData) { + data = initData(context, data); } - var result = templateSpec.call( - container, - namespace, context, - helpers, - partials, - options.data); - - if (!options.partial) { - env.VM.checkRevision(container.compilerInfo); + var depths; + if (templateSpec.useDepths) { + depths = options.depths ? [context].concat(options.depths) : [context]; } - return result; + return templateSpec.main.call(container, context, container.helpers, container.partials, data, depths); }; + ret.isTop = true; + + ret._setup = function(options) { + if (!options.partial) { + container.helpers = container.merge(options.helpers, env.helpers); + + if (templateSpec.usePartial) { + container.partials = container.merge(options.partials, env.partials); + } + } else { + container.helpers = options.helpers; + container.partials = options.partials; + } + }; + + ret._child = function(i, data, depths) { + if (templateSpec.useDepths && !depths) { + throw new Exception('must pass parent depths'); + } + + return program(container, i, templateSpec[i], data, depths); + }; + return ret; } - __exports__.template = template;function programWithDepth(i, fn, data /*, $depth */) { - var args = Array.prototype.slice.call(arguments, 3); - + __exports__.template = template;function program(container, i, fn, data, depths) { var prog = function(context, options) { options = options || {}; - return fn.apply(this, [context, options.data || data].concat(args)); + return fn.call(container, context, container.helpers, container.partials, options.data || data, depths && [context].concat(depths)); }; prog.program = i; - prog.depth = args.length; + prog.depth = depths ? depths.length : 0; return prog; } - __exports__.programWithDepth = programWithDepth;function program(i, fn, data) { - var prog = function(context, options) { - options = options || {}; - - return fn(context, options.data || data); - }; - prog.program = i; - prog.depth = 0; - return prog; - } - - __exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data) { - var options = { partial: true, helpers: helpers, partials: partials, data: data }; + __exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data, depths) { + var options = { partial: true, helpers: helpers, partials: partials, data: data, depths: depths }; if(partial === undefined) { throw new Exception("The partial " + name + " could not be found"); @@ -472,7 +605,13 @@ var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) { __exports__.invokePartial = invokePartial;function noop() { return ""; } - __exports__.noop = noop; + __exports__.noop = noop;function initData(context, data) { + if (!data || !('root' in data)) { + data = data ? createFrame(data) : {}; + data.root = context; + } + return data; + } return __exports__; })(__module3__, __module5__, __module2__); @@ -498,6 +637,7 @@ var __module1__ = (function(__dependency1__, __dependency2__, __dependency3__, _ hb.SafeString = SafeString; hb.Exception = Exception; hb.Utils = Utils; + hb.escapeExpression = Utils.escapeExpression; hb.VM = runtime; hb.template = function(spec) { @@ -510,6 +650,8 @@ var __module1__ = (function(__dependency1__, __dependency2__, __dependency3__, _ var Handlebars = create(); Handlebars.create = create; + Handlebars['default'] = Handlebars; + __exports__ = Handlebars; return __exports__; })(__module2__, __module4__, __module5__, __module3__, __module6__); @@ -520,23 +662,25 @@ var __module7__ = (function(__dependency1__) { var __exports__; var Exception = __dependency1__; + function LocationInfo(locInfo) { + locInfo = locInfo || {}; + this.firstLine = locInfo.first_line; + this.firstColumn = locInfo.first_column; + this.lastColumn = locInfo.last_column; + this.lastLine = locInfo.last_line; + } + var AST = { - ProgramNode: function(statements, inverseStrip, inverse) { + ProgramNode: function(statements, strip, locInfo) { + LocationInfo.call(this, locInfo); this.type = "program"; this.statements = statements; - this.strip = {}; - - if(inverse) { - this.inverse = new AST.ProgramNode(inverse, inverseStrip); - this.strip.right = inverseStrip.left; - } else if (inverseStrip) { - this.strip.left = inverseStrip.right; - } + this.strip = strip; }, - MustacheNode: function(rawParams, hash, open, strip) { + MustacheNode: function(rawParams, hash, open, strip, locInfo) { + LocationInfo.call(this, locInfo); this.type = "mustache"; - this.hash = hash; this.strip = strip; // Open may be a string parsed from the parser or a passed boolean flag @@ -548,86 +692,127 @@ var __module7__ = (function(__dependency1__) { this.escaped = !!open; } + if (rawParams instanceof AST.SexprNode) { + this.sexpr = rawParams; + } else { + // Support old AST API + this.sexpr = new AST.SexprNode(rawParams, hash); + } + + // Support old AST API that stored this info in MustacheNode + this.id = this.sexpr.id; + this.params = this.sexpr.params; + this.hash = this.sexpr.hash; + this.eligibleHelper = this.sexpr.eligibleHelper; + this.isHelper = this.sexpr.isHelper; + }, + + SexprNode: function(rawParams, hash, locInfo) { + LocationInfo.call(this, locInfo); + + this.type = "sexpr"; + this.hash = hash; + var id = this.id = rawParams[0]; var params = this.params = rawParams.slice(1); - // a mustache is an eligible helper if: - // * its id is simple (a single part, not `this` or `..`) - var eligibleHelper = this.eligibleHelper = id.isSimple; - // a mustache is definitely a helper if: // * it is an eligible helper, and // * it has at least one parameter or hash segment - this.isHelper = eligibleHelper && (params.length || hash); + this.isHelper = !!(params.length || hash); + + // a mustache is an eligible helper if: + // * its id is simple (a single part, not `this` or `..`) + this.eligibleHelper = this.isHelper || id.isSimple; // if a mustache is an eligible helper but not a definite // helper, it is ambiguous, and will be resolved in a later // pass or at runtime. }, - PartialNode: function(partialName, context, strip) { + PartialNode: function(partialName, context, hash, strip, locInfo) { + LocationInfo.call(this, locInfo); this.type = "partial"; this.partialName = partialName; this.context = context; + this.hash = hash; this.strip = strip; + + this.strip.inlineStandalone = true; }, - BlockNode: function(mustache, program, inverse, close) { - if(mustache.id.original !== close.path.original) { - throw new Exception(mustache.id.original + " doesn't match " + close.path.original); - } + BlockNode: function(mustache, program, inverse, strip, locInfo) { + LocationInfo.call(this, locInfo); - this.type = "block"; + this.type = 'block'; this.mustache = mustache; this.program = program; this.inverse = inverse; - - this.strip = { - left: mustache.strip.left, - right: close.strip.right - }; - - (program || inverse).strip.left = mustache.strip.right; - (inverse || program).strip.right = close.strip.left; + this.strip = strip; if (inverse && !program) { this.isInverse = true; } }, - ContentNode: function(string) { - this.type = "content"; - this.string = string; + RawBlockNode: function(mustache, content, close, locInfo) { + LocationInfo.call(this, locInfo); + + if (mustache.sexpr.id.original !== close) { + throw new Exception(mustache.sexpr.id.original + " doesn't match " + close, this); + } + + content = new AST.ContentNode(content, locInfo); + + this.type = 'block'; + this.mustache = mustache; + this.program = new AST.ProgramNode([content], {}, locInfo); }, - HashNode: function(pairs) { + ContentNode: function(string, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "content"; + this.original = this.string = string; + }, + + HashNode: function(pairs, locInfo) { + LocationInfo.call(this, locInfo); this.type = "hash"; this.pairs = pairs; }, - IdNode: function(parts) { + IdNode: function(parts, locInfo) { + LocationInfo.call(this, locInfo); this.type = "ID"; var original = "", dig = [], - depth = 0; + depth = 0, + depthString = ''; for(var i=0,l=parts.length; i 0) { throw new Exception("Invalid path: " + original); } - else if (part === "..") { depth++; } - else { this.isScoped = true; } + if (dig.length > 0) { + throw new Exception("Invalid path: " + original, this); + } else if (part === "..") { + depth++; + depthString += '../'; + } else { + this.isScoped = true; + } + } else { + dig.push(part); } - else { dig.push(part); } } this.original = original; this.parts = dig; this.string = dig.join('.'); this.depth = depth; + this.idName = depthString + this.string; // an ID is simple if it only has one part, and that part is not // `..` or `this`. @@ -636,42 +821,55 @@ var __module7__ = (function(__dependency1__) { this.stringModeValue = this.string; }, - PartialNameNode: function(name) { + PartialNameNode: function(name, locInfo) { + LocationInfo.call(this, locInfo); this.type = "PARTIAL_NAME"; this.name = name.original; }, - DataNode: function(id) { + DataNode: function(id, locInfo) { + LocationInfo.call(this, locInfo); this.type = "DATA"; this.id = id; + this.stringModeValue = id.stringModeValue; + this.idName = '@' + id.stringModeValue; }, - StringNode: function(string) { + StringNode: function(string, locInfo) { + LocationInfo.call(this, locInfo); this.type = "STRING"; this.original = this.string = this.stringModeValue = string; }, - IntegerNode: function(integer) { - this.type = "INTEGER"; + NumberNode: function(number, locInfo) { + LocationInfo.call(this, locInfo); + this.type = "NUMBER"; this.original = - this.integer = integer; - this.stringModeValue = Number(integer); + this.number = number; + this.stringModeValue = Number(number); }, - BooleanNode: function(bool) { + BooleanNode: function(bool, locInfo) { + LocationInfo.call(this, locInfo); this.type = "BOOLEAN"; this.bool = bool; this.stringModeValue = bool === "true"; }, - CommentNode: function(comment) { + CommentNode: function(comment, locInfo) { + LocationInfo.call(this, locInfo); this.type = "comment"; this.comment = comment; + + this.strip = { + inlineStandalone: true + }; } }; + // Must be exported as an object rather than the root of the module as the jison lexer // most modify the object to operate properly. __exports__ = AST; @@ -683,107 +881,108 @@ var __module9__ = (function() { "use strict"; var __exports__; /* jshint ignore:start */ + /* istanbul ignore next */ /* Jison generated parser */ var handlebars = (function(){ var parser = {trace: function trace() { }, yy: {}, - symbols_: {"error":2,"root":3,"statements":4,"EOF":5,"program":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"inMustache":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"CLOSE_UNESCAPED":24,"OPEN_PARTIAL":25,"partialName":26,"partial_option0":27,"inMustache_repetition0":28,"inMustache_option0":29,"dataName":30,"param":31,"STRING":32,"INTEGER":33,"BOOLEAN":34,"hash":35,"hash_repetition_plus0":36,"hashSegment":37,"ID":38,"EQUALS":39,"DATA":40,"pathSegments":41,"SEP":42,"$accept":0,"$end":1}, - terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"CLOSE_UNESCAPED",25:"OPEN_PARTIAL",32:"STRING",33:"INTEGER",34:"BOOLEAN",38:"ID",39:"EQUALS",40:"DATA",42:"SEP"}, - productions_: [0,[3,2],[3,1],[6,2],[6,3],[6,2],[6,1],[6,1],[6,0],[4,1],[4,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,4],[7,2],[17,3],[17,1],[31,1],[31,1],[31,1],[31,1],[31,1],[35,1],[37,3],[26,1],[26,1],[26,1],[30,2],[21,1],[41,3],[41,1],[27,0],[27,1],[28,0],[28,2],[29,0],[29,1],[36,1],[36,2]], + symbols_: {"error":2,"root":3,"program":4,"EOF":5,"program_repetition0":6,"statement":7,"mustache":8,"block":9,"rawBlock":10,"partial":11,"CONTENT":12,"COMMENT":13,"openRawBlock":14,"END_RAW_BLOCK":15,"OPEN_RAW_BLOCK":16,"sexpr":17,"CLOSE_RAW_BLOCK":18,"openBlock":19,"block_option0":20,"closeBlock":21,"openInverse":22,"block_option1":23,"OPEN_BLOCK":24,"CLOSE":25,"OPEN_INVERSE":26,"inverseAndProgram":27,"INVERSE":28,"OPEN_ENDBLOCK":29,"path":30,"OPEN":31,"OPEN_UNESCAPED":32,"CLOSE_UNESCAPED":33,"OPEN_PARTIAL":34,"partialName":35,"param":36,"partial_option0":37,"partial_option1":38,"sexpr_repetition0":39,"sexpr_option0":40,"dataName":41,"STRING":42,"NUMBER":43,"BOOLEAN":44,"OPEN_SEXPR":45,"CLOSE_SEXPR":46,"hash":47,"hash_repetition_plus0":48,"hashSegment":49,"ID":50,"EQUALS":51,"DATA":52,"pathSegments":53,"SEP":54,"$accept":0,"$end":1}, + terminals_: {2:"error",5:"EOF",12:"CONTENT",13:"COMMENT",15:"END_RAW_BLOCK",16:"OPEN_RAW_BLOCK",18:"CLOSE_RAW_BLOCK",24:"OPEN_BLOCK",25:"CLOSE",26:"OPEN_INVERSE",28:"INVERSE",29:"OPEN_ENDBLOCK",31:"OPEN",32:"OPEN_UNESCAPED",33:"CLOSE_UNESCAPED",34:"OPEN_PARTIAL",42:"STRING",43:"NUMBER",44:"BOOLEAN",45:"OPEN_SEXPR",46:"CLOSE_SEXPR",50:"ID",51:"EQUALS",52:"DATA",54:"SEP"}, + productions_: [0,[3,2],[4,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[10,3],[14,3],[9,4],[9,4],[19,3],[22,3],[27,2],[21,3],[8,3],[8,3],[11,5],[11,4],[17,3],[17,1],[36,1],[36,1],[36,1],[36,1],[36,1],[36,3],[47,1],[49,3],[35,1],[35,1],[35,1],[41,2],[30,1],[53,3],[53,1],[6,0],[6,2],[20,0],[20,1],[23,0],[23,1],[37,0],[37,1],[38,0],[38,1],[39,0],[39,2],[40,0],[40,1],[48,1],[48,2]], performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) { var $0 = $$.length - 1; switch (yystate) { - case 1: return new yy.ProgramNode($$[$0-1]); + case 1: yy.prepareProgram($$[$0-1].statements, true); return $$[$0-1]; break; - case 2: return new yy.ProgramNode([]); + case 2:this.$ = new yy.ProgramNode(yy.prepareProgram($$[$0]), {}, this._$); break; - case 3:this.$ = new yy.ProgramNode([], $$[$0-1], $$[$0]); + case 3:this.$ = $$[$0]; break; - case 4:this.$ = new yy.ProgramNode($$[$0-2], $$[$0-1], $$[$0]); + case 4:this.$ = $$[$0]; break; - case 5:this.$ = new yy.ProgramNode($$[$0-1], $$[$0], []); + case 5:this.$ = $$[$0]; break; - case 6:this.$ = new yy.ProgramNode($$[$0]); + case 6:this.$ = $$[$0]; break; - case 7:this.$ = new yy.ProgramNode([]); + case 7:this.$ = new yy.ContentNode($$[$0], this._$); break; - case 8:this.$ = new yy.ProgramNode([]); + case 8:this.$ = new yy.CommentNode($$[$0], this._$); break; - case 9:this.$ = [$$[$0]]; + case 9:this.$ = new yy.RawBlockNode($$[$0-2], $$[$0-1], $$[$0], this._$); break; - case 10: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]; + case 10:this.$ = new yy.MustacheNode($$[$0-1], null, '', '', this._$); break; - case 11:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0]); + case 11:this.$ = yy.prepareBlock($$[$0-3], $$[$0-2], $$[$0-1], $$[$0], false, this._$); break; - case 12:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0]); + case 12:this.$ = yy.prepareBlock($$[$0-3], $$[$0-2], $$[$0-1], $$[$0], true, this._$); break; - case 13:this.$ = $$[$0]; + case 13:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$); break; - case 14:this.$ = $$[$0]; + case 14:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$); break; - case 15:this.$ = new yy.ContentNode($$[$0]); + case 15:this.$ = { strip: yy.stripFlags($$[$0-1], $$[$0-1]), program: $$[$0] }; break; - case 16:this.$ = new yy.CommentNode($$[$0]); + case 16:this.$ = {path: $$[$0-1], strip: yy.stripFlags($$[$0-2], $$[$0])}; break; - case 17:this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], $$[$0-2], stripFlags($$[$0-2], $$[$0])); + case 17:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$); break; - case 18:this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], $$[$0-2], stripFlags($$[$0-2], $$[$0])); + case 18:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$); break; - case 19:this.$ = {path: $$[$0-1], strip: stripFlags($$[$0-2], $$[$0])}; + case 19:this.$ = new yy.PartialNode($$[$0-3], $$[$0-2], $$[$0-1], yy.stripFlags($$[$0-4], $$[$0]), this._$); break; - case 20:this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], $$[$0-2], stripFlags($$[$0-2], $$[$0])); + case 20:this.$ = new yy.PartialNode($$[$0-2], undefined, $$[$0-1], yy.stripFlags($$[$0-3], $$[$0]), this._$); break; - case 21:this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], $$[$0-2], stripFlags($$[$0-2], $$[$0])); + case 21:this.$ = new yy.SexprNode([$$[$0-2]].concat($$[$0-1]), $$[$0], this._$); break; - case 22:this.$ = new yy.PartialNode($$[$0-2], $$[$0-1], stripFlags($$[$0-3], $$[$0])); + case 22:this.$ = new yy.SexprNode([$$[$0]], null, this._$); break; - case 23:this.$ = stripFlags($$[$0-1], $$[$0]); + case 23:this.$ = $$[$0]; break; - case 24:this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]]; + case 24:this.$ = new yy.StringNode($$[$0], this._$); break; - case 25:this.$ = [[$$[$0]], null]; + case 25:this.$ = new yy.NumberNode($$[$0], this._$); break; - case 26:this.$ = $$[$0]; + case 26:this.$ = new yy.BooleanNode($$[$0], this._$); break; - case 27:this.$ = new yy.StringNode($$[$0]); + case 27:this.$ = $$[$0]; break; - case 28:this.$ = new yy.IntegerNode($$[$0]); + case 28:$$[$0-1].isHelper = true; this.$ = $$[$0-1]; break; - case 29:this.$ = new yy.BooleanNode($$[$0]); + case 29:this.$ = new yy.HashNode($$[$0], this._$); break; - case 30:this.$ = $$[$0]; + case 30:this.$ = [$$[$0-2], $$[$0]]; break; - case 31:this.$ = new yy.HashNode($$[$0]); + case 31:this.$ = new yy.PartialNameNode($$[$0], this._$); break; - case 32:this.$ = [$$[$0-2], $$[$0]]; + case 32:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0], this._$), this._$); break; - case 33:this.$ = new yy.PartialNameNode($$[$0]); + case 33:this.$ = new yy.PartialNameNode(new yy.NumberNode($$[$0], this._$)); break; - case 34:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0])); + case 34:this.$ = new yy.DataNode($$[$0], this._$); break; - case 35:this.$ = new yy.PartialNameNode(new yy.IntegerNode($$[$0])); + case 35:this.$ = new yy.IdNode($$[$0], this._$); break; - case 36:this.$ = new yy.DataNode($$[$0]); + case 36: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2]; break; - case 37:this.$ = new yy.IdNode($$[$0]); + case 37:this.$ = [{part: $$[$0]}]; break; - case 38: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2]; + case 38:this.$ = []; break; - case 39:this.$ = [{part: $$[$0]}]; + case 39:$$[$0-1].push($$[$0]); break; - case 42:this.$ = []; + case 48:this.$ = []; break; - case 43:$$[$0-1].push($$[$0]); + case 49:$$[$0-1].push($$[$0]); break; - case 46:this.$ = [$$[$0]]; + case 52:this.$ = [$$[$0]]; break; - case 47:$$[$0-1].push($$[$0]); + case 53:$$[$0-1].push($$[$0]); break; } }, - table: [{3:1,4:2,5:[1,3],8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[3]},{5:[1,16],8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[2,2]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],25:[2,9]},{4:20,6:18,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{4:20,6:22,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{5:[2,13],14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],25:[2,13]},{5:[2,14],14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],25:[2,14]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],25:[2,15]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[2,16]},{17:23,21:24,30:25,38:[1,28],40:[1,27],41:26},{17:29,21:24,30:25,38:[1,28],40:[1,27],41:26},{17:30,21:24,30:25,38:[1,28],40:[1,27],41:26},{17:31,21:24,30:25,38:[1,28],40:[1,27],41:26},{21:33,26:32,32:[1,34],33:[1,35],38:[1,28],41:26},{1:[2,1]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],25:[2,10]},{10:36,20:[1,37]},{4:38,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,7],22:[1,13],23:[1,14],25:[1,15]},{7:39,8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,6],22:[1,13],23:[1,14],25:[1,15]},{17:23,18:[1,40],21:24,30:25,38:[1,28],40:[1,27],41:26},{10:41,20:[1,37]},{18:[1,42]},{18:[2,42],24:[2,42],28:43,32:[2,42],33:[2,42],34:[2,42],38:[2,42],40:[2,42]},{18:[2,25],24:[2,25]},{18:[2,37],24:[2,37],32:[2,37],33:[2,37],34:[2,37],38:[2,37],40:[2,37],42:[1,44]},{21:45,38:[1,28],41:26},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],38:[2,39],40:[2,39],42:[2,39]},{18:[1,46]},{18:[1,47]},{24:[1,48]},{18:[2,40],21:50,27:49,38:[1,28],41:26},{18:[2,33],38:[2,33]},{18:[2,34],38:[2,34]},{18:[2,35],38:[2,35]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],25:[2,11]},{21:51,38:[1,28],41:26},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,3],22:[1,13],23:[1,14],25:[1,15]},{4:52,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,5],22:[1,13],23:[1,14],25:[1,15]},{14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],25:[2,23]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],25:[2,12]},{14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],25:[2,18]},{18:[2,44],21:56,24:[2,44],29:53,30:60,31:54,32:[1,57],33:[1,58],34:[1,59],35:55,36:61,37:62,38:[1,63],40:[1,27],41:26},{38:[1,64]},{18:[2,36],24:[2,36],32:[2,36],33:[2,36],34:[2,36],38:[2,36],40:[2,36]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],25:[2,17]},{5:[2,20],14:[2,20],15:[2,20],16:[2,20],19:[2,20],20:[2,20],22:[2,20],23:[2,20],25:[2,20]},{5:[2,21],14:[2,21],15:[2,21],16:[2,21],19:[2,21],20:[2,21],22:[2,21],23:[2,21],25:[2,21]},{18:[1,65]},{18:[2,41]},{18:[1,66]},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],25:[1,15]},{18:[2,24],24:[2,24]},{18:[2,43],24:[2,43],32:[2,43],33:[2,43],34:[2,43],38:[2,43],40:[2,43]},{18:[2,45],24:[2,45]},{18:[2,26],24:[2,26],32:[2,26],33:[2,26],34:[2,26],38:[2,26],40:[2,26]},{18:[2,27],24:[2,27],32:[2,27],33:[2,27],34:[2,27],38:[2,27],40:[2,27]},{18:[2,28],24:[2,28],32:[2,28],33:[2,28],34:[2,28],38:[2,28],40:[2,28]},{18:[2,29],24:[2,29],32:[2,29],33:[2,29],34:[2,29],38:[2,29],40:[2,29]},{18:[2,30],24:[2,30],32:[2,30],33:[2,30],34:[2,30],38:[2,30],40:[2,30]},{18:[2,31],24:[2,31],37:67,38:[1,68]},{18:[2,46],24:[2,46],38:[2,46]},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],38:[2,39],39:[1,69],40:[2,39],42:[2,39]},{18:[2,38],24:[2,38],32:[2,38],33:[2,38],34:[2,38],38:[2,38],40:[2,38],42:[2,38]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],25:[2,22]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],25:[2,19]},{18:[2,47],24:[2,47],38:[2,47]},{39:[1,69]},{21:56,30:60,31:70,32:[1,57],33:[1,58],34:[1,59],38:[1,28],40:[1,27],41:26},{18:[2,32],24:[2,32],38:[2,32]}], - defaultActions: {3:[2,2],16:[2,1],50:[2,41]}, + table: [{3:1,4:2,5:[2,38],6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],31:[2,38],32:[2,38],34:[2,38]},{1:[3]},{5:[1,4]},{5:[2,2],7:5,8:6,9:7,10:8,11:9,12:[1,10],13:[1,11],14:16,16:[1,20],19:14,22:15,24:[1,18],26:[1,19],28:[2,2],29:[2,2],31:[1,12],32:[1,13],34:[1,17]},{1:[2,1]},{5:[2,39],12:[2,39],13:[2,39],16:[2,39],24:[2,39],26:[2,39],28:[2,39],29:[2,39],31:[2,39],32:[2,39],34:[2,39]},{5:[2,3],12:[2,3],13:[2,3],16:[2,3],24:[2,3],26:[2,3],28:[2,3],29:[2,3],31:[2,3],32:[2,3],34:[2,3]},{5:[2,4],12:[2,4],13:[2,4],16:[2,4],24:[2,4],26:[2,4],28:[2,4],29:[2,4],31:[2,4],32:[2,4],34:[2,4]},{5:[2,5],12:[2,5],13:[2,5],16:[2,5],24:[2,5],26:[2,5],28:[2,5],29:[2,5],31:[2,5],32:[2,5],34:[2,5]},{5:[2,6],12:[2,6],13:[2,6],16:[2,6],24:[2,6],26:[2,6],28:[2,6],29:[2,6],31:[2,6],32:[2,6],34:[2,6]},{5:[2,7],12:[2,7],13:[2,7],16:[2,7],24:[2,7],26:[2,7],28:[2,7],29:[2,7],31:[2,7],32:[2,7],34:[2,7]},{5:[2,8],12:[2,8],13:[2,8],16:[2,8],24:[2,8],26:[2,8],28:[2,8],29:[2,8],31:[2,8],32:[2,8],34:[2,8]},{17:21,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:27,30:22,41:23,50:[1,26],52:[1,25],53:24},{4:28,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],28:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{4:29,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],28:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{12:[1,30]},{30:32,35:31,42:[1,33],43:[1,34],50:[1,26],53:24},{17:35,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:36,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:37,30:22,41:23,50:[1,26],52:[1,25],53:24},{25:[1,38]},{18:[2,48],25:[2,48],33:[2,48],39:39,42:[2,48],43:[2,48],44:[2,48],45:[2,48],46:[2,48],50:[2,48],52:[2,48]},{18:[2,22],25:[2,22],33:[2,22],46:[2,22]},{18:[2,35],25:[2,35],33:[2,35],42:[2,35],43:[2,35],44:[2,35],45:[2,35],46:[2,35],50:[2,35],52:[2,35],54:[1,40]},{30:41,50:[1,26],53:24},{18:[2,37],25:[2,37],33:[2,37],42:[2,37],43:[2,37],44:[2,37],45:[2,37],46:[2,37],50:[2,37],52:[2,37],54:[2,37]},{33:[1,42]},{20:43,27:44,28:[1,45],29:[2,40]},{23:46,27:47,28:[1,45],29:[2,42]},{15:[1,48]},{25:[2,46],30:51,36:49,38:50,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],47:57,48:58,49:60,50:[1,59],52:[1,25],53:24},{25:[2,31],42:[2,31],43:[2,31],44:[2,31],45:[2,31],50:[2,31],52:[2,31]},{25:[2,32],42:[2,32],43:[2,32],44:[2,32],45:[2,32],50:[2,32],52:[2,32]},{25:[2,33],42:[2,33],43:[2,33],44:[2,33],45:[2,33],50:[2,33],52:[2,33]},{25:[1,61]},{25:[1,62]},{18:[1,63]},{5:[2,17],12:[2,17],13:[2,17],16:[2,17],24:[2,17],26:[2,17],28:[2,17],29:[2,17],31:[2,17],32:[2,17],34:[2,17]},{18:[2,50],25:[2,50],30:51,33:[2,50],36:65,40:64,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],46:[2,50],47:66,48:58,49:60,50:[1,59],52:[1,25],53:24},{50:[1,67]},{18:[2,34],25:[2,34],33:[2,34],42:[2,34],43:[2,34],44:[2,34],45:[2,34],46:[2,34],50:[2,34],52:[2,34]},{5:[2,18],12:[2,18],13:[2,18],16:[2,18],24:[2,18],26:[2,18],28:[2,18],29:[2,18],31:[2,18],32:[2,18],34:[2,18]},{21:68,29:[1,69]},{29:[2,41]},{4:70,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{21:71,29:[1,69]},{29:[2,43]},{5:[2,9],12:[2,9],13:[2,9],16:[2,9],24:[2,9],26:[2,9],28:[2,9],29:[2,9],31:[2,9],32:[2,9],34:[2,9]},{25:[2,44],37:72,47:73,48:58,49:60,50:[1,74]},{25:[1,75]},{18:[2,23],25:[2,23],33:[2,23],42:[2,23],43:[2,23],44:[2,23],45:[2,23],46:[2,23],50:[2,23],52:[2,23]},{18:[2,24],25:[2,24],33:[2,24],42:[2,24],43:[2,24],44:[2,24],45:[2,24],46:[2,24],50:[2,24],52:[2,24]},{18:[2,25],25:[2,25],33:[2,25],42:[2,25],43:[2,25],44:[2,25],45:[2,25],46:[2,25],50:[2,25],52:[2,25]},{18:[2,26],25:[2,26],33:[2,26],42:[2,26],43:[2,26],44:[2,26],45:[2,26],46:[2,26],50:[2,26],52:[2,26]},{18:[2,27],25:[2,27],33:[2,27],42:[2,27],43:[2,27],44:[2,27],45:[2,27],46:[2,27],50:[2,27],52:[2,27]},{17:76,30:22,41:23,50:[1,26],52:[1,25],53:24},{25:[2,47]},{18:[2,29],25:[2,29],33:[2,29],46:[2,29],49:77,50:[1,74]},{18:[2,37],25:[2,37],33:[2,37],42:[2,37],43:[2,37],44:[2,37],45:[2,37],46:[2,37],50:[2,37],51:[1,78],52:[2,37],54:[2,37]},{18:[2,52],25:[2,52],33:[2,52],46:[2,52],50:[2,52]},{12:[2,13],13:[2,13],16:[2,13],24:[2,13],26:[2,13],28:[2,13],29:[2,13],31:[2,13],32:[2,13],34:[2,13]},{12:[2,14],13:[2,14],16:[2,14],24:[2,14],26:[2,14],28:[2,14],29:[2,14],31:[2,14],32:[2,14],34:[2,14]},{12:[2,10]},{18:[2,21],25:[2,21],33:[2,21],46:[2,21]},{18:[2,49],25:[2,49],33:[2,49],42:[2,49],43:[2,49],44:[2,49],45:[2,49],46:[2,49],50:[2,49],52:[2,49]},{18:[2,51],25:[2,51],33:[2,51],46:[2,51]},{18:[2,36],25:[2,36],33:[2,36],42:[2,36],43:[2,36],44:[2,36],45:[2,36],46:[2,36],50:[2,36],52:[2,36],54:[2,36]},{5:[2,11],12:[2,11],13:[2,11],16:[2,11],24:[2,11],26:[2,11],28:[2,11],29:[2,11],31:[2,11],32:[2,11],34:[2,11]},{30:79,50:[1,26],53:24},{29:[2,15]},{5:[2,12],12:[2,12],13:[2,12],16:[2,12],24:[2,12],26:[2,12],28:[2,12],29:[2,12],31:[2,12],32:[2,12],34:[2,12]},{25:[1,80]},{25:[2,45]},{51:[1,78]},{5:[2,20],12:[2,20],13:[2,20],16:[2,20],24:[2,20],26:[2,20],28:[2,20],29:[2,20],31:[2,20],32:[2,20],34:[2,20]},{46:[1,81]},{18:[2,53],25:[2,53],33:[2,53],46:[2,53],50:[2,53]},{30:51,36:82,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],50:[1,26],52:[1,25],53:24},{25:[1,83]},{5:[2,19],12:[2,19],13:[2,19],16:[2,19],24:[2,19],26:[2,19],28:[2,19],29:[2,19],31:[2,19],32:[2,19],34:[2,19]},{18:[2,28],25:[2,28],33:[2,28],42:[2,28],43:[2,28],44:[2,28],45:[2,28],46:[2,28],50:[2,28],52:[2,28]},{18:[2,30],25:[2,30],33:[2,30],46:[2,30],50:[2,30]},{5:[2,16],12:[2,16],13:[2,16],16:[2,16],24:[2,16],26:[2,16],28:[2,16],29:[2,16],31:[2,16],32:[2,16],34:[2,16]}], + defaultActions: {4:[2,1],44:[2,41],47:[2,43],57:[2,47],63:[2,10],70:[2,15],73:[2,45]}, parseError: function parseError(str, hash) { throw new Error(str); }, @@ -891,15 +1090,6 @@ var __module9__ = (function() { return true; } }; - - - function stripFlags(open, close) { - return { - left: open.charAt(2) === '~', - right: close.charAt(0) === '~' || close.charAt(1) === '~' - }; - } - /* Jison generated lexer */ var lexer = (function(){ var lexer = ({EOF:1, @@ -1089,76 +1279,100 @@ var __module9__ = (function() { } else { this.begin("mu"); } - if(yy_.yytext) return 14; + if(yy_.yytext) return 12; break; - case 1:return 14; + case 1:return 12; break; case 2: this.popState(); - return 14; + return 12; break; - case 3:strip(0,4); this.popState(); return 15; + case 3: + yy_.yytext = yy_.yytext.substr(5, yy_.yyleng-9); + this.popState(); + return 15; + break; - case 4:return 25; + case 4: return 12; break; - case 5:return 16; + case 5:strip(0,4); this.popState(); return 13; break; - case 6:return 20; + case 6:return 45; break; - case 7:return 19; + case 7:return 46; break; - case 8:return 19; + case 8: return 16; break; - case 9:return 23; + case 9: + this.popState(); + this.begin('raw'); + return 18; + break; - case 10:return 22; + case 10:return 34; break; - case 11:this.popState(); this.begin('com'); + case 11:return 24; break; - case 12:strip(3,5); this.popState(); return 15; + case 12:return 29; break; - case 13:return 22; + case 13:this.popState(); return 28; break; - case 14:return 39; + case 14:this.popState(); return 28; break; - case 15:return 38; + case 15:return 26; break; - case 16:return 38; + case 16:return 26; break; - case 17:return 42; + case 17:return 32; break; - case 18:// ignore whitespace + case 18:return 31; break; - case 19:this.popState(); return 24; + case 19:this.popState(); this.begin('com'); break; - case 20:this.popState(); return 18; + case 20:strip(3,5); this.popState(); return 13; break; - case 21:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 32; + case 21:return 31; break; - case 22:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 32; + case 22:return 51; break; - case 23:return 40; + case 23:return 50; break; - case 24:return 34; + case 24:return 50; break; - case 25:return 34; + case 25:return 54; break; - case 26:return 33; + case 26:// ignore whitespace break; - case 27:return 38; + case 27:this.popState(); return 33; break; - case 28:yy_.yytext = strip(1,2); return 38; + case 28:this.popState(); return 25; break; - case 29:return 'INVALID'; + case 29:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 42; break; - case 30:return 5; + case 30:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 42; + break; + case 31:return 52; + break; + case 32:return 44; + break; + case 33:return 44; + break; + case 34:return 43; + break; + case 35:return 50; + break; + case 36:yy_.yytext = strip(1,2); return 50; + break; + case 37:return 'INVALID'; + break; + case 38:return 5; break; } }; - lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s])))/,/^(?:false(?=([~}\s])))/,/^(?:-?[0-9]+(?=([~}\s])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/]; - lexer.conditions = {"mu":{"rules":[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"INITIAL":{"rules":[0,1,30],"inclusive":true}}; + lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/,/^(?:[^\x00]*?(?=(\{\{\{\{\/)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{\{\{)/,/^(?:\}\}\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^\s*(~)?\}\})/,/^(?:\{\{(~)?\s*else\s*(~)?\}\})/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/]; + lexer.conditions = {"mu":{"rules":[6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[5],"inclusive":false},"raw":{"rules":[3,4],"inclusive":false},"INITIAL":{"rules":[0,1,38],"inclusive":true}}; return lexer;})() parser.lexer = lexer; function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser; @@ -1168,34 +1382,691 @@ var __module9__ = (function() { return __exports__; })(); +// handlebars/compiler/helpers.js +var __module10__ = (function(__dependency1__) { + "use strict"; + var __exports__ = {}; + var Exception = __dependency1__; + + function stripFlags(open, close) { + return { + left: open.charAt(2) === '~', + right: close.charAt(close.length-3) === '~' + }; + } + + __exports__.stripFlags = stripFlags; + function prepareBlock(mustache, program, inverseAndProgram, close, inverted, locInfo) { + /*jshint -W040 */ + if (mustache.sexpr.id.original !== close.path.original) { + throw new Exception(mustache.sexpr.id.original + ' doesn\'t match ' + close.path.original, mustache); + } + + var inverse = inverseAndProgram && inverseAndProgram.program; + + var strip = { + left: mustache.strip.left, + right: close.strip.right, + + // Determine the standalone candiacy. Basically flag our content as being possibly standalone + // so our parent can determine if we actually are standalone + openStandalone: isNextWhitespace(program.statements), + closeStandalone: isPrevWhitespace((inverse || program).statements) + }; + + if (mustache.strip.right) { + omitRight(program.statements, null, true); + } + + if (inverse) { + var inverseStrip = inverseAndProgram.strip; + + if (inverseStrip.left) { + omitLeft(program.statements, null, true); + } + if (inverseStrip.right) { + omitRight(inverse.statements, null, true); + } + if (close.strip.left) { + omitLeft(inverse.statements, null, true); + } + + // Find standalone else statments + if (isPrevWhitespace(program.statements) + && isNextWhitespace(inverse.statements)) { + + omitLeft(program.statements); + omitRight(inverse.statements); + } + } else { + if (close.strip.left) { + omitLeft(program.statements, null, true); + } + } + + if (inverted) { + return new this.BlockNode(mustache, inverse, program, strip, locInfo); + } else { + return new this.BlockNode(mustache, program, inverse, strip, locInfo); + } + } + + __exports__.prepareBlock = prepareBlock; + function prepareProgram(statements, isRoot) { + for (var i = 0, l = statements.length; i < l; i++) { + var current = statements[i], + strip = current.strip; + + if (!strip) { + continue; + } + + var _isPrevWhitespace = isPrevWhitespace(statements, i, isRoot, current.type === 'partial'), + _isNextWhitespace = isNextWhitespace(statements, i, isRoot), + + openStandalone = strip.openStandalone && _isPrevWhitespace, + closeStandalone = strip.closeStandalone && _isNextWhitespace, + inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace; + + if (strip.right) { + omitRight(statements, i, true); + } + if (strip.left) { + omitLeft(statements, i, true); + } + + if (inlineStandalone) { + omitRight(statements, i); + + if (omitLeft(statements, i)) { + // If we are on a standalone node, save the indent info for partials + if (current.type === 'partial') { + current.indent = (/([ \t]+$)/).exec(statements[i-1].original) ? RegExp.$1 : ''; + } + } + } + if (openStandalone) { + omitRight((current.program || current.inverse).statements); + + // Strip out the previous content node if it's whitespace only + omitLeft(statements, i); + } + if (closeStandalone) { + // Always strip the next node + omitRight(statements, i); + + omitLeft((current.inverse || current.program).statements); + } + } + + return statements; + } + + __exports__.prepareProgram = prepareProgram;function isPrevWhitespace(statements, i, isRoot) { + if (i === undefined) { + i = statements.length; + } + + // Nodes that end with newlines are considered whitespace (but are special + // cased for strip operations) + var prev = statements[i-1], + sibling = statements[i-2]; + if (!prev) { + return isRoot; + } + + if (prev.type === 'content') { + return (sibling || !isRoot ? (/\r?\n\s*?$/) : (/(^|\r?\n)\s*?$/)).test(prev.original); + } + } + function isNextWhitespace(statements, i, isRoot) { + if (i === undefined) { + i = -1; + } + + var next = statements[i+1], + sibling = statements[i+2]; + if (!next) { + return isRoot; + } + + if (next.type === 'content') { + return (sibling || !isRoot ? (/^\s*?\r?\n/) : (/^\s*?(\r?\n|$)/)).test(next.original); + } + } + + // Marks the node to the right of the position as omitted. + // I.e. {{foo}}' ' will mark the ' ' node as omitted. + // + // If i is undefined, then the first child will be marked as such. + // + // If mulitple is truthy then all whitespace will be stripped out until non-whitespace + // content is met. + function omitRight(statements, i, multiple) { + var current = statements[i == null ? 0 : i + 1]; + if (!current || current.type !== 'content' || (!multiple && current.rightStripped)) { + return; + } + + var original = current.string; + current.string = current.string.replace(multiple ? (/^\s+/) : (/^[ \t]*\r?\n?/), ''); + current.rightStripped = current.string !== original; + } + + // Marks the node to the left of the position as omitted. + // I.e. ' '{{foo}} will mark the ' ' node as omitted. + // + // If i is undefined then the last child will be marked as such. + // + // If mulitple is truthy then all whitespace will be stripped out until non-whitespace + // content is met. + function omitLeft(statements, i, multiple) { + var current = statements[i == null ? statements.length - 1 : i - 1]; + if (!current || current.type !== 'content' || (!multiple && current.leftStripped)) { + return; + } + + // We omit the last node if it's whitespace only and not preceeded by a non-content node. + var original = current.string; + current.string = current.string.replace(multiple ? (/\s+$/) : (/[ \t]+$/), ''); + current.leftStripped = current.string !== original; + return current.leftStripped; + } + return __exports__; +})(__module5__); + // handlebars/compiler/base.js -var __module8__ = (function(__dependency1__, __dependency2__) { +var __module8__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__) { "use strict"; var __exports__ = {}; var parser = __dependency1__; var AST = __dependency2__; + var Helpers = __dependency3__; + var extend = __dependency4__.extend; __exports__.parser = parser; + var yy = {}; + extend(yy, Helpers, AST); + function parse(input) { // Just return if an already-compile AST was passed in. - if(input.constructor === AST.ProgramNode) { return input; } + if (input.constructor === AST.ProgramNode) { return input; } + + parser.yy = yy; - parser.yy = AST; return parser.parse(input); } __exports__.parse = parse; return __exports__; -})(__module9__, __module7__); +})(__module9__, __module7__, __module10__, __module3__); + +// handlebars/compiler/compiler.js +var __module11__ = (function(__dependency1__, __dependency2__) { + "use strict"; + var __exports__ = {}; + var Exception = __dependency1__; + var isArray = __dependency2__.isArray; + + var slice = [].slice; + + function Compiler() {} + + __exports__.Compiler = Compiler;// the foundHelper register will disambiguate helper lookup from finding a + // function in a context. This is necessary for mustache compatibility, which + // requires that context functions in blocks are evaluated by blockHelperMissing, + // and then proceed as if the resulting value was provided to blockHelperMissing. + + Compiler.prototype = { + compiler: Compiler, + + equals: function(other) { + var len = this.opcodes.length; + if (other.opcodes.length !== len) { + return false; + } + + for (var i = 0; i < len; i++) { + var opcode = this.opcodes[i], + otherOpcode = other.opcodes[i]; + if (opcode.opcode !== otherOpcode.opcode || !argEquals(opcode.args, otherOpcode.args)) { + return false; + } + } + + // We know that length is the same between the two arrays because they are directly tied + // to the opcode behavior above. + len = this.children.length; + for (i = 0; i < len; i++) { + if (!this.children[i].equals(other.children[i])) { + return false; + } + } + + return true; + }, + + guid: 0, + + compile: function(program, options) { + this.opcodes = []; + this.children = []; + this.depths = {list: []}; + this.options = options; + this.stringParams = options.stringParams; + this.trackIds = options.trackIds; + + // These changes will propagate to the other compiler components + var knownHelpers = this.options.knownHelpers; + this.options.knownHelpers = { + 'helperMissing': true, + 'blockHelperMissing': true, + 'each': true, + 'if': true, + 'unless': true, + 'with': true, + 'log': true, + 'lookup': true + }; + if (knownHelpers) { + for (var name in knownHelpers) { + this.options.knownHelpers[name] = knownHelpers[name]; + } + } + + return this.accept(program); + }, + + accept: function(node) { + return this[node.type](node); + }, + + program: function(program) { + var statements = program.statements; + + for(var i=0, l=statements.length; i 0) { - this.source[1] = this.source[1] + ", " + locals.join(", "); + varDeclarations += ", " + locals.join(", "); } // Generate minimizer alias mappings - if (!this.isChild) { - for (var alias in this.context.aliases) { - if (this.context.aliases.hasOwnProperty(alias)) { - this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias]; - } + for (var alias in this.aliases) { + if (this.aliases.hasOwnProperty(alias)) { + varDeclarations += ', ' + alias + '=' + this.aliases[alias]; } } - if (this.source[1]) { - this.source[1] = "var " + this.source[1].substring(2) + ";"; - } + var params = ["depth0", "helpers", "partials", "data"]; - // Merge children - if (!this.isChild) { - this.source[1] += '\n' + this.context.programs.join('\n') + '\n'; - } - - if (!this.environment.isSimple) { - this.pushSource("return buffer;"); - } - - var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"]; - - for(var i=0, l=this.environment.depths.list.length; i