dist/ember.prod.js in ember-source-2.7.2 vs dist/ember.prod.js in ember-source-2.8.0.beta.1

- old
+ new

@@ -4,11 +4,11 @@ * @copyright Copyright 2011-2016 Tilde Inc. and contributors * Portions Copyright 2006-2011 Strobe Inc. * Portions Copyright 2008-2011 Apple Inc. All rights reserved. * @license Licensed under MIT license * See https://raw.github.com/emberjs/ember.js/master/LICENSE - * @version 2.7.2 + * @version 2.8.0-beta.1 */ var enifed, requireModule, require, Ember; var mainContext = this; @@ -1154,10 +1154,12 @@ } }); enifed('container/container', ['exports', 'ember-environment', 'ember-metal/debug', 'ember-metal/dictionary', 'container/owner', 'ember-runtime/mixins/container_proxy', 'ember-metal/symbol'], function (exports, _emberEnvironment, _emberMetalDebug, _emberMetalDictionary, _containerOwner, _emberRuntimeMixinsContainer_proxy, _emberMetalSymbol) { 'use strict'; + exports.default = Container; + var CONTAINER_OVERRIDE = _emberMetalSymbol.default('CONTAINER_OVERRIDE'); /** A container used to instantiate and cache objects. @@ -1169,18 +1171,20 @@ stable. @private @class Container */ + function Container(registry, options) { this.registry = registry; this.owner = options && options.owner ? options.owner : null; this.cache = _emberMetalDictionary.default(options && options.cache ? options.cache : null); this.factoryCache = _emberMetalDictionary.default(options && options.factoryCache ? options.factoryCache : null); this.validationCache = _emberMetalDictionary.default(options && options.validationCache ? options.validationCache : null); this._fakeContainerToInject = _emberRuntimeMixinsContainer_proxy.buildFakeContainerWithDeprecations(this); this[CONTAINER_OVERRIDE] = undefined; + this.isDestroyed = false; } Container.prototype = { /** @private @@ -1222,27 +1226,27 @@ Given a fullName return a corresponding instance. The default behaviour is for lookup to return a singleton instance. The singleton is scoped to the container, allowing multiple containers to all have their own locally scoped singletons. ```javascript - var registry = new Registry(); - var container = registry.container(); + let registry = new Registry(); + let container = registry.container(); registry.register('api:twitter', Twitter); - var twitter = container.lookup('api:twitter'); + let twitter = container.lookup('api:twitter'); twitter instanceof Twitter; // => true // by default the container will return singletons - var twitter2 = container.lookup('api:twitter'); + let twitter2 = container.lookup('api:twitter'); twitter2 instanceof Twitter; // => true twitter === twitter2; //=> true ``` If singletons are not wanted, an optional flag can be provided at lookup. ```javascript - var registry = new Registry(); - var container = registry.container(); + let registry = new Registry(); + let container = registry.container(); registry.register('api:twitter', Twitter); - var twitter = container.lookup('api:twitter', { singleton: false }); - var twitter2 = container.lookup('api:twitter', { singleton: false }); + let twitter = container.lookup('api:twitter', { singleton: false }); + let twitter2 = container.lookup('api:twitter', { singleton: false }); twitter === twitter2; //=> false ``` @private @method lookup @param {String} fullName @@ -1356,21 +1360,21 @@ var hash = {}; if (arguments.length > 1) { var container = arguments[0]; var injections = []; - var injection; + var injection = undefined; for (var i = 1; i < arguments.length; i++) { if (arguments[i]) { injections = injections.concat(arguments[i]); } } container.registry.validateInjections(injections); - for (i = 0; i < injections.length; i++) { + for (var i = 0; i < injections.length; i++) { injection = injections[i]; hash[injection.property] = lookup(container, injection.fullName); if (!isSingleton(container, injection.fullName)) { markInjectionsAsDynamic(hash); } @@ -1462,19 +1466,20 @@ return factoryInjections; } function instantiate(container, fullName) { var factory = factoryFor(container, fullName); - var lazyInjections, validationCache; + var lazyInjections = undefined, + validationCache = undefined; if (container.registry.getOption(fullName, 'instantiate') === false) { return factory; } if (factory) { if (typeof factory.create !== 'function') { - throw new Error('Failed to create an instance of \'' + fullName + '\'. ' + 'Most likely an improperly defined class or an invalid module export.'); + throw new Error('Failed to create an instance of \'' + fullName + '\'. Most likely an improperly defined class or' + ' an invalid module export.'); } validationCache = container.validationCache; validationCache[fullName] = true; @@ -1526,15 +1531,14 @@ } function eachDestroyable(container, callback) { var cache = container.cache; var keys = Object.keys(cache); - var key, value; for (var i = 0; i < keys.length; i++) { - key = keys[i]; - value = cache[key]; + var key = keys[i]; + var value = cache[key]; if (container.registry.getOption(key, 'instantiate') !== false) { callback(value); } } @@ -1561,12 +1565,10 @@ if (member.destroy) { member.destroy(); } } } - - exports.default = Container; }); // Ensure that all lazy injections are valid at instantiation time enifed('container/index', ['exports', 'container/registry', 'container/container', 'container/owner'], function (exports, _containerRegistry, _containerContainer, _containerOwner) { /* @@ -1628,13 +1630,14 @@ } }); ``` @method getOwner + @for Ember @param {Object} object An object with an owner. @return {Object} An owner object. - @for Ember + @since 2.3.0 @public */ function getOwner(object) { return object[OWNER]; @@ -1643,23 +1646,25 @@ /** `setOwner` forces a new owner on a given object instance. This is primarily useful in some testing cases. @method setOwner + @for Ember @param {Object} object An object with an owner. @return {Object} An owner object. - @for Ember + @since 2.3.0 @public */ function setOwner(object, owner) { object[OWNER] = owner; } }); enifed('container/registry', ['exports', 'ember-metal/debug', 'ember-metal/dictionary', 'ember-metal/empty_object', 'ember-metal/assign', 'container/container', 'ember-metal/utils'], function (exports, _emberMetalDebug, _emberMetalDictionary, _emberMetalEmpty_object, _emberMetalAssign, _containerContainer, _emberMetalUtils) { 'use strict'; + exports.default = Registry; exports.privatize = privatize; var VALID_FULL_NAME_REGEXP = /^[^:]+:[^:]+$/; /** @@ -1673,10 +1678,11 @@ @private @class Registry @since 1.11.0 */ + function Registry(options) { this.fallback = options && options.fallback ? options.fallback : null; if (options && options.resolver) { this.resolver = options.resolver; @@ -1795,11 +1801,11 @@ /** Registers a factory for later injection. Example: ```javascript - var registry = new Registry(); + let registry = new Registry(); registry.register('model:user', Person, {singleton: false }); registry.register('fruit:favorite', Orange); registry.register('communication:main', Email, {singleton: false}); ``` @private @@ -1810,28 +1816,28 @@ */ register: function (fullName, factory) { var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; if (factory === undefined) { - throw new TypeError('Attempting to register an unknown factory: `' + fullName + '`'); + throw new TypeError('Attempting to register an unknown factory: \'' + fullName + '\''); } var normalizedName = this.normalize(fullName); if (this._resolveCache[normalizedName]) { - throw new Error('Cannot re-register: `' + fullName + '`, as it has already been resolved.'); + throw new Error('Cannot re-register: \'' + fullName + '\', as it has already been resolved.'); } delete this._failCache[normalizedName]; this.registrations[normalizedName] = factory; this._options[normalizedName] = options; }, /** Unregister a fullName ```javascript - var registry = new Registry(); + let registry = new Registry(); registry.register('model:user', User); registry.resolve('model:user').create() instanceof User //=> true registry.unregister('model:user') registry.resolve('model:user') === undefined //=> true ``` @@ -1854,20 +1860,20 @@ /** Given a fullName return the corresponding factory. By default `resolve` will retrieve the factory from the registry. ```javascript - var registry = new Registry(); + let registry = new Registry(); registry.register('api:twitter', Twitter); registry.resolve('api:twitter') // => Twitter ``` Optionally the registry can be provided with a custom resolver. If provided, `resolve` will first provide the custom resolver the opportunity to resolve the fullName, otherwise it will fallback to the registry. ```javascript - var registry = new Registry(); + let registry = new Registry(); registry.resolver = function(fullName) { // lookup via the module system of choice }; // the twitter factory is added to the module system registry.resolve('api:twitter') // => Twitter @@ -1976,21 +1982,21 @@ }, /** Allow registering options for all factories of a type. ```javascript - var registry = new Registry(); - var container = registry.container(); + let registry = new Registry(); + let container = registry.container(); // if all of type `connection` must not be singletons registry.optionsForType('connection', { singleton: false }); registry.register('connection:twitter', TwitterConnection); registry.register('connection:facebook', FacebookConnection); - var twitter = container.lookup('connection:twitter'); - var twitter2 = container.lookup('connection:twitter'); + let twitter = container.lookup('connection:twitter'); + let twitter2 = container.lookup('connection:twitter'); twitter === twitter2; // => false - var facebook = container.lookup('connection:facebook'); - var facebook2 = container.lookup('connection:facebook'); + let facebook = container.lookup('connection:facebook'); + let facebook2 = container.lookup('connection:facebook'); facebook === facebook2; // => false ``` @private @method optionsForType @param {String} type @@ -2022,10 +2028,11 @@ }, getOptions: function (fullName) { var normalizedName = this.normalize(fullName); var options = this._options[normalizedName]; + if (options === undefined && this.fallback) { options = this.fallback.getOptions(fullName); } return options; }, @@ -2053,18 +2060,18 @@ all objects of one type to be injected with a reference to another object. For example, provided each object of type `controller` needed a `router`. one would do the following: ```javascript - var registry = new Registry(); - var container = registry.container(); + let registry = new Registry(); + let container = registry.container(); registry.register('router:main', Router); registry.register('controller:user', UserController); registry.register('controller:post', PostController); registry.typeInjection('controller', 'router', 'router:main'); - var user = container.lookup('controller:user'); - var post = container.lookup('controller:post'); + let user = container.lookup('controller:user'); + let post = container.lookup('controller:post'); user.router instanceof Router; //=> true post.router instanceof Router; //=> true // both controllers share the same router user.router === post.router; //=> true ``` @@ -2076,11 +2083,11 @@ */ typeInjection: function (type, property, fullName) { var fullNameType = fullName.split(':')[0]; if (fullNameType === type) { - throw new Error('Cannot inject a `' + fullName + '` on other ' + type + '(s).'); + throw new Error('Cannot inject a \'' + fullName + '\' on other ' + type + '(s).'); } var injections = this._typeInjections[type] || (this._typeInjections[type] = []); injections.push({ @@ -2096,22 +2103,22 @@ Two forms of injections are possible: * Injecting one fullName on another fullName * Injecting one fullName on a type Example: ```javascript - var registry = new Registry(); - var container = registry.container(); + let registry = new Registry(); + let container = registry.container(); registry.register('source:main', Source); registry.register('model:user', User); registry.register('model:post', Post); // injecting one fullName on another fullName // eg. each user model gets a post model registry.injection('model:user', 'post', 'model:post'); // injecting one fullName on another type registry.injection('model', 'source', 'source:main'); - var user = container.lookup('model:user'); - var post = container.lookup('model:post'); + let user = container.lookup('model:user'); + let post = container.lookup('model:post'); user.source instanceof Source; //=> true post.source instanceof Source; //=> true user.post instanceof Post; //=> true // and both models share the same source user.source === post.source; //=> true @@ -2146,15 +2153,15 @@ all factory of one type to be injected with a reference to another object. For example, provided each factory of type `model` needed a `store`. one would do the following: ```javascript - var registry = new Registry(); + let registry = new Registry(); registry.register('store:main', SomeStore); registry.factoryTypeInjection('model', 'store', 'store:main'); - var store = registry.lookup('store:main'); - var UserFactory = registry.lookupFactory('model:user'); + let store = registry.lookup('store:main'); + let UserFactory = registry.lookupFactory('model:user'); UserFactory.store instanceof SomeStore; //=> true ``` @private @method factoryTypeInjection @param {String} type @@ -2179,23 +2186,23 @@ Two forms of injections are possible: * Injecting one fullName on another fullName * Injecting one fullName on a type Example: ```javascript - var registry = new Registry(); - var container = registry.container(); + let registry = new Registry(); + let container = registry.container(); registry.register('store:main', Store); registry.register('store:secondary', OtherStore); registry.register('model:user', User); registry.register('model:post', Post); // injecting one fullName on another type registry.factoryInjection('model', 'store', 'store:main'); // injecting one fullName on another fullName registry.factoryInjection('model:post', 'secondaryStore', 'store:secondary'); - var UserFactory = container.lookupFactory('model:user'); - var PostFactory = container.lookupFactory('model:post'); - var store = container.lookup('store:main'); + let UserFactory = container.lookupFactory('model:user'); + let PostFactory = container.lookupFactory('model:post'); + let store = container.lookup('store:main'); UserFactory.store instanceof Store; //=> true UserFactory.secondaryStore instanceof OtherStore; //=> false PostFactory.store instanceof Store; //=> true PostFactory.secondaryStore instanceof OtherStore; //=> true // and both models share the same source instance @@ -2256,11 +2263,11 @@ return _emberMetalAssign.default({}, fallbackKnown, localKnown, resolverKnown); }, validateFullName: function (fullName) { if (!this.isValidFullName(fullName)) { - throw new TypeError('Invalid Fullname, expected: `type:name` got: ' + fullName); + throw new TypeError('Invalid Fullname, expected: \'type:name\' got: ' + fullName); } return true; }, @@ -2271,17 +2278,17 @@ validateInjections: function (injections) { if (!injections) { return; } - var fullName; + var fullName = undefined; for (var i = 0; i < injections.length; i++) { fullName = injections[i].fullName; if (!this.has(fullName)) { - throw new Error('Attempting to inject an unknown injection: `' + fullName + '`'); + throw new Error('Attempting to inject an unknown injection: \'' + fullName + '\''); } } }, normalizeInjectionsHash: function (hash) { @@ -2342,11 +2349,11 @@ /** Given a fullName and a source fullName returns the fully resolved fullName. Used to allow for local lookup. ```javascript - var registry = new Registry(); + let registry = new Registry(); // the twitter factory is added to the module system registry.expandLocalLookup('component:post-title', { source: 'template:post' }) // => component:post/post-title ``` @@ -2432,11 +2439,11 @@ function has(registry, fullName, source) { return registry.resolve(fullName, { source: source }) !== undefined; } var privateNames = _emberMetalDictionary.default(null); - var privateSuffix = Math.floor(Math.random() * new Date()) + ''; + var privateSuffix = '' + Math.random() + Date.now(); function privatize(_ref) { var fullName = _ref[0]; var name = privateNames[fullName]; @@ -2449,12 +2456,10 @@ var type = _fullName$split[0]; var rawName = _fullName$split[1]; return privateNames[fullName] = _emberMetalUtils.intern(type + ':' + rawName + '-' + privateSuffix); } - - exports.default = Registry; }); enifed('dag-map', ['exports', 'vertex', 'visit'], function (exports, _vertex, _visit) { 'use strict'; exports.default = DAG; @@ -3697,34 +3702,54 @@ function preferAttr(tagName, propName) { var tag = ATTR_OVERRIDES[tagName.toUpperCase()]; return tag && tag[propName.toLowerCase()] || false; } }); -enifed('ember-application/index', ['exports', 'ember-metal/core', 'ember-metal/features', 'ember-runtime/system/lazy_load', 'ember-application/system/resolver', 'ember-application/system/application', 'ember-application/system/application-instance', 'ember-application/system/engine', 'ember-application/system/engine-instance'], function (exports, _emberMetalCore, _emberMetalFeatures, _emberRuntimeSystemLazy_load, _emberApplicationSystemResolver, _emberApplicationSystemApplication, _emberApplicationSystemApplicationInstance, _emberApplicationSystemEngine, _emberApplicationSystemEngineInstance) { +enifed('ember-application/index', ['exports', 'ember-metal/core', 'ember-metal/features', 'ember-runtime/system/lazy_load', 'ember-application/system/resolver', 'ember-application/system/application', 'ember-application/system/application-instance', 'ember-application/system/engine', 'ember-application/system/engine-instance', 'ember-application/initializers/dom-templates'], function (exports, _emberMetalCore, _emberMetalFeatures, _emberRuntimeSystemLazy_load, _emberApplicationSystemResolver, _emberApplicationSystemApplication, _emberApplicationSystemApplicationInstance, _emberApplicationSystemEngine, _emberApplicationSystemEngineInstance, _emberApplicationInitializersDomTemplates) { 'use strict'; _emberMetalCore.default.Application = _emberApplicationSystemApplication.default; _emberMetalCore.default.Resolver = _emberApplicationSystemResolver.Resolver; _emberMetalCore.default.DefaultResolver = _emberApplicationSystemResolver.default; - if (false) { + if (true) { _emberMetalCore.default.Engine = _emberApplicationSystemEngine.default; // Expose `EngineInstance` and `ApplicationInstance` for easy overriding. // Reanalyze whether to continue exposing these after feature flag is removed. _emberMetalCore.default.EngineInstance = _emberApplicationSystemEngineInstance.default; _emberMetalCore.default.ApplicationInstance = _emberApplicationSystemApplicationInstance.default; } + // add domTemplates initializer (only does something if `ember-template-compiler` + // is loaded already) + _emberRuntimeSystemLazy_load.runLoadHooks('Ember.Application', _emberApplicationSystemApplication.default); }); // reexports /** @module ember @submodule ember-application */ +enifed('ember-application/initializers/dom-templates', ['exports', 'require', 'ember-environment', 'ember-application/system/application'], function (exports, _require, _emberEnvironment, _emberApplicationSystemApplication) { + 'use strict'; + + var bootstrap = function () {}; + + _emberApplicationSystemApplication.default.initializer({ + name: 'domTemplates', + initialize: function () { + var bootstrapModuleId = 'ember-template-compiler/system/bootstrap'; + if (_emberEnvironment.environment.hasDOM && _require.has(bootstrapModuleId)) { + bootstrap = _require.default(bootstrapModuleId).default; + } + + bootstrap(); + } + }); +}); enifed('ember-application/system/application-instance', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/run_loop', 'ember-metal/computed', 'ember-runtime/mixins/registry_proxy', 'ember-metal/assign', 'ember-environment', 'ember-runtime/ext/rsvp', 'ember-views/system/jquery', 'ember-application/system/engine-instance'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalRun_loop, _emberMetalComputed, _emberRuntimeMixinsRegistry_proxy, _emberMetalAssign, _emberEnvironment, _emberRuntimeExtRsvp, _emberViewsSystemJquery, _emberApplicationSystemEngineInstance) { /** @module ember @submodule ember-application */ @@ -4190,11 +4215,11 @@ } }); exports.default = ApplicationInstance; }); -enifed('ember-application/system/application', ['exports', 'ember-environment', 'ember-metal/debug', 'ember-metal/libraries', 'ember-metal/testing', 'ember-metal/property_get', 'ember-runtime/system/namespace', 'ember-runtime/system/lazy_load', 'ember-metal/run_loop', 'ember-views/views/view', '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-application/system/application-instance', 'ember-runtime/mixins/registry_proxy', 'container/registry', 'ember-runtime/ext/rsvp', 'ember-application/system/engine', 'require'], function (exports, _emberEnvironment, _emberMetalDebug, _emberMetalLibraries, _emberMetalTesting, _emberMetalProperty_get, _emberRuntimeSystemNamespace, _emberRuntimeSystemLazy_load, _emberMetalRun_loop, _emberViewsViewsView, _emberViewsSystemEvent_dispatcher, _emberViewsSystemJquery, _emberRoutingSystemRoute, _emberRoutingSystemRouter, _emberRoutingLocationHash_location, _emberRoutingLocationHistory_location, _emberRoutingLocationAuto_location, _emberRoutingLocationNone_location, _emberRoutingSystemCache, _emberApplicationSystemApplicationInstance, _emberRuntimeMixinsRegistry_proxy, _containerRegistry, _emberRuntimeExtRsvp, _emberApplicationSystemEngine, _require) { +enifed('ember-application/system/application', ['exports', 'ember-environment', 'ember-metal/debug', 'ember-metal/libraries', 'ember-metal/testing', 'ember-metal/property_get', 'ember-runtime/system/namespace', 'ember-runtime/system/lazy_load', 'ember-metal/run_loop', '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-application/system/application-instance', 'ember-runtime/mixins/registry_proxy', 'container/registry', 'ember-runtime/ext/rsvp', 'ember-application/system/engine', 'require'], function (exports, _emberEnvironment, _emberMetalDebug, _emberMetalLibraries, _emberMetalTesting, _emberMetalProperty_get, _emberRuntimeSystemNamespace, _emberRuntimeSystemLazy_load, _emberMetalRun_loop, _emberViewsSystemEvent_dispatcher, _emberViewsSystemJquery, _emberRoutingSystemRoute, _emberRoutingSystemRouter, _emberRoutingLocationHash_location, _emberRoutingLocationHistory_location, _emberRoutingLocationAuto_location, _emberRoutingLocationNone_location, _emberRoutingSystemCache, _emberApplicationSystemApplicationInstance, _emberRuntimeMixinsRegistry_proxy, _containerRegistry, _emberRuntimeExtRsvp, _emberApplicationSystemEngine, _require) { /** @module ember @submodule ember-application */ 'use strict'; @@ -4276,11 +4301,11 @@ If there is a bubbling browser event that Ember does not listen for by default, you can specify custom events and their corresponding view method names by setting the application's `customEvents` property: ```javascript - var App = Ember.Application.create({ + let App = Ember.Application.create({ customEvents: { // add support for the paste event paste: 'paste' } }); @@ -4289,11 +4314,11 @@ To prevent Ember from setting up a listener for a default event, specify the event name with a `null` value in the `customEvents` property: ```javascript - var App = Ember.Application.create({ + let App = Ember.Application.create({ customEvents: { // prevent listeners for mouseenter/mouseleave events mouseenter: null, mouseleave: null } @@ -4307,11 +4332,11 @@ For example, if only events inside a DOM element with the ID of `ember-app` should be delegated, set your application's `rootElement` property: ```javascript - var App = Ember.Application.create({ + let App = Ember.Application.create({ rootElement: '#ember-app' }); ``` The `rootElement` can be either a DOM element or a jQuery-compatible selector @@ -4349,11 +4374,11 @@ between routes can be logged with the `LOG_TRANSITIONS` flag, and more detailed intra-transition logging can be logged with the `LOG_TRANSITIONS_INTERNAL` flag: ```javascript - var App = Ember.Application.create({ + let App = Ember.Application.create({ LOG_TRANSITIONS: true, // basic logging of successful transitions LOG_TRANSITIONS_INTERNAL: true // detailed logging of all routing steps }); ``` @@ -4416,20 +4441,20 @@ corresponding view method name as the value. Setting an event to a value of `null` will prevent a default event listener from being added for that event. To add new events to be listened to: ```javascript - var App = Ember.Application.create({ + let App = Ember.Application.create({ customEvents: { // add support for the paste event paste: 'paste' } }); ``` To prevent default events from being listened to: ```javascript - var App = Ember.Application.create({ + let App = Ember.Application.create({ customEvents: { // remove support for mouseenter / mouseleave events mouseenter: null, mouseleave: null } @@ -4458,11 +4483,11 @@ /** Whether the application should be configured for the legacy "globals mode". Under this mode, the Application object serves as a global namespace for all classes. ```javascript - var App = Ember.Application.create({ + let App = Ember.Application.create({ ... }); App.Router.reopen({ location: 'none' }); @@ -4553,14 +4578,14 @@ /* Build the deprecated instance for legacy globals mode support. Called when creating and resetting the application. This is orthogonal to autoboot: the deprecated instance needs to be created at Application construction (not boot) time to expose - App.__container__ and the global Ember.View.views registry. If - autoboot sees that this instance exists, it will continue booting - it to avoid doing unncessary work (as opposed to building a new - instance at boot time), but they are otherwise unrelated. + App.__container__. If autoboot sees that this instance exists, + it will continue booting it to avoid doing unncessary work (as + opposed to building a new instance at boot time), but they are + otherwise unrelated. @private @method _buildDeprecatedInstance */ _buildDeprecatedInstance: function () { // Build a default instance @@ -4568,14 +4593,10 @@ // Legacy support for App.__container__ and other global methods // on App that rely on a single, default instance. this.__deprecatedInstance__ = instance; this.__container__ = instance.__container__; - - // For the default instance only, set the view registry to the global - // Ember.View.views hash for backwards-compatibility. - _emberViewsViewsView.default.views = instance.lookup('-view-registry:main'); }, /** Automatically kick-off the boot process for the application once the DOM has become ready. @@ -4636,11 +4657,11 @@ /** Use this to defer readiness until some condition is true. Example: ```javascript - var App = Ember.Application.create(); + let App = Ember.Application.create(); App.deferReadiness(); // Ember.$ is a reference to the jQuery object/function Ember.$.getJSON('/auth-token', function(token) { App.token = token; App.advanceReadiness(); @@ -4715,20 +4736,10 @@ _bootSync: function () { if (this._booted) { return; } - if (_emberEnvironment.ENV._ENABLE_LEGACY_VIEW_SUPPORT && !warnedAboutLegacyViewAddon) { - - warnedAboutLegacyViewAddon = true; - } - - if (_emberEnvironment.ENV._ENABLE_LEGACY_CONTROLLER_SUPPORT && !warnedAboutLegacyControllerAddon) { - - warnedAboutLegacyControllerAddon = true; - } - // Even though this returns synchronously, we still need to make sure the // boot promise exists for book-keeping purposes: if anything went wrong in // the boot process, we need to store the error as a rejection on the boot // promise so that a future caller of `boot()` can tell what failed. var defer = this._bootResolver = new _emberRuntimeExtRsvp.default.defer(); @@ -4755,11 +4766,11 @@ 2. Destroy all objects in the container 3. Create a new application container 4. Re-route to the existing url Typical Example: ```javascript - var App; + let App; run(function() { App = Ember.Application.create(); }); module('acceptance test', { setup: function() { @@ -4776,11 +4787,11 @@ Advanced Example: Occasionally you may want to prevent the app from initializing during setup. This could enable extra configuration, or enable asserting prior to the app becoming ready. ```javascript - var App; + let App; run(function() { App = Ember.Application.create(); }); module('acceptance test', { setup: function() { @@ -5254,11 +5265,11 @@ _bootSync: function (options) { if (this._booted) { return this; } - if (false) { + if (true) { this.cloneParentDependencies(); } this.base.runInstanceInitializers(this); @@ -5287,11 +5298,11 @@ this._super.apply(this, arguments); _emberMetalRun_loop.default(this.__container__, 'destroy'); } }); - if (false) { + if (true) { EngineInstance.reopen({ /** Build a new `Ember.EngineInstance` that's a child of this instance. Engines must be registered by name with their parent engine (or application). @@ -5325,16 +5336,16 @@ cloneParentDependencies: function () { var _this2 = this; var parent = _emberApplicationSystemEngineParent.getEngineParent(this); - ['route:basic', 'event_dispatcher:main', _containerRegistry.privatize(_templateObject), 'service:-routing'].forEach(function (key) { - _this2.register(key, parent.resolveRegistration(key)); + ['route:basic', 'event_dispatcher:main', 'service:-routing'].forEach(function (key) { + return _this2.register(key, parent.resolveRegistration(key)); }); - ['router:main', '-view-registry:main'].forEach(function (key) { - _this2.register(key, parent.lookup(key), { instantiate: false }); + ['router:main', _containerRegistry.privatize(_templateObject), '-view-registry:main'].forEach(function (key) { + return _this2.register(key, parent.lookup(key), { instantiate: false }); }); } }); } @@ -5378,11 +5389,11 @@ function setEngineParent(engine, parent) { engine[ENGINE_PARENT] = parent; } }); -enifed('ember-application/system/engine', ['exports', 'ember-runtime/system/namespace', 'container/registry', 'ember-runtime/mixins/registry_proxy', 'dag-map', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/debug', 'ember-metal/utils', 'ember-metal/empty_object', 'ember-application/system/resolver', 'ember-application/system/engine-instance', 'ember-metal/features', 'ember-metal/symbol', 'ember-runtime/controllers/controller', 'ember-routing/services/routing', 'ember-extension-support/container_debug_adapter', 'require'], function (exports, _emberRuntimeSystemNamespace, _containerRegistry, _emberRuntimeMixinsRegistry_proxy, _dagMap, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalDebug, _emberMetalUtils, _emberMetalEmpty_object, _emberApplicationSystemResolver, _emberApplicationSystemEngineInstance, _emberMetalFeatures, _emberMetalSymbol, _emberRuntimeControllersController, _emberRoutingServicesRouting, _emberExtensionSupportContainer_debug_adapter, _require) { +enifed('ember-application/system/engine', ['exports', 'ember-runtime/system/namespace', 'container/registry', 'ember-runtime/mixins/registry_proxy', 'dag-map', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/debug', 'ember-metal/utils', 'ember-metal/empty_object', 'ember-application/system/resolver', 'ember-application/system/engine-instance', 'ember-metal/features', 'ember-metal/symbol', 'ember-runtime/controllers/controller', 'ember-routing/services/routing', 'ember-extension-support/container_debug_adapter', 'ember-views/component_lookup', 'require'], function (exports, _emberRuntimeSystemNamespace, _containerRegistry, _emberRuntimeMixinsRegistry_proxy, _dagMap, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalDebug, _emberMetalUtils, _emberMetalEmpty_object, _emberApplicationSystemResolver, _emberApplicationSystemEngineInstance, _emberMetalFeatures, _emberMetalSymbol, _emberRuntimeControllersController, _emberRoutingServicesRouting, _emberExtensionSupportContainer_debug_adapter, _emberViewsComponent_lookup, _require) { /** @module ember @submodule ember-application */ 'use strict'; @@ -5526,19 +5537,19 @@ _runInitializer: function (bucketName, cb) { var initializersByName = _emberMetalProperty_get.get(this.constructor, bucketName); var initializers = props(initializersByName); var graph = new _dagMap.default(); - var initializer; + var initializer = undefined; for (var i = 0; i < initializers.length; i++) { initializer = initializersByName[initializers[i]]; graph.addEdges(initializer.name, initializer, initializer.before, initializer.after); } graph.topsort(function (vertex) { - cb(vertex.name, vertex.value); + return cb(vertex.name, vertex.value); }); } }); Engine.reopenClass({ @@ -5804,10 +5815,12 @@ registry.register('controller:basic', _emberRuntimeControllersController.default, { instantiate: false }); registry.injection('service:-dom-helper', 'document', 'service:-document'); registry.injection('view', '_viewRegistry', '-view-registry:main'); + registry.injection('renderer', '_viewRegistry', '-view-registry:main'); + registry.injection('event_dispatcher:main', '_viewRegistry', '-view-registry:main'); registry.injection('route', '_topLevelViewTemplate', 'template:-outlet'); registry.injection('view:-outlet', 'namespace', 'application:main'); @@ -5830,10 +5843,12 @@ registry.injection('container-debug-adapter:main', 'resolver', 'resolver-for-debugging:main'); registry.injection('data-adapter:main', 'containerDebugAdapter', 'container-debug-adapter:main'); // Custom resolver authors may want to register their own ContainerDebugAdapter with this key registry.register('container-debug-adapter:main', _emberExtensionSupportContainer_debug_adapter.default); + + registry.register('component-lookup:main', _emberViewsComponent_lookup.default); } exports.default = Engine; }); enifed('ember-application/system/resolver', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-runtime/system/string', 'ember-runtime/system/object', 'ember-runtime/system/namespace', 'ember-application/utils/validate-type', 'ember-metal/dictionary', 'ember-templates/template_registry'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberRuntimeSystemString, _emberRuntimeSystemObject, _emberRuntimeSystemNamespace, _emberApplicationUtilsValidateType, _emberMetalDictionary, _emberTemplatesTemplate_registry) { @@ -5892,11 +5907,11 @@ ```javascript App = Ember.Application.create({ Resolver: Ember.DefaultResolver.extend({ resolveTemplate: function(parsedName) { - var resolvedTemplate = this._super(parsedName); + let resolvedTemplate = this._super(parsedName); if (resolvedTemplate) { return resolvedTemplate; } return Ember.TEMPLATES['not_found']; } }) }); @@ -6067,11 +6082,11 @@ @method lookupDescription @protected */ lookupDescription: function (fullName) { var parsedName = this.parseName(fullName); - var description; + var description = undefined; if (parsedName.type === 'template') { return 'template at ' + parsedName.fullNameWithoutType.replace(/\./g, '/'); } @@ -6159,13 +6174,11 @@ */ resolveModel: function (parsedName) { var className = _emberRuntimeSystemString.classify(parsedName.name); var factory = _emberMetalProperty_get.get(parsedName.root, className); - if (factory) { - return factory; - } + return factory; }, /** Look up the specified object (from parsedName) on the appropriate namespace (usually on the Application) @param {Object} parsedName a parseName object with the parsed @@ -6185,13 +6198,11 @@ @protected */ resolveOther: function (parsedName) { var className = _emberRuntimeSystemString.classify(parsedName.name) + _emberRuntimeSystemString.classify(parsedName.type); var factory = _emberMetalProperty_get.get(parsedName.root, className); - if (factory) { - return factory; - } + return factory; }, resolveMain: function (parsedName) { var className = _emberRuntimeSystemString.classify(parsedName.type); return _emberMetalProperty_get.get(parsedName.root, className); @@ -6202,11 +6213,12 @@ @param {Boolean} found @param {Object} parsedName @private */ _logLookup: function (found, parsedName) { - var symbol, padding; + var symbol = undefined, + padding = undefined; if (found) { symbol = '[✓]'; } else { symbol = '[ ]'; @@ -6637,11 +6649,11 @@ ```javascript Application.initializer({ name: "containerDebugAdapter", - initialize: function(application) { + initialize(application) { application.register('container-debug-adapter:main', require('app/container-debug-adapter')); } }); ``` @@ -6834,11 +6846,11 @@ watchModelTypes: function (typesAdded, typesUpdated) { var _this = this; var modelTypes = this.getModelTypes(); var releaseMethods = _emberRuntimeSystemNative_array.A(); - var typesToSend; + var typesToSend = undefined; typesToSend = modelTypes.map(function (type) { var klass = type.klass; var wrapped = _this.wrapModelType(klass, type.name); releaseMethods.push(_this.observeModelType(type.name, typesUpdated)); @@ -6886,15 +6898,15 @@ var _this2 = this; var releaseMethods = _emberRuntimeSystemNative_array.A(); var klass = this._nameToClass(modelName); var records = this.getRecords(klass, modelName); - var release; + var release = undefined; - var recordUpdated = function (updatedRecord) { + function recordUpdated(updatedRecord) { recordsUpdated([updatedRecord]); - }; + } var recordsToSend = records.map(function (record) { releaseMethods.push(_this2.observeRecord(record, recordUpdated)); return _this2.wrapRecord(record); }); @@ -6917,11 +6929,11 @@ } }; _emberRuntimeMixinsArray.addArrayObserver(records, this, observer); release = function () { releaseMethods.forEach(function (fn) { - fn(); + return fn(); }); _emberRuntimeMixinsArray.removeArrayObserver(records, _this2, observer); _this2.releaseMethods.removeObject(release); }; @@ -6937,11 +6949,11 @@ @method willDestroy */ willDestroy: function () { this._super.apply(this, arguments); this.releaseMethods.forEach(function (fn) { - fn(); + return fn(); }); }, /** Detect whether a class is a model. @@ -6982,13 +6994,14 @@ var _this3 = this; var klass = this._nameToClass(modelName); var records = this.getRecords(klass, modelName); - var onChange = function () { - typesUpdated([_this3.wrapModelType(klass, modelName)]); - }; + function onChange() { + typesUpdated([this.wrapModelType(klass, modelName)]); + } + var observer = { didChange: function () { _emberMetalRun_loop.default.scheduleOnce('actions', this, onChange); }, willChange: function () { @@ -6997,11 +7010,11 @@ }; _emberRuntimeMixinsArray.addArrayObserver(records, this, observer); var release = function () { - _emberRuntimeMixinsArray.removeArrayObserver(records, _this3, observer); + return _emberRuntimeMixinsArray.removeArrayObserver(records, _this3, observer); }; return release; }, @@ -7021,11 +7034,11 @@ object: {Class} The actual Model type class. release: {Function} The function to remove observers. */ wrapModelType: function (klass, name) { var records = this.getRecords(klass, name); - var typeToSend; + var typeToSend = undefined; typeToSend = { name: name, count: _emberMetalProperty_get.get(records, 'length'), columns: this.columnsForType(klass), @@ -7043,11 +7056,11 @@ */ getModelTypes: function () { var _this4 = this; var containerDebugAdapter = this.get('containerDebugAdapter'); - var types; + var types = undefined; if (containerDebugAdapter.canCatalogEntriesByType('model')) { types = containerDebugAdapter.catalogEntriesByType('model'); } else { types = this._getObjectsOnNamespaces(); @@ -7089,15 +7102,15 @@ // we should not call `lookupFactory` on non-models // (especially when `EmberENV.MODEL_FACTORY_INJECTIONS` is `true`) if (!_this5.detect(namespace[key])) { continue; } - var name = _emberRuntimeSystemString.dasherize(key); + var _name = _emberRuntimeSystemString.dasherize(key); if (!(namespace instanceof _emberApplicationSystemApplication.default) && namespace.toString()) { - name = namespace + '/' + name; + _name = namespace + '/' + _name; } - types.push(name); + types.push(_name); } }); return types; }, @@ -7201,488 +7214,16 @@ _emberMetalCore.default.DataAdapter = _emberExtensionSupportData_adapter.default; _emberMetalCore.default.ContainerDebugAdapter = _emberExtensionSupportContainer_debug_adapter.default; }); // reexports -enifed('ember-htmlbars-template-compiler/index', ['exports', 'ember-htmlbars-template-compiler/system/compile', 'ember-htmlbars-template-compiler/system/precompile', 'ember-htmlbars-template-compiler/system/template', 'ember-htmlbars-template-compiler/system/compile-options'], function (exports, _emberHtmlbarsTemplateCompilerSystemCompile, _emberHtmlbarsTemplateCompilerSystemPrecompile, _emberHtmlbarsTemplateCompilerSystemTemplate, _emberHtmlbarsTemplateCompilerSystemCompileOptions) { +enifed('ember-htmlbars/component', ['exports', 'ember-metal/debug', 'ember-metal/mixin', 'ember-environment', 'ember-runtime/mixins/target_action_support', 'ember-views/mixins/action_support', 'ember-views/views/view', 'ember-metal/computed', 'container/owner', 'ember-metal/symbol'], function (exports, _emberMetalDebug, _emberMetalMixin, _emberEnvironment, _emberRuntimeMixinsTarget_action_support, _emberViewsMixinsAction_support, _emberViewsViewsView, _emberMetalComputed, _containerOwner, _emberMetalSymbol) { 'use strict'; - exports.compile = _emberHtmlbarsTemplateCompilerSystemCompile.default; - exports.precompile = _emberHtmlbarsTemplateCompilerSystemPrecompile.default; - exports.template = _emberHtmlbarsTemplateCompilerSystemTemplate.default; - exports.defaultCompileOptions = _emberHtmlbarsTemplateCompilerSystemCompileOptions.default; - exports.registerPlugin = _emberHtmlbarsTemplateCompilerSystemCompileOptions.registerPlugin; -}); -enifed('ember-htmlbars-template-compiler/plugins/transform-closure-component-attrs-into-mut', ['exports'], function (exports) { - 'use strict'; - - function TransformClosureComponentAttrsIntoMut() { - // set later within HTMLBars to the syntax package - this.syntax = null; - } - - /** - @private - @method transform - @param {AST} ast The AST to be transformed. - */ - TransformClosureComponentAttrsIntoMut.prototype.transform = function TransformClosureComponentAttrsIntoMut_transform(ast) { - var b = this.syntax.builders; - - this.syntax.traverse(ast, { - SubExpression: function (node) { - if (isComponentClosure(node)) { - mutParameters(b, node); - } - } - }); - - return ast; - }; - - function isComponentClosure(node) { - return node.type === 'SubExpression' && node.path.original === 'component'; - } - - function mutParameters(builder, node) { - for (var i = 1; i < node.params.length; i++) { - if (node.params[i].type === 'PathExpression') { - node.params[i] = builder.sexpr(builder.path('@mut'), [node.params[i]]); - } - } - - each(node.hash.pairs, function (pair) { - var value = pair.value; - - if (value.type === 'PathExpression') { - pair.value = builder.sexpr(builder.path('@mut'), [pair.value]); - } - }); - } - - function each(list, callback) { - for (var i = 0, l = list.length; i < l; i++) { - callback(list[i]); - } - } - - exports.default = TransformClosureComponentAttrsIntoMut; -}); -enifed('ember-htmlbars-template-compiler/plugins/transform-component-attrs-into-mut', ['exports'], function (exports) { - 'use strict'; - - function TransformComponentAttrsIntoMut() { - // set later within HTMLBars to the syntax package - this.syntax = null; - } - - /** - @private - @method transform - @param {AST} ast The AST to be transformed. - */ - TransformComponentAttrsIntoMut.prototype.transform = function TransformComponentAttrsIntoMut_transform(ast) { - var b = this.syntax.builders; - var walker = new this.syntax.Walker(); - - walker.visit(ast, function (node) { - if (!validate(node)) { - return; - } - - each(node.hash.pairs, function (pair) { - var value = pair.value; - - if (value.type === 'PathExpression') { - pair.value = b.sexpr(b.path('@mut'), [pair.value]); - } - }); - }); - - return ast; - }; - - function validate(node) { - return node.type === 'BlockStatement' || node.type === 'MustacheStatement'; - } - - function each(list, callback) { - for (var i = 0; i < list.length; i++) { - callback(list[i]); - } - } - - exports.default = TransformComponentAttrsIntoMut; -}); -enifed('ember-htmlbars-template-compiler/plugins/transform-component-curly-to-readonly', ['exports'], function (exports) { - 'use strict'; - - function TransformComponentCurlyToReadonly() { - // set later within HTMLBars to the syntax package - this.syntax = null; - } - - /** - @private - @method transform - @param {AST} ast The AST to be transformed. - */ - TransformComponentCurlyToReadonly.prototype.transform = function TransformComponetnCurlyToReadonly_transform(ast) { - var b = this.syntax.builders; - var walker = new this.syntax.Walker(); - - walker.visit(ast, function (node) { - if (!validate(node)) { - return; - } - - each(node.attributes, function (attr) { - if (attr.value.type !== 'MustacheStatement') { - return; - } - if (attr.value.params.length || attr.value.hash.pairs.length) { - return; - } - - attr.value = b.mustache(b.path('readonly'), [attr.value.path], null, !attr.value.escape); - }); - }); - - return ast; - }; - - function validate(node) { - return node.type === 'ComponentNode'; - } - - function each(list, callback) { - for (var i = 0; i < list.length; i++) { - callback(list[i]); - } - } - - exports.default = TransformComponentCurlyToReadonly; -}); -enifed('ember-htmlbars-template-compiler/plugins/transform-old-class-binding-syntax', ['exports'], function (exports) { - 'use strict'; - - exports.default = TransformOldClassBindingSyntax; - - function TransformOldClassBindingSyntax(options) { - this.syntax = null; - this.options = options; - } - - TransformOldClassBindingSyntax.prototype.transform = function TransformOldClassBindingSyntax_transform(ast) { - var b = this.syntax.builders; - var walker = new this.syntax.Walker(); - - walker.visit(ast, function (node) { - if (!validate(node)) { - return; - } - - var allOfTheMicrosyntaxes = []; - var allOfTheMicrosyntaxIndexes = []; - var classPair = undefined; - - each(node.hash.pairs, function (pair, index) { - var key = pair.key; - - if (key === 'classBinding' || key === 'classNameBindings') { - allOfTheMicrosyntaxIndexes.push(index); - allOfTheMicrosyntaxes.push(pair); - } else if (key === 'class') { - classPair = pair; - } - }); - - if (allOfTheMicrosyntaxes.length === 0) { - return; - } - - var classValue = []; - - if (classPair) { - classValue.push(classPair.value); - classValue.push(b.string(' ')); - } else { - classPair = b.pair('class', null); - node.hash.pairs.push(classPair); - } - - each(allOfTheMicrosyntaxIndexes, function (index) { - node.hash.pairs.splice(index, 1); - }); - - each(allOfTheMicrosyntaxes, function (_ref) { - var value = _ref.value; - var loc = _ref.loc; - - var sexprs = []; - // TODO: add helpful deprecation when both `classNames` and `classNameBindings` can - // be removed. - - if (value.type === 'StringLiteral') { - var microsyntax = parseMicrosyntax(value.original); - - buildSexprs(microsyntax, sexprs, b); - - classValue.push.apply(classValue, sexprs); - } - }); - - var hash = b.hash(); - classPair.value = b.sexpr(b.string('concat'), classValue, hash); - }); - - return ast; - }; - - function buildSexprs(microsyntax, sexprs, b) { - for (var i = 0; i < microsyntax.length; i++) { - var _microsyntax$i = microsyntax[i]; - var propName = _microsyntax$i[0]; - var activeClass = _microsyntax$i[1]; - var inactiveClass = _microsyntax$i[2]; - - var sexpr = undefined; - - // :my-class-name microsyntax for static values - if (propName === '') { - sexpr = b.string(activeClass); - } else { - var params = [b.path(propName)]; - - if (activeClass) { - params.push(b.string(activeClass)); - } else { - var sexprParams = [b.string(propName), b.path(propName)]; - - var hash = b.hash(); - if (activeClass !== undefined) { - hash.pairs.push(b.pair('activeClass', b.string(activeClass))); - } - - if (inactiveClass !== undefined) { - hash.pairs.push(b.pair('inactiveClass', b.string(inactiveClass))); - } - - params.push(b.sexpr(b.string('-normalize-class'), sexprParams, hash)); - } - - if (inactiveClass) { - params.push(b.string(inactiveClass)); - } - - sexpr = b.sexpr(b.string('if'), params); - } - - sexprs.push(sexpr); - sexprs.push(b.string(' ')); - } - } - - function validate(node) { - return node.type === 'BlockStatement' || node.type === 'MustacheStatement'; - } - - function each(list, callback) { - for (var i = 0; i < list.length; i++) { - callback(list[i], i); - } - } - - function parseMicrosyntax(string) { - var segments = string.split(' '); - - for (var i = 0; i < segments.length; i++) { - segments[i] = segments[i].split(':'); - } - - return segments; - } -}); -enifed('ember-htmlbars-template-compiler/system/compile-options', ['exports', 'ember/version', 'ember-metal/assign', 'ember-template-compiler/plugins', 'ember-htmlbars-template-compiler/plugins/transform-closure-component-attrs-into-mut', 'ember-htmlbars-template-compiler/plugins/transform-component-attrs-into-mut', 'ember-htmlbars-template-compiler/plugins/transform-component-curly-to-readonly', 'ember-htmlbars-template-compiler/plugins/transform-old-class-binding-syntax'], function (exports, _emberVersion, _emberMetalAssign, _emberTemplateCompilerPlugins, _emberHtmlbarsTemplateCompilerPluginsTransformClosureComponentAttrsIntoMut, _emberHtmlbarsTemplateCompilerPluginsTransformComponentAttrsIntoMut, _emberHtmlbarsTemplateCompilerPluginsTransformComponentCurlyToReadonly, _emberHtmlbarsTemplateCompilerPluginsTransformOldClassBindingSyntax) { - /** - @module ember - @submodule ember-htmlbars - */ - - 'use strict'; - - exports.registerPlugin = registerPlugin; - exports.removePlugin = removePlugin; - - var compileOptions = undefined; - - var PLUGINS = [].concat(_emberTemplateCompilerPlugins.default, [ - - // the following are ember-htmlbars specific - _emberHtmlbarsTemplateCompilerPluginsTransformClosureComponentAttrsIntoMut.default, _emberHtmlbarsTemplateCompilerPluginsTransformComponentAttrsIntoMut.default, _emberHtmlbarsTemplateCompilerPluginsTransformComponentCurlyToReadonly.default, _emberHtmlbarsTemplateCompilerPluginsTransformOldClassBindingSyntax.default]); - - exports.PLUGINS = PLUGINS; - var USER_PLUGINS = []; - - function mergePlugins(options) { - options = options || {}; - options = _emberMetalAssign.default({}, options); - if (!options.plugins) { - options.plugins = { ast: [].concat(USER_PLUGINS, PLUGINS) }; - } else { - var potententialPugins = [].concat(USER_PLUGINS, PLUGINS); - var pluginsToAdd = potententialPugins.filter(function (plugin) { - return options.plugins.ast.indexOf(plugin) === -1; - }); - - options.plugins.ast = options.plugins.ast.slice().concat(pluginsToAdd); - } - - return options; - } - - function registerPlugin(type, PluginClass) { - if (type !== 'ast') { - throw new Error('Attempting to register ' + PluginClass + ' as "' + type + '" which is not a valid HTMLBars plugin type.'); - } - - if (USER_PLUGINS.indexOf(PluginClass) === -1) { - USER_PLUGINS = [PluginClass].concat(USER_PLUGINS); - } - } - - function removePlugin(type, PluginClass) { - if (type !== 'ast') { - throw new Error('Attempting to unregister ' + PluginClass + ' as "' + type + '" which is not a valid Glimmer plugin type.'); - } - - USER_PLUGINS = USER_PLUGINS.filter(function (plugin) { - return plugin !== PluginClass; - }); - } - - /** - @private - @property compileOptions - */ - compileOptions = function (_options) { - var disableComponentGeneration = true; - - var options = undefined; - // When calling `Ember.Handlebars.compile()` a second argument of `true` - // had a special meaning (long since lost), this just gaurds against - // `options` being true, and causing an error during compilation. - if (_options === true) { - options = {}; - } else { - options = _options || {}; - } - - options.disableComponentGeneration = disableComponentGeneration; - - options = mergePlugins(options); - - options.buildMeta = function buildMeta(program) { - return { - revision: 'Ember@' + _emberVersion.default, - loc: program.loc, - moduleName: options.moduleName - }; - }; - - return options; - }; - - exports.default = compileOptions; -}); -enifed('ember-htmlbars-template-compiler/system/compile', ['exports', 'require', 'ember-htmlbars-template-compiler/system/template', 'ember-htmlbars-template-compiler/system/compile-options'], function (exports, _require, _emberHtmlbarsTemplateCompilerSystemTemplate, _emberHtmlbarsTemplateCompilerSystemCompileOptions) { - 'use strict'; - - exports.default = compiler; - - var compile = undefined; - - function compiler(string, options) { - if (!compile && _require.has('htmlbars-compiler/compiler')) { - compile = _require.default('htmlbars-compiler/compiler').compile; - } - - if (!compile) { - throw new Error('Cannot call `compile` without the template compiler loaded. Please load `ember-template-compiler.js` prior to calling `compile`.'); - } - - var templateSpec = compile(string, _emberHtmlbarsTemplateCompilerSystemCompileOptions.default(options)); - - return _emberHtmlbarsTemplateCompilerSystemTemplate.default(templateSpec); - } -}); -enifed('ember-htmlbars-template-compiler/system/precompile', ['exports', 'ember-htmlbars-template-compiler/system/compile-options', 'require'], function (exports, _emberHtmlbarsTemplateCompilerSystemCompileOptions, _require) { - 'use strict'; - - exports.default = precompile; - - var compileSpec = undefined; - - function precompile(templateString, options) { - if (!compileSpec && _require.has('htmlbars-compiler/compiler')) { - compileSpec = _require.default('htmlbars-compiler/compiler').compileSpec; - } - - if (!compileSpec) { - throw new Error('Cannot call `compileSpec` without the template compiler loaded. Please load `ember-template-compiler.js` prior to calling `compileSpec`.'); - } - - return compileSpec(templateString, _emberHtmlbarsTemplateCompilerSystemCompileOptions.default(options)); - } -}); -enifed('ember-htmlbars-template-compiler/system/template', ['exports', 'require'], function (exports, _require2) { - 'use strict'; - - var _require = _require2.default('htmlbars-runtime/hooks'); - - var wrap = _require.wrap; - - var template = function (templateSpec) { - if (!templateSpec.render) { - templateSpec = wrap(templateSpec); - } - - templateSpec.isTop = true; - templateSpec.isMethod = false; - - return templateSpec; - }; - - exports.default = template; -}); -enifed('ember-htmlbars/compat', ['exports', 'ember-metal/core', 'ember-htmlbars/utils/string'], function (exports, _emberMetalCore, _emberHtmlbarsUtilsString) { - 'use strict'; - - var EmberHandlebars = _emberMetalCore.default.Handlebars = _emberMetalCore.default.Handlebars || {}; - - EmberHandlebars.SafeString = _emberHtmlbarsUtilsString.SafeString; - EmberHandlebars.Utils = { - escapeExpression: _emberHtmlbarsUtilsString.escapeExpression - }; - - exports.default = EmberHandlebars; -}); -// for Handlebars export -enifed('ember-htmlbars/component', ['exports', 'ember-metal/debug', 'ember-metal/mixin', 'ember-environment', 'ember-runtime/mixins/target_action_support', 'ember-views/views/view', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/is_none', 'ember-metal/utils', 'ember-metal/computed', 'ember-views/compat/attrs-proxy', 'container/owner', 'ember-metal/symbol'], function (exports, _emberMetalDebug, _emberMetalMixin, _emberEnvironment, _emberRuntimeMixinsTarget_action_support, _emberViewsViewsView, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalIs_none, _emberMetalUtils, _emberMetalComputed, _emberViewsCompatAttrsProxy, _containerOwner, _emberMetalSymbol) { - 'use strict'; - var HAS_BLOCK = _emberMetalSymbol.default('HAS_BLOCK'); exports.HAS_BLOCK = HAS_BLOCK; - function validateAction(component, actionName) { - if (actionName && actionName[_emberViewsCompatAttrsProxy.MUTABLE_CELL]) { - actionName = actionName.value; - } - - return actionName; - } - /** @module ember @submodule ember-views */ @@ -7771,37 +7312,23 @@ @namespace Ember @extends Ember.View @uses Ember.ViewTargetActionSupport @public */ - var Component = _emberViewsViewsView.default.extend(_emberRuntimeMixinsTarget_action_support.default, { + var Component = _emberViewsViewsView.default.extend(_emberRuntimeMixinsTarget_action_support.default, _emberViewsMixinsAction_support.default, { isComponent: true, - /* - This is set so that the proto inspection in appendTemplatedView does not - think that it should set the component's `context` to that of the parent view. - */ - controller: null, - context: null, instrumentName: 'component', instrumentDisplay: _emberMetalComputed.computed(function () { if (this._debugContainerKey) { return '{{' + this._debugContainerKey.split(':')[1] + '}}'; } }), init: function () { this._super.apply(this, arguments); - _emberMetalProperty_set.set(this, 'controller', this); - _emberMetalProperty_set.set(this, 'context', this); - if (!this.layout && this.layoutName && _containerOwner.getOwner(this)) { - var layoutName = _emberMetalProperty_get.get(this, 'layoutName'); - - this.layout = this.templateForName(layoutName); - } - // If a `defaultLayout` was specified move it to the `layout` prop. // `layout` is no longer a CP, so this just ensures that the `defaultLayout` // logic is supported with a deprecation if (this.defaultLayout && !this.layout) { @@ -7815,152 +7342,45 @@ template: null, layoutName: null, layout: null, /** - If the component is currently inserted into the DOM of a parent view, this - property will point to the controller of the parent view. - @property targetObject - @type Ember.Controller - @default null - @private - */ - targetObject: _emberMetalComputed.computed('controller', function (key) { - if (this._targetObject) { - return this._targetObject; - } - if (this._controller) { - return this._controller; - } - var parentView = _emberMetalProperty_get.get(this, 'parentView'); - return parentView ? _emberMetalProperty_get.get(parentView, 'controller') : null; - }), - - /** - Calls an action passed to a component. - For example a component for playing or pausing music may translate click events - into action notifications of "play" or "stop" depending on some internal state - of the component: - ```javascript - // app/components/play-button.js - export default Ember.Component.extend({ - click() { - if (this.get('isPlaying')) { - this.sendAction('play'); - } else { - this.sendAction('stop'); - } - } - }); - ``` - The actions "play" and "stop" must be passed to this `play-button` component: - ```handlebars - {{! app/templates/application.hbs }} - {{play-button play=(action "musicStarted") stop=(action "musicStopped")}} - ``` - When the component receives a browser `click` event it translate this - interaction into application-specific semantics ("play" or "stop") and - calls the specified action. - ```javascript - // app/controller/application.js - export default Ember.Controller.extend({ - actions: { - musicStarted() { - // called when the play button is clicked - // and the music started playing - }, - musicStopped() { - // called when the play button is clicked - // and the music stopped playing - } - } - }); - ``` - If no action is passed to `sendAction` a default name of "action" - is assumed. - ```javascript - // app/components/next-button.js - export default Ember.Component.extend({ - click() { - this.sendAction(); - } - }); - ``` - ```handlebars - {{! app/templates/application.hbs }} - {{next-button action=(action "playNextSongInAlbum")}} - ``` - ```javascript - // app/controllers/application.js - App.ApplicationController = Ember.Controller.extend({ - actions: { - playNextSongInAlbum() { - ... - } - } - }); - ``` - @method sendAction - @param [action] {String} the action to call - @param [params] {*} arguments for the action + Normally, Ember's component model is "write-only". The component takes a + bunch of attributes that it got passed in, and uses them to render its + template. + One nice thing about this model is that if you try to set a value to the + same thing as last time, Ember (through HTMLBars) will avoid doing any + work on the DOM. + This is not just a performance optimization. If an attribute has not + changed, it is important not to clobber the element's "hidden state". + For example, if you set an input's `value` to the same value as before, + it will clobber selection state and cursor position. In other words, + setting an attribute is not **always** idempotent. + This method provides a way to read an element's attribute and also + update the last value Ember knows about at the same time. This makes + setting an attribute idempotent. + In particular, what this means is that if you get an `<input>` element's + `value` attribute and then re-render the template with the same value, + it will avoid clobbering the cursor and selection position. + Since most attribute sets are idempotent in the browser, you typically + can get away with reading attributes using jQuery, but the most reliable + way to do so is through this method. + @method readDOMAttr + @param {String} name the name of the attribute + @return String @public */ - sendAction: function (action) { - for (var _len = arguments.length, contexts = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - contexts[_key - 1] = arguments[_key]; + readDOMAttr: function (name) { + var attr = this._renderNode.childNodes.filter(function (node) { + return node.attrName === name; + })[0]; + if (!attr) { + return null; } - - var actionName; - - // Send the default action - if (action === undefined) { - action = 'action'; - } - actionName = _emberMetalProperty_get.get(this, 'attrs.' + action) || _emberMetalProperty_get.get(this, action); - actionName = validateAction(this, actionName); - - // If no action name for that action could be found, just abort. - if (actionName === undefined) { - return; - } - - if (typeof actionName === 'function') { - actionName.apply(undefined, contexts); - } else { - this.triggerAction({ - action: actionName, - actionContext: contexts - }); - } + return attr.getContent(); }, - send: function (actionName) { - for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { - args[_key2 - 1] = arguments[_key2]; - } - - var target; - var action = this.actions && this.actions[actionName]; - - if (action) { - var shouldBubble = action.apply(this, args) === true; - if (!shouldBubble) { - return; - } - } - - if (target = _emberMetalProperty_get.get(this, 'target')) { - var _target; - - (_target = target).send.apply(_target, arguments); - } else { - if (!action) { - throw new Error(_emberMetalUtils.inspect(this) + ' had no action handler for: ' + actionName); - } - } - } - /** Returns true when the component was invoked with a block template. Example (`hasBlock` will be `false`): ```hbs {{! templates/application.hbs }} @@ -8086,10 +7506,11 @@ every time any attribute updates. @method didReceiveAttrs @public @since 1.13.0 */ + didReceiveAttrs: function () {}, /** Called when the attributes passed into the component have been updated. Called both during the initial render of a container and during a rerender. Can be used in place of an observer; code placed here will be executed @@ -8104,10 +7525,11 @@ in subsequent rerenders. @method didRender @public @since 1.13.0 */ + didRender: function () {}, /** Called after a component has been rendered, both on initial render and in subsequent rerenders. @event didRender @@ -8120,10 +7542,11 @@ in subsequent rerenders. @method willRender @public @since 1.13.0 */ + willRender: function () {}, /** Called before a component has been rendered, both on initial render and in subsequent rerenders. @event willRender @@ -8136,10 +7559,11 @@ Called only during a rerender, not during an initial render. @method didUpdateAttrs @public @since 1.13.0 */ + didUpdateAttrs: function () {}, /** Called when the attributes passed into the component have been changed. Called only during a rerender, not during an initial render. @event didUpdateAttrs @@ -8152,10 +7576,11 @@ Called only during a rerender, not during an initial render. @method willUpdate @public @since 1.13.0 */ + willUpdate: function () {}, /** Called when the component is about to update and rerender itself. Called only during a rerender, not during an initial render. @event willUpdate @@ -8164,14 +7589,15 @@ */ /** Called when the component has updated and rerendered itself. Called only during a rerender, not during an initial render. - @event didUpdate + @method didUpdate @public @since 1.13.0 */ + didUpdate: function () {} /** Called when the component has updated and rerendered itself. Called only during a rerender, not during an initial render. @event didUpdate @@ -8181,11 +7607,12 @@ }); Component[_emberMetalMixin.NAME_KEY] = 'Ember.Component'; Component.reopenClass({ - isComponentFactory: true + isComponentFactory: true, + positionalParams: [] }); exports.default = Component; }); enifed('ember-htmlbars/components/checkbox', ['exports', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-htmlbars/component'], function (exports, _emberMetalProperty_get, _emberMetalProperty_set, _emberHtmlbarsComponent) { @@ -9026,11 +8453,11 @@ var lastParam = params[params.length - 1]; if (lastParam && lastParam.isQueryParams) { queryParams = params.pop(); } else { - queryParams = { values: {} }; + queryParams = {}; } this.set('queryParams', queryParams); // 4. Any remaining indices (excepting `targetRouteName` at 0) are `models`. if (params.length > 1) { @@ -9093,11 +8520,11 @@ @module ember @submodule ember-views */ 'use strict'; - var inputTypeTestElement; + var inputTypeTestElement = undefined; var inputTypes = new _emberMetalEmpty_object.default(); function canSetTypeOfInput(type) { if (type in inputTypes) { return inputTypes[type]; } @@ -9219,11 +8646,11 @@ @public */ max: null }); }); -enifed('ember-htmlbars/env', ['exports', 'ember-environment', 'htmlbars-runtime', 'ember-metal/assign', 'ember-htmlbars/hooks/subexpr', 'ember-htmlbars/hooks/concat', 'ember-htmlbars/hooks/link-render-node', 'ember-htmlbars/hooks/create-fresh-scope', 'ember-htmlbars/hooks/bind-shadow-scope', 'ember-htmlbars/hooks/bind-self', 'ember-htmlbars/hooks/bind-scope', 'ember-htmlbars/hooks/bind-local', 'ember-htmlbars/hooks/bind-block', 'ember-htmlbars/hooks/update-self', 'ember-htmlbars/hooks/get-root', 'ember-htmlbars/hooks/get-child', 'ember-htmlbars/hooks/get-block', 'ember-htmlbars/hooks/get-value', 'ember-htmlbars/hooks/get-cell-or-value', 'ember-htmlbars/hooks/cleanup-render-node', 'ember-htmlbars/hooks/destroy-render-node', 'ember-htmlbars/hooks/did-render-node', 'ember-htmlbars/hooks/will-cleanup-tree', 'ember-htmlbars/hooks/did-cleanup-tree', 'ember-htmlbars/hooks/classify', 'ember-htmlbars/hooks/component', 'ember-htmlbars/hooks/lookup-helper', 'ember-htmlbars/hooks/has-helper', 'ember-htmlbars/hooks/invoke-helper', 'ember-htmlbars/hooks/element', 'ember-htmlbars/helpers', 'ember-htmlbars/keywords', 'ember-htmlbars/system/dom-helper', 'ember-htmlbars/keywords/debugger', 'ember-htmlbars/keywords/with', 'ember-htmlbars/keywords/outlet', 'ember-htmlbars/keywords/unbound', 'ember-htmlbars/keywords/view', 'ember-htmlbars/keywords/component', 'ember-htmlbars/keywords/element-component', 'ember-htmlbars/keywords/partial', 'ember-htmlbars/keywords/input', 'ember-htmlbars/keywords/textarea', 'ember-htmlbars/keywords/yield', 'ember-htmlbars/keywords/mut', 'ember-htmlbars/keywords/readonly', 'ember-htmlbars/keywords/get', 'ember-htmlbars/keywords/action', 'ember-htmlbars/keywords/render', 'ember-htmlbars/keywords/element-action'], function (exports, _emberEnvironment, _htmlbarsRuntime, _emberMetalAssign, _emberHtmlbarsHooksSubexpr, _emberHtmlbarsHooksConcat, _emberHtmlbarsHooksLinkRenderNode, _emberHtmlbarsHooksCreateFreshScope, _emberHtmlbarsHooksBindShadowScope, _emberHtmlbarsHooksBindSelf, _emberHtmlbarsHooksBindScope, _emberHtmlbarsHooksBindLocal, _emberHtmlbarsHooksBindBlock, _emberHtmlbarsHooksUpdateSelf, _emberHtmlbarsHooksGetRoot, _emberHtmlbarsHooksGetChild, _emberHtmlbarsHooksGetBlock, _emberHtmlbarsHooksGetValue, _emberHtmlbarsHooksGetCellOrValue, _emberHtmlbarsHooksCleanupRenderNode, _emberHtmlbarsHooksDestroyRenderNode, _emberHtmlbarsHooksDidRenderNode, _emberHtmlbarsHooksWillCleanupTree, _emberHtmlbarsHooksDidCleanupTree, _emberHtmlbarsHooksClassify, _emberHtmlbarsHooksComponent, _emberHtmlbarsHooksLookupHelper, _emberHtmlbarsHooksHasHelper, _emberHtmlbarsHooksInvokeHelper, _emberHtmlbarsHooksElement, _emberHtmlbarsHelpers, _emberHtmlbarsKeywords, _emberHtmlbarsSystemDomHelper, _emberHtmlbarsKeywordsDebugger, _emberHtmlbarsKeywordsWith, _emberHtmlbarsKeywordsOutlet, _emberHtmlbarsKeywordsUnbound, _emberHtmlbarsKeywordsView, _emberHtmlbarsKeywordsComponent, _emberHtmlbarsKeywordsElementComponent, _emberHtmlbarsKeywordsPartial, _emberHtmlbarsKeywordsInput, _emberHtmlbarsKeywordsTextarea, _emberHtmlbarsKeywordsYield, _emberHtmlbarsKeywordsMut, _emberHtmlbarsKeywordsReadonly, _emberHtmlbarsKeywordsGet, _emberHtmlbarsKeywordsAction, _emberHtmlbarsKeywordsRender, _emberHtmlbarsKeywordsElementAction) { +enifed('ember-htmlbars/env', ['exports', 'ember-environment', 'htmlbars-runtime', 'ember-metal/assign', 'ember-metal/features', 'ember-htmlbars/hooks/subexpr', 'ember-htmlbars/hooks/concat', 'ember-htmlbars/hooks/link-render-node', 'ember-htmlbars/hooks/create-fresh-scope', 'ember-htmlbars/hooks/bind-shadow-scope', 'ember-htmlbars/hooks/bind-self', 'ember-htmlbars/hooks/bind-scope', 'ember-htmlbars/hooks/bind-local', 'ember-htmlbars/hooks/bind-block', 'ember-htmlbars/hooks/update-self', 'ember-htmlbars/hooks/get-root', 'ember-htmlbars/hooks/get-child', 'ember-htmlbars/hooks/get-block', 'ember-htmlbars/hooks/get-value', 'ember-htmlbars/hooks/get-cell-or-value', 'ember-htmlbars/hooks/cleanup-render-node', 'ember-htmlbars/hooks/destroy-render-node', 'ember-htmlbars/hooks/did-render-node', 'ember-htmlbars/hooks/will-cleanup-tree', 'ember-htmlbars/hooks/did-cleanup-tree', 'ember-htmlbars/hooks/classify', 'ember-htmlbars/hooks/component', 'ember-htmlbars/hooks/lookup-helper', 'ember-htmlbars/hooks/has-helper', 'ember-htmlbars/hooks/invoke-helper', 'ember-htmlbars/hooks/element', 'ember-htmlbars/helpers', 'ember-htmlbars/keywords', 'ember-htmlbars/system/dom-helper', 'ember-htmlbars/keywords/debugger', 'ember-htmlbars/keywords/with', 'ember-htmlbars/keywords/outlet', 'ember-htmlbars/keywords/unbound', 'ember-htmlbars/keywords/component', 'ember-htmlbars/keywords/element-component', 'ember-htmlbars/keywords/mount', 'ember-htmlbars/keywords/partial', 'ember-htmlbars/keywords/input', 'ember-htmlbars/keywords/textarea', 'ember-htmlbars/keywords/yield', 'ember-htmlbars/keywords/mut', 'ember-htmlbars/keywords/readonly', 'ember-htmlbars/keywords/get', 'ember-htmlbars/keywords/action', 'ember-htmlbars/keywords/render', 'ember-htmlbars/keywords/element-action'], function (exports, _emberEnvironment, _htmlbarsRuntime, _emberMetalAssign, _emberMetalFeatures, _emberHtmlbarsHooksSubexpr, _emberHtmlbarsHooksConcat, _emberHtmlbarsHooksLinkRenderNode, _emberHtmlbarsHooksCreateFreshScope, _emberHtmlbarsHooksBindShadowScope, _emberHtmlbarsHooksBindSelf, _emberHtmlbarsHooksBindScope, _emberHtmlbarsHooksBindLocal, _emberHtmlbarsHooksBindBlock, _emberHtmlbarsHooksUpdateSelf, _emberHtmlbarsHooksGetRoot, _emberHtmlbarsHooksGetChild, _emberHtmlbarsHooksGetBlock, _emberHtmlbarsHooksGetValue, _emberHtmlbarsHooksGetCellOrValue, _emberHtmlbarsHooksCleanupRenderNode, _emberHtmlbarsHooksDestroyRenderNode, _emberHtmlbarsHooksDidRenderNode, _emberHtmlbarsHooksWillCleanupTree, _emberHtmlbarsHooksDidCleanupTree, _emberHtmlbarsHooksClassify, _emberHtmlbarsHooksComponent, _emberHtmlbarsHooksLookupHelper, _emberHtmlbarsHooksHasHelper, _emberHtmlbarsHooksInvokeHelper, _emberHtmlbarsHooksElement, _emberHtmlbarsHelpers, _emberHtmlbarsKeywords, _emberHtmlbarsSystemDomHelper, _emberHtmlbarsKeywordsDebugger, _emberHtmlbarsKeywordsWith, _emberHtmlbarsKeywordsOutlet, _emberHtmlbarsKeywordsUnbound, _emberHtmlbarsKeywordsComponent, _emberHtmlbarsKeywordsElementComponent, _emberHtmlbarsKeywordsMount, _emberHtmlbarsKeywordsPartial, _emberHtmlbarsKeywordsInput, _emberHtmlbarsKeywordsTextarea, _emberHtmlbarsKeywordsYield, _emberHtmlbarsKeywordsMut, _emberHtmlbarsKeywordsReadonly, _emberHtmlbarsKeywordsGet, _emberHtmlbarsKeywordsAction, _emberHtmlbarsKeywordsRender, _emberHtmlbarsKeywordsElementAction) { 'use strict'; var emberHooks = _emberMetalAssign.default({}, _htmlbarsRuntime.hooks); emberHooks.keywords = _emberHtmlbarsKeywords.default; @@ -9261,10 +8688,13 @@ _emberHtmlbarsKeywords.registerKeyword('with', _emberHtmlbarsKeywordsWith.default); _emberHtmlbarsKeywords.registerKeyword('outlet', _emberHtmlbarsKeywordsOutlet.default); _emberHtmlbarsKeywords.registerKeyword('unbound', _emberHtmlbarsKeywordsUnbound.default); _emberHtmlbarsKeywords.registerKeyword('component', _emberHtmlbarsKeywordsComponent.default); _emberHtmlbarsKeywords.registerKeyword('@element_component', _emberHtmlbarsKeywordsElementComponent.default); + if (true) { + _emberHtmlbarsKeywords.registerKeyword('mount', _emberHtmlbarsKeywordsMount.default); + } _emberHtmlbarsKeywords.registerKeyword('partial', _emberHtmlbarsKeywordsPartial.default); _emberHtmlbarsKeywords.registerKeyword('input', _emberHtmlbarsKeywordsInput.default); _emberHtmlbarsKeywords.registerKeyword('textarea', _emberHtmlbarsKeywordsTextarea.default); _emberHtmlbarsKeywords.registerKeyword('yield', _emberHtmlbarsKeywordsYield.default); _emberHtmlbarsKeywords.registerKeyword('mut', _emberHtmlbarsKeywordsMut.default); @@ -9273,14 +8703,10 @@ _emberHtmlbarsKeywords.registerKeyword('get', _emberHtmlbarsKeywordsGet.default); _emberHtmlbarsKeywords.registerKeyword('action', _emberHtmlbarsKeywordsAction.default); _emberHtmlbarsKeywords.registerKeyword('render', _emberHtmlbarsKeywordsRender.default); _emberHtmlbarsKeywords.registerKeyword('@element_action', _emberHtmlbarsKeywordsElementAction.default); - if (_emberEnvironment.ENV._ENABLE_LEGACY_VIEW_SUPPORT) { - _emberHtmlbarsKeywords.registerKeyword('view', _emberHtmlbarsKeywordsView.default); - } - exports.default = { hooks: emberHooks, helpers: _emberHtmlbarsHelpers.default, useFragmentCache: true }; @@ -9333,10 +8759,25 @@ As instances, these helpers also have access to the container and will accept injected dependencies. Additionally, class helpers can call `recompute` to force a new computation. + If the output of your helper is only dependent on the current input, then you + can use the `Helper.helper` function. + See [Ember.Helper.helper](/api/classes/Ember.Helper.html#method_helper). + + In this form the example above becomes: + + ```js + export default Ember.Helper.helper((params, hash) => { + let cents = params[0]; + let currency = hash.currency; + return `${currency}${cents * 0.01}`; + }); + ``` + + @class Ember.Helper @public @since 1.13.0 */ var Helper = _emberRuntimeSystemObject.default.extend({ @@ -9398,21 +8839,25 @@ // tests/myhelper.js import { formatCurrency } from ..../helpers/myhelper // add some tests ``` + This form is more efficient at run time and results in smaller compiled js. + It is also easier to test by using the following structure and importing the + `formatCurrency` function into a test. + @static @param {Function} helper The helper function @method helper @public @since 1.13.0 */ - function helper(helperFn) { + function helper(compute) { return { isHelperInstance: true, - compute: helperFn + compute: compute }; } exports.default = Helper; }); @@ -9579,10 +9024,12 @@ @submodule ember-templates */ 'use strict'; + exports.default = eachInHelper; + /** The `{{each-in}}` helper loops over properties on an object. It is unbound, in that new (or removed) properties added to the target object will not be rendered. @@ -9611,26 +9058,26 @@ @method each-in @for Ember.Templates.helpers @public @since 2.1.0 */ - var eachInHelper = function (_ref, hash, blocks) { + + function eachInHelper(_ref, hash, blocks) { var object = _ref[0]; - var objKeys, prop, i; + var objKeys = undefined, + prop = undefined; objKeys = object ? Object.keys(object) : []; if (_emberHtmlbarsStreamsShould_display.default(objKeys)) { - for (i = 0; i < objKeys.length; i++) { + for (var i = 0; i < objKeys.length; i++) { prop = objKeys[i]; blocks.template.yieldItem(prop, [prop, object[prop]]); } } else if (blocks.inverse.yield) { blocks.inverse.yield(); } - }; - - exports.default = eachInHelper; + } }); enifed('ember-htmlbars/helpers/each', ['exports', 'ember-htmlbars/streams/should_display', 'ember-htmlbars/utils/decode-each-key'], function (exports, _emberHtmlbarsStreamsShould_display, _emberHtmlbarsUtilsDecodeEachKey) { /** @module ember @submodule ember-templates @@ -9646,11 +9093,11 @@ The default behavior of `{{#each}}` is to yield its inner block once for every item in an array passing the item as the first block parameter. ```javascript - var developers = [{name: 'Yehuda'},{name: 'Tom'}, {name: 'Paul'}]; + var developers = [{ name: 'Yehuda' },{ name: 'Tom' }, { name: 'Paul' }]; ``` ```handlebars {{#each developers key="name" as |person|}} {{person.name}} @@ -10073,28 +9520,20 @@ exports.default = bindScope; function bindScope(env, scope) {} }); -enifed('ember-htmlbars/hooks/bind-self', ['exports', 'ember-environment', 'ember-htmlbars/streams/proxy-stream'], function (exports, _emberEnvironment, _emberHtmlbarsStreamsProxyStream) { +enifed('ember-htmlbars/hooks/bind-self', ['exports', 'ember-htmlbars/streams/proxy-stream'], function (exports, _emberHtmlbarsStreamsProxyStream) { /** @module ember @submodule ember-htmlbars */ 'use strict'; exports.default = bindSelf; function bindSelf(env, scope, self) { - if (self && self.isView) { - if (!!_emberEnvironment.ENV._ENABLE_LEGACY_VIEW_SUPPORT) { - scope.bindLocal('view', newStream(self, 'view')); - } - var _selfStream = newStream(self, ''); - scope.bindSelf(newStream(_selfStream.getKey('context'), '')); - return; - } var selfStream = newStream(self, ''); scope.bindSelf(selfStream); } function newStream(newValue, key) { @@ -10174,11 +9613,11 @@ if (renderNode.cleanup) { renderNode.cleanup(); } } }); -enifed('ember-htmlbars/hooks/component', ['exports', 'ember-metal/debug', 'ember-htmlbars/node-managers/component-node-manager', 'ember-htmlbars/utils/lookup-component', 'ember-metal/assign', 'ember-metal/empty_object', 'ember-htmlbars/system/lookup-helper', 'ember-htmlbars/utils/extract-positional-params', 'ember-htmlbars/keywords/closure-component'], function (exports, _emberMetalDebug, _emberHtmlbarsNodeManagersComponentNodeManager, _emberHtmlbarsUtilsLookupComponent, _emberMetalAssign, _emberMetalEmpty_object, _emberHtmlbarsSystemLookupHelper, _emberHtmlbarsUtilsExtractPositionalParams, _emberHtmlbarsKeywordsClosureComponent) { +enifed('ember-htmlbars/hooks/component', ['exports', 'ember-metal/debug', 'ember-htmlbars/node-managers/component-node-manager', 'ember-views/utils/lookup-component', 'ember-metal/assign', 'ember-metal/empty_object', 'ember-htmlbars/system/lookup-helper', 'ember-htmlbars/utils/extract-positional-params', 'ember-htmlbars/keywords/closure-component'], function (exports, _emberMetalDebug, _emberHtmlbarsNodeManagersComponentNodeManager, _emberViewsUtilsLookupComponent, _emberMetalAssign, _emberMetalEmpty_object, _emberHtmlbarsSystemLookupHelper, _emberHtmlbarsUtilsExtractPositionalParams, _emberHtmlbarsKeywordsClosureComponent) { 'use strict'; exports.default = componentHook; function componentHook(renderNode, env, scope, _tagName, params, _attrs, templates, visitor) { @@ -10216,11 +9655,11 @@ if (state.manager) { var sm = state.manager; var templateMeta = null; if (sm.block) { templateMeta = sm.block.template.meta; - } else if (sm.scope && sm.scope._view && sm.scope._view.template) { + } else if (sm.scope && sm.scope._view) { templateMeta = sm.scope._view.template.meta; } env.meta.moduleName = templateMeta && templateMeta.moduleName || env.meta && env.meta.moduleName; _emberHtmlbarsUtilsExtractPositionalParams.default(renderNode, sm.component.constructor, params, attrs, false); state.manager.rerender(env, attrs, visitor); @@ -10232,11 +9671,11 @@ var moduleName = env.meta && env.meta.moduleName; if (moduleName) { options.source = 'template:' + moduleName; } - var _lookupComponent = _emberHtmlbarsUtilsLookupComponent.default(env.owner, tagName, options); + var _lookupComponent = _emberViewsUtilsLookupComponent.default(env.owner, tagName, options); var component = _lookupComponent.component; var layout = _lookupComponent.layout; var manager = _emberHtmlbarsNodeManagersComponentNodeManager.default.create(renderNode, env, { @@ -10252,22 +9691,22 @@ state.manager = manager; manager.render(env, visitor); } }); -enifed('ember-htmlbars/hooks/concat', ['exports', 'ember-htmlbars/streams/utils'], function (exports, _emberHtmlbarsStreamsUtils) { +enifed('ember-htmlbars/hooks/concat', ['exports', 'ember-htmlbars/streams/concat'], function (exports, _emberHtmlbarsStreamsConcat) { /** @module ember @submodule ember-htmlbars */ 'use strict'; exports.default = concat; function concat(env, parts) { - return _emberHtmlbarsStreamsUtils.concat(parts, ''); + return _emberHtmlbarsStreamsConcat.default(parts, ''); } }); enifed('ember-htmlbars/hooks/create-fresh-scope', ['exports', 'ember-htmlbars/streams/proxy-stream', 'ember-metal/empty_object'], function (exports, _emberHtmlbarsStreamsProxyStream, _emberMetalEmpty_object) { 'use strict'; @@ -10491,18 +9930,18 @@ enifed("ember-htmlbars/hooks/destroy-render-node", ["exports"], function (exports) { /** @module ember @submodule ember-htmlbars */ - "use strict"; exports.default = destroyRenderNode; function destroyRenderNode(renderNode) { - if (renderNode.emberView) { - renderNode.emberView.destroy(); + var view = renderNode.emberView; + if (view) { + view.renderer.remove(view, true); } var streamUnsubscribers = renderNode.streamUnsubscribers; if (streamUnsubscribers) { for (var i = 0; i < streamUnsubscribers.length; i++) { @@ -10544,11 +9983,11 @@ function emberElement(morph, env, scope, path, params, hash, visitor) { if (_htmlbarsRuntimeHooks.handleRedirect(morph, env, scope, path, params, hash, null, null, visitor)) { return; } - var result; + var result = undefined; var helper = _emberHtmlbarsSystemLookupHelper.findHelper(path, scope.getSelf(), env); if (helper) { var helperStream = _emberHtmlbarsSystemInvokeHelper.buildHelperStream(helper, params, hash, { element: morph.element }, env, scope, path); result = helperStream.value(); } else { @@ -11004,11 +10443,11 @@ // untouched. This view is then cleared once cleanup is complete in // `didCleanupTree`. view.ownerView._destroyingSubtreeForView = view; } }); -enifed('ember-htmlbars/index', ['exports', 'ember-metal/core', 'ember-htmlbars/system/make_bound_helper', 'ember-htmlbars/helpers', 'ember-htmlbars/helpers/if_unless', 'ember-htmlbars/helpers/with', 'ember-htmlbars/helpers/loc', 'ember-htmlbars/helpers/log', 'ember-htmlbars/helpers/each', 'ember-htmlbars/helpers/each-in', 'ember-htmlbars/helpers/-normalize-class', 'ember-htmlbars/helpers/concat', 'ember-htmlbars/helpers/-join-classes', 'ember-htmlbars/helpers/-html-safe', 'ember-htmlbars/helpers/hash', 'ember-htmlbars/system/dom-helper', 'ember-htmlbars/helpers/query-params', 'ember-htmlbars/compat'], function (exports, _emberMetalCore, _emberHtmlbarsSystemMake_bound_helper, _emberHtmlbarsHelpers, _emberHtmlbarsHelpersIf_unless, _emberHtmlbarsHelpersWith, _emberHtmlbarsHelpersLoc, _emberHtmlbarsHelpersLog, _emberHtmlbarsHelpersEach, _emberHtmlbarsHelpersEachIn, _emberHtmlbarsHelpersNormalizeClass, _emberHtmlbarsHelpersConcat, _emberHtmlbarsHelpersJoinClasses, _emberHtmlbarsHelpersHtmlSafe, _emberHtmlbarsHelpersHash, _emberHtmlbarsSystemDomHelper, _emberHtmlbarsHelpersQueryParams, _emberHtmlbarsCompat) { +enifed('ember-htmlbars/index', ['exports', 'ember-metal/core', 'ember-htmlbars/helpers', 'ember-htmlbars/helpers/if_unless', 'ember-htmlbars/helpers/with', 'ember-htmlbars/helpers/loc', 'ember-htmlbars/helpers/log', 'ember-htmlbars/helpers/each', 'ember-htmlbars/helpers/each-in', 'ember-htmlbars/helpers/-normalize-class', 'ember-htmlbars/helpers/concat', 'ember-htmlbars/helpers/-join-classes', 'ember-htmlbars/helpers/-html-safe', 'ember-htmlbars/helpers/hash', 'ember-htmlbars/helpers/query-params', 'ember-htmlbars/system/dom-helper', 'ember-htmlbars/system/template'], function (exports, _emberMetalCore, _emberHtmlbarsHelpers, _emberHtmlbarsHelpersIf_unless, _emberHtmlbarsHelpersWith, _emberHtmlbarsHelpersLoc, _emberHtmlbarsHelpersLog, _emberHtmlbarsHelpersEach, _emberHtmlbarsHelpersEachIn, _emberHtmlbarsHelpersNormalizeClass, _emberHtmlbarsHelpersConcat, _emberHtmlbarsHelpersJoinClasses, _emberHtmlbarsHelpersHtmlSafe, _emberHtmlbarsHelpersHash, _emberHtmlbarsHelpersQueryParams, _emberHtmlbarsSystemDomHelper, _emberHtmlbarsSystemTemplate) { /** Ember templates are executed by [HTMLBars](https://github.com/tildeio/htmlbars), an HTML-friendly version of [Handlebars](http://handlebarsjs.com/). Any valid Handlebars syntax is valid in an Ember template. ### Showing a property @@ -11103,10 +10542,12 @@ @main ember-htmlbars @public */ 'use strict'; + exports.template = _emberHtmlbarsSystemTemplate.default; + _emberHtmlbarsHelpers.registerHelper('if', _emberHtmlbarsHelpersIf_unless.ifHelper); _emberHtmlbarsHelpers.registerHelper('unless', _emberHtmlbarsHelpersIf_unless.unlessHelper); _emberHtmlbarsHelpers.registerHelper('with', _emberHtmlbarsHelpersWith.default); _emberHtmlbarsHelpers.registerHelper('loc', _emberHtmlbarsHelpersLoc.default); _emberHtmlbarsHelpers.registerHelper('log', _emberHtmlbarsHelpersLog.default); @@ -11118,18 +10559,14 @@ _emberHtmlbarsHelpers.registerHelper('-html-safe', _emberHtmlbarsHelpersHtmlSafe.default); _emberHtmlbarsHelpers.registerHelper('hash', _emberHtmlbarsHelpersHash.default); _emberHtmlbarsHelpers.registerHelper('query-params', _emberHtmlbarsHelpersQueryParams.default); _emberMetalCore.default.HTMLBars = { - makeBoundHelper: _emberHtmlbarsSystemMake_bound_helper.default, DOMHelper: _emberHtmlbarsSystemDomHelper.default }; }); -// reexports - -// Importing ember-htmlbars/compat updates the -// Ember.Handlebars global if htmlbars is enabled. +// exposing Ember.HTMLBars enifed('ember-htmlbars/keywords', ['exports', 'htmlbars-runtime'], function (exports, _htmlbarsRuntime) { /** @module ember @submodule ember-htmlbars */ @@ -11445,10 +10882,12 @@ var ACTION = _emberMetalSymbol.default('ACTION'); exports.ACTION = ACTION; function closureAction(morph, env, scope, params, hash, template, inverse, visitor) { + var _this = this; + var s = new _emberHtmlbarsStreamsStream.Stream(function () { var rawAction = params[0]; var actionArguments = _emberHtmlbarsStreamsUtils.readArray(params.slice(1, params.length)); var target = undefined, @@ -11497,11 +10936,11 @@ // <button on-keypress={{action (mut name) value="which"}} // on-keypress is not even an Ember feature yet valuePath = _emberHtmlbarsStreamsUtils.read(hash.value); } - return createClosureAction(this, target, action, valuePath, actionArguments); + return createClosureAction(_this, target, action, valuePath, actionArguments); }, function () { return _emberHtmlbarsHooksSubexpr.labelForSubexpr(params, hash, 'action'); }); params.forEach(s.addDependency, s); @@ -11511,11 +10950,11 @@ return s; } function createClosureAction(stream, target, action, valuePath, actionArguments) { - var closureAction; + var closureAction = undefined; if (actionArguments.length > 0) { closureAction = function () { var args = actionArguments; @@ -11555,11 +10994,11 @@ closureAction[ACTION] = true; return closureAction; } }); -enifed('ember-htmlbars/keywords/closure-component', ['exports', 'ember-metal/debug', 'ember-metal/is_empty', 'ember-metal/is_none', 'ember-metal/symbol', 'ember-htmlbars/streams/stream', 'ember-metal/empty_object', 'ember-htmlbars/streams/utils', 'ember-htmlbars/hooks/subexpr', 'ember-metal/assign', 'ember-htmlbars/utils/lookup-component', 'ember-htmlbars/utils/extract-positional-params'], function (exports, _emberMetalDebug, _emberMetalIs_empty, _emberMetalIs_none, _emberMetalSymbol, _emberHtmlbarsStreamsStream, _emberMetalEmpty_object, _emberHtmlbarsStreamsUtils, _emberHtmlbarsHooksSubexpr, _emberMetalAssign, _emberHtmlbarsUtilsLookupComponent, _emberHtmlbarsUtilsExtractPositionalParams) { +enifed('ember-htmlbars/keywords/closure-component', ['exports', 'ember-metal/debug', 'ember-metal/is_empty', 'ember-metal/is_none', 'ember-metal/symbol', 'ember-htmlbars/streams/stream', 'ember-metal/empty_object', 'ember-htmlbars/streams/utils', 'ember-htmlbars/hooks/subexpr', 'ember-metal/assign', 'ember-htmlbars/utils/extract-positional-params', 'ember-views/utils/lookup-component'], function (exports, _emberMetalDebug, _emberMetalIs_empty, _emberMetalIs_none, _emberMetalSymbol, _emberHtmlbarsStreamsStream, _emberMetalEmpty_object, _emberHtmlbarsStreamsUtils, _emberHtmlbarsHooksSubexpr, _emberMetalAssign, _emberHtmlbarsUtilsExtractPositionalParams, _emberViewsUtilsLookupComponent) { /** @module ember @submodule ember-templates */ @@ -11628,11 +11067,11 @@ return createNewClosureComponentCell(env, componentPath, params, newHash); } } function isValidComponentPath(env, path) { - var result = _emberHtmlbarsUtilsLookupComponent.default(env.owner, path); + var result = _emberViewsUtilsLookupComponent.default(env.owner, path); return !!(result.component || result.layout); } function isComponentCell(component) { @@ -11671,11 +11110,11 @@ */ function getPositionalParams(container, componentPath) { if (!componentPath) { return []; } - var result = _emberHtmlbarsUtilsLookupComponent.default(container, componentPath); + var result = _emberViewsUtilsLookupComponent.default(container, componentPath); var component = result.component; if (component && component.positionalParams) { return component.positionalParams; } else { @@ -11893,11 +11332,11 @@ debugger; return true; } }); -enifed('ember-htmlbars/keywords/element-action', ['exports', 'ember-metal/debug', 'ember-metal/utils', 'ember-htmlbars/streams/utils', 'ember-metal/run_loop', 'ember-views/system/utils', 'ember-views/system/action_manager'], function (exports, _emberMetalDebug, _emberMetalUtils, _emberHtmlbarsStreamsUtils, _emberMetalRun_loop, _emberViewsSystemUtils, _emberViewsSystemAction_manager) { +enifed('ember-htmlbars/keywords/element-action', ['exports', 'ember-metal/debug', 'ember-metal/utils', 'ember-htmlbars/streams/utils', 'ember-metal/run_loop', 'ember-views/system/utils', 'ember-views/system/action_manager', 'ember-metal/instrumentation'], function (exports, _emberMetalDebug, _emberMetalUtils, _emberHtmlbarsStreamsUtils, _emberMetalRun_loop, _emberViewsSystemUtils, _emberViewsSystemAction_manager, _emberMetalInstrumentation) { 'use strict'; exports.default = { setupState: function (state, env, scope, params, hash) { var getStream = env.hooks.get; @@ -11908,11 +11347,11 @@ var actionArgs = []; for (var i = 1; i < params.length; i++) { actionArgs.push(_emberHtmlbarsStreamsUtils.readUnwrappedModel(params[i])); } - var target; + var target = undefined; if (hash.target) { if (typeof hash.target === 'string') { target = read(getStream(env, scope, hash.target)); } else { target = read(hash.target); @@ -11940,11 +11379,11 @@ withKeyCode: hash.withKeyCode, allowedKeys: hash.allowedKeys }); node.cleanup = function () { - ActionHelper.unregisterAction(actionId); + return ActionHelper.unregisterAction(actionId); }; env.dom.setAttribute(node.element, 'data-ember-action', actionId); } }; @@ -11989,29 +11428,39 @@ var target = _node$getState.target; var actionName = _node$getState.actionName; var actionArgs = _node$getState.actionArgs; _emberMetalRun_loop.default(function runRegisteredAction() { + var payload = { + target: target, + args: actionArgs + }; if (typeof actionName === 'function') { - actionName.apply(target, actionArgs); + _emberMetalInstrumentation.flaggedInstrument('interaction.ember-action', payload, function () { + actionName.apply(target, actionArgs); + }); return; } + payload.name = actionName; if (target.send) { - target.send.apply(target, [actionName].concat(actionArgs)); + _emberMetalInstrumentation.flaggedInstrument('interaction.ember-action', payload, function () { + target.send.apply(target, [actionName].concat(actionArgs)); + }); } else { - - target[actionName].apply(target, actionArgs); + _emberMetalInstrumentation.flaggedInstrument('interaction.ember-action', payload, function () { + target[actionName].apply(target, actionArgs); + }); } }); } }); return actionId; }; ActionHelper.unregisterAction = function (actionId) { - delete _emberViewsSystemAction_manager.default.registeredActions[actionId]; + return delete _emberViewsSystemAction_manager.default.registeredActions[actionId]; }; var MODIFIERS = ['alt', 'shift', 'meta', 'ctrl']; var POINTER_EVENT_TYPE_REGEX = /^click|mouse|touch/; @@ -12035,11 +11484,11 @@ } return true; } }); -enifed('ember-htmlbars/keywords/element-component', ['exports', 'ember-metal/assign', 'ember-htmlbars/keywords/closure-component', 'ember-htmlbars/utils/lookup-component', 'ember-htmlbars/utils/extract-positional-params'], function (exports, _emberMetalAssign, _emberHtmlbarsKeywordsClosureComponent, _emberHtmlbarsUtilsLookupComponent, _emberHtmlbarsUtilsExtractPositionalParams) { +enifed('ember-htmlbars/keywords/element-component', ['exports', 'ember-metal/assign', 'ember-htmlbars/keywords/closure-component', 'ember-views/utils/lookup-component', 'ember-htmlbars/utils/extract-positional-params'], function (exports, _emberMetalAssign, _emberHtmlbarsKeywordsClosureComponent, _emberViewsUtilsLookupComponent, _emberHtmlbarsUtilsExtractPositionalParams) { 'use strict'; exports.default = { setupState: function (lastState, env, scope, params, hash) { var componentPath = getComponentPath(params[0], env); @@ -12097,11 +11546,11 @@ } path = env.hooks.getValue(path); if (isRerender) { - var result = _emberHtmlbarsUtilsLookupComponent.default(env.owner, componentPath); + var result = _emberViewsUtilsLookupComponent.default(env.owner, componentPath); var component = result.component; _emberHtmlbarsUtilsExtractPositionalParams.default(null, component, params, hash); } @@ -12124,10 +11573,12 @@ @submodule ember-templates */ 'use strict'; + exports.default = getKeyword; + function labelFor(source, key) { var sourceLabel = source.label ? source.label : ''; var keyLabel = key.label ? key.label : ''; return '(get ' + sourceLabel + ' ' + keyLabel + ')'; } @@ -12193,18 +11644,18 @@ this.observedKey = null; } } }); - var buildStream = function buildStream(params) { + function buildStream(params) { var objRef = params[0]; var pathRef = params[1]; var stream = buildDynamicKeyStream(objRef, pathRef); return stream; - }; + } function buildDynamicKeyStream(source, keySource) { if (!_emberHtmlbarsStreamsUtils.isStream(keySource)) { return source.get(keySource); } else { @@ -12253,10 +11704,11 @@ @public @method get @for Ember.Templates.helpers @since 2.1.0 */ + function getKeyword(morph, env, scope, params, hash, template, inverse, visitor) { if (morph === null) { return buildStream(params); } else { var stream = undefined; @@ -12273,12 +11725,10 @@ env.hooks.range(morph, env, scope, null, stream, visitor); } return true; } - - exports.default = getKeyword; }); enifed('ember-htmlbars/keywords/input', ['exports', 'ember-metal/debug', 'ember-metal/assign'], function (exports, _emberMetalDebug, _emberMetalAssign) { /** @module ember @submodule ember-templates @@ -12452,10 +11902,144 @@ var componentNameMap = { 'checkbox': '-checkbox' }; }); +enifed('ember-htmlbars/keywords/mount', ['exports', 'ember-htmlbars/node-managers/view-node-manager', 'ember-htmlbars/system/render-env', 'ember-metal/debug', 'container/owner', 'ember-htmlbars/keywords/outlet', 'ember-htmlbars/keywords/render'], function (exports, _emberHtmlbarsNodeManagersViewNodeManager, _emberHtmlbarsSystemRenderEnv, _emberMetalDebug, _containerOwner, _emberHtmlbarsKeywordsOutlet, _emberHtmlbarsKeywordsRender) { + /** + @module ember + @submodule ember-templates + */ + + 'use strict'; + + /** + The `{{mount}}` helper lets you embed a routeless engine in a template. + + Mounting an engine will cause an instance to be booted and its `application` + template to be rendered. + + For example, the following template mounts the `ember-chat` engine: + + ```handlebars + {{! application.hbs }} + {{mount "ember-chat"}} + ``` + + Currently, the engine name is the only argument that can be passed to + `{{mount}}`. + + @method mount + @for Ember.Templates.helpers + @category ember-application-engines + @public + */ + exports.default = { + setupState: function (prevState, env, scope, params /*, hash */) { + var name = params[0]; + + var engineInstance = env.owner.buildChildEngineInstance(name); + + engineInstance.boot(); + + var state = { + parentView: env.view, + manager: prevState.manager, + controller: lookupEngineController(engineInstance), + childOutletState: _emberHtmlbarsKeywordsRender.childOutletState(name, env) + }; + + _containerOwner.setOwner(state, engineInstance); + + return state; + }, + + childEnv: function (state, env) { + return buildEnvForEngine(_containerOwner.getOwner(state), env); + }, + + isStable: function (lastState, nextState) { + return isStable(lastState.childOutletState, nextState.childOutletState); + }, + + isEmpty: function () /* state */{ + return false; + }, + + render: function (node, env, scope, params, hash, template, inverse, visitor) { + var state = node.getState(); + + var engineInstance = _containerOwner.getOwner(state); + + var engineController = lookupEngineController(engineInstance); + + var engineTemplate = lookupEngineTemplate(engineInstance); + + var options = { + layout: null, + self: engineController + }; + + var engineEnv = buildEnvForEngine(engineInstance, env); + + var nodeManager = _emberHtmlbarsNodeManagersViewNodeManager.default.create(node, engineEnv, hash, options, state.parentView, null, null, engineTemplate); + + state.manager = nodeManager; + + nodeManager.render(engineEnv, hash, visitor); + } + }; + + function isStable(a, b) { + if (!a && !b) { + return true; + } + if (!a || !b) { + return false; + } + for (var outletName in a) { + if (!_emberHtmlbarsKeywordsOutlet.isOutletStable(a[outletName], b[outletName])) { + return false; + } + } + return true; + } + + function lookupEngineController(engineInstance) { + return engineInstance.lookup('controller:application'); + } + + function lookupEngineView(engineInstance, ownerView) { + var engineView = engineInstance.lookup('view:toplevel'); + + if (engineView.ownerView !== ownerView) { + engineView.ownerView = ownerView; + } + + return engineView; + } + + function lookupEngineTemplate(engineInstance) { + var engineTemplate = engineInstance.lookup('template:application'); + + if (engineTemplate && engineTemplate.raw) { + engineTemplate = engineTemplate.raw; + } + + return engineTemplate; + } + + function buildEnvForEngine(engineInstance, parentEnv) { + var engineView = lookupEngineView(engineInstance, parentEnv.view.ownerView); + + var engineTemplate = lookupEngineTemplate(engineInstance); + + var engineEnv = _emberHtmlbarsSystemRenderEnv.default.build(engineView, engineTemplate.meta); + + return engineEnv; + } +}); enifed('ember-htmlbars/keywords/mut', ['exports', 'ember-metal/debug', 'ember-metal/symbol', 'ember-htmlbars/streams/proxy-stream', 'ember-htmlbars/streams/stream', 'ember-htmlbars/streams/utils', 'ember-views/compat/attrs-proxy', 'ember-htmlbars/keywords/closure-action'], function (exports, _emberMetalDebug, _emberMetalSymbol, _emberHtmlbarsStreamsProxyStream, _emberHtmlbarsStreamsStream, _emberHtmlbarsStreamsUtils, _emberViewsCompatAttrsProxy, _emberHtmlbarsKeywordsClosureAction) { /** @module ember @submodule ember-templates */ @@ -12609,10 +12193,12 @@ @submodule ember-templates */ 'use strict'; + exports.isOutletStable = isOutletStable; + if (!false) { _emberHtmlbarsTemplatesTopLevelView.default.meta.revision = 'Ember@' + _emberVersion.default; } /** @@ -12691,33 +12277,48 @@ childEnv: function (state, env) { var outletState = state.outletState; var toRender = outletState && outletState.render; var meta = toRender && toRender.template && toRender.template.meta; - return env.childWithOutletState(outletState && outletState.outlets, true, meta); + var childEnv = env.childWithOutletState(outletState && outletState.outlets, true, meta); + + if (true) { + var owner = outletState && outletState.render && outletState.render.owner; + if (owner && owner !== childEnv.owner) { + childEnv.originalOwner = childEnv.owner; + childEnv.owner = owner; + } + } + + return childEnv; }, isStable: function (lastState, nextState) { - return isStable(lastState.outletState, nextState.outletState); + return isOutletStable(lastState.outletState, nextState.outletState); }, isEmpty: function (state) { - return isEmpty(state.outletState); + return isOutletEmpty(state.outletState); }, render: function (renderNode, env, scope, params, hash, _template, inverse, visitor) { var state = renderNode.getState(); + var owner = env.owner; var parentView = env.view; var outletState = state.outletState; var toRender = outletState.render; - var namespace = env.owner.lookup('application:main'); + var namespace = owner.lookup('application:main'); var LOG_VIEW_LOOKUPS = _emberMetalProperty_get.get(namespace, 'LOG_VIEW_LOOKUPS'); var ViewClass = outletState.render.ViewClass; + if (true) { + owner = env.originalOwner || owner; + } + if (!state.hasParentOutlet && !ViewClass) { - ViewClass = env.owner._lookupFactory('view:toplevel'); + ViewClass = owner._lookupFactory('view:toplevel'); } var attrs = {}; var options = { component: ViewClass, @@ -12734,22 +12335,32 @@ if (state.manager) { state.manager.destroy(); state.manager = null; } + if (true) { + // detect if we are crossing into an engine + if (env.originalOwner) { + // when this outlet represents an engine we must ensure that a `ViewClass` is present + // even if the engine does not contain a `view:application`. We need a `ViewClass` to + // ensure that an `ownerView` is set on the `env` created just above + options.component = options.component || owner._lookupFactory('view:toplevel'); + } + } + var nodeManager = _emberHtmlbarsNodeManagersViewNodeManager.default.create(renderNode, env, attrs, options, parentView, null, null, template); state.manager = nodeManager; nodeManager.render(env, hash, visitor); } }; - function isEmpty(outletState) { + function isOutletEmpty(outletState) { return !outletState || !outletState.render.ViewClass && !outletState.render.template; } - function isStable(a, b) { + function isOutletStable(a, b) { if (!a && !b) { return true; } if (!a || !b) { return false; @@ -12785,16 +12396,16 @@ {{foo}} {{partial "nav"}} ``` The above example template will render a template named - "-nav", which has the same context as the parent template - it's rendered into, so if the "-nav" template also referenced + "_nav", which has the same context as the parent template + it's rendered into, so if the "_nav" template also referenced `{{foo}}`, it would print the same thing as the `{{foo}}` in the above example. - If a "-nav" template isn't found, the `partial` helper will + If a "_nav" template isn't found, the `partial` helper will fall back to a template named "nav". ### Bound template names The parameter supplied to `partial` can also be a path @@ -12860,18 +12471,20 @@ } return true; } }); -enifed('ember-htmlbars/keywords/render', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/empty_object', 'ember-metal/error', 'ember-htmlbars/streams/utils', 'ember-runtime/system/string', 'ember-routing/system/generate_controller', 'ember-htmlbars/node-managers/view-node-manager'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalEmpty_object, _emberMetalError, _emberHtmlbarsStreamsUtils, _emberRuntimeSystemString, _emberRoutingSystemGenerate_controller, _emberHtmlbarsNodeManagersViewNodeManager) { +enifed('ember-htmlbars/keywords/render', ['exports', 'ember-metal/debug', 'ember-metal/empty_object', 'ember-metal/error', 'ember-htmlbars/streams/utils', 'ember-routing/system/generate_controller', 'ember-htmlbars/node-managers/view-node-manager'], function (exports, _emberMetalDebug, _emberMetalEmpty_object, _emberMetalError, _emberHtmlbarsStreamsUtils, _emberRoutingSystemGenerate_controller, _emberHtmlbarsNodeManagersViewNodeManager) { /** @module ember @submodule ember-templates */ 'use strict'; + exports.childOutletState = childOutletState; + /** Calling ``{{render}}`` from within a template will insert another template that matches the provided name. The inserted template will access its properties on its own controller (rather than the controller of the parent template). @@ -12973,39 +12586,25 @@ var name = params[0]; var context = params[1]; var owner = env.owner; - // The render keyword presumes it can work without a router. This is really - // only to satisfy the test: - // - // {{view}} should not override class bindings defined on a child view" - // var router = owner.lookup('router:main'); if (params.length === 1) {} else if (params.length !== 2) { throw new _emberMetalError.default('You must pass a templateName to render'); } var templateName = 'template:' + name; - var view = owner.lookup('view:' + name); - if (!view) { - view = owner.lookup('view:default'); - } - var viewHasTemplateSpecified = view && !!_emberMetalProperty_get.get(view, 'template'); - if (!template && !viewHasTemplateSpecified) { + if (!template) { template = owner.lookup(templateName); } - if (view) { - view.ownerView = env.view.ownerView; - } - // provide controller override - var controllerName; - var controllerFullName; + var controllerName = undefined; + var controllerFullName = undefined; if (hash.controller) { controllerName = hash.controller; controllerFullName = 'controller:' + controllerName; delete hash.controller; @@ -13013,11 +12612,11 @@ controllerName = name; controllerFullName = 'controller:' + controllerName; } var target = router; - var controller; + var controller = undefined; // choose name if (params.length > 1) { var factory = owner._lookupFactory(controllerFullName) || _emberRoutingSystemGenerate_controller.generateControllerFactory(owner, controllerName); @@ -13033,30 +12632,21 @@ controller.setProperties({ target: target }); } - if (view) { - view.set('controller', controller); - } state.controller = controller; - hash.viewName = _emberRuntimeSystemString.camelize(name); - if (template && template.raw) { template = template.raw; } var options = { layout: null, self: controller }; - if (view) { - options.component = view; - } - var nodeManager = _emberHtmlbarsNodeManagersViewNodeManager.default.create(node, env, hash, options, state.parentView, null, null, template); state.manager = nodeManager; if (router && params.length === 1) { router._connectActiveComponentNode(name, nodeManager); @@ -13404,299 +12994,10 @@ } env.hooks.range(morph, env, scope, null, stream, visitor); return true; } }); -enifed('ember-htmlbars/keywords/view', ['exports', 'ember-htmlbars/streams/utils', 'ember-views/views/view', 'ember-htmlbars/node-managers/view-node-manager'], function (exports, _emberHtmlbarsStreamsUtils, _emberViewsViewsView, _emberHtmlbarsNodeManagersViewNodeManager) { - /** - @module ember - @submodule ember-templates - */ - - 'use strict'; - - /** - `{{view}}` inserts a new instance of an `Ember.View` into a template passing its - options to the `Ember.View`'s `create` method and using the supplied block as - the view's own template. - - An empty `<body>` and the following template: - - ```handlebars - A span: - {{#view tagName="span"}} - hello. - {{/view}} - ``` - - Will result in HTML structure: - - ```html - <body> - <!-- Note: the handlebars template script - also results in a rendered Ember.View - which is the outer <div> here --> - - <div class="ember-view"> - A span: - <span id="ember1" class="ember-view"> - Hello. - </span> - </div> - </body> - ``` - - ### `parentView` setting - - The `parentView` property of the new `Ember.View` instance created through - `{{view}}` will be set to the `Ember.View` instance of the template where - `{{view}}` was called. - - ```javascript - aView = Ember.View.create({ - template: Ember.Handlebars.compile("{{#view}} my parent: {{parentView.elementId}} {{/view}}") - }); - - aView.appendTo('body'); - ``` - - Will result in HTML structure: - - ```html - <div id="ember1" class="ember-view"> - <div id="ember2" class="ember-view"> - my parent: ember1 - </div> - </div> - ``` - - ### Setting CSS id and class attributes - - The HTML `id` attribute can be set on the `{{view}}`'s resulting element with - the `id` option. This option will _not_ be passed to `Ember.View.create`. - - ```handlebars - {{#view tagName="span" id="a-custom-id"}} - hello. - {{/view}} - ``` - - Results in the following HTML structure: - - ```html - <div class="ember-view"> - <span id="a-custom-id" class="ember-view"> - hello. - </span> - </div> - ``` - - The HTML `class` attribute can be set on the `{{view}}`'s resulting element - with the `class` or `classNameBindings` options. The `class` option will - directly set the CSS `class` attribute and will not be passed to - `Ember.View.create`. `classNameBindings` will be passed to `create` and use - `Ember.View`'s class name binding functionality: - - ```handlebars - {{#view tagName="span" class="a-custom-class"}} - hello. - {{/view}} - ``` - - Results in the following HTML structure: - - ```html - <div class="ember-view"> - <span id="ember2" class="ember-view a-custom-class"> - hello. - </span> - </div> - ``` - - ### Supplying a different view class - - `{{view}}` can take an optional first argument before its supplied options to - specify a path to a custom view class. - - ```handlebars - {{#view "custom"}}{{! will look up App.CustomView }} - hello. - {{/view}} - ``` - - The first argument can also be a relative path accessible from the current - context. - - ```javascript - MyApp = Ember.Application.create({}); - MyApp.OuterView = Ember.View.extend({ - innerViewClass: Ember.View.extend({ - classNames: ['a-custom-view-class-as-property'] - }), - template: Ember.Handlebars.compile('{{#view view.innerViewClass}} hi {{/view}}') - }); - - MyApp.OuterView.create().appendTo('body'); - ``` - - Will result in the following HTML: - - ```html - <div id="ember1" class="ember-view"> - <div id="ember2" class="ember-view a-custom-view-class-as-property"> - hi - </div> - </div> - ``` - - ### Blockless use - - If you supply a custom `Ember.View` subclass that specifies its own template - or provide a `templateName` option to `{{view}}` it can be used without - supplying a block. Attempts to use both a `templateName` option and supply a - block will throw an error. - - ```javascript - var App = Ember.Application.create(); - App.WithTemplateDefinedView = Ember.View.extend({ - templateName: 'defined-template' - }); - ``` - - ```handlebars - {{! application.hbs }} - {{view 'with-template-defined'}} - ``` - - ```handlebars - {{! defined-template.hbs }} - Some content for the defined template view. - ``` - - ### `viewName` property - - You can supply a `viewName` option to `{{view}}`. The `Ember.View` instance - will be referenced as a property of its parent view by this name. - - ```javascript - aView = Ember.View.create({ - template: Ember.Handlebars.compile('{{#view viewName="aChildByName"}} hi {{/view}}') - }); - - aView.appendTo('body'); - aView.get('aChildByName') // the instance of Ember.View created by {{view}} helper - ``` - - @method view - @for Ember.Templates.helpers - @public - @deprecated - */ - - exports.default = { - setupState: function (state, env, scope, params, hash) { - var read = env.hooks.getValue; - var targetObject = read(scope.getSelf()); - var viewClassOrInstance = state.viewClassOrInstance; - if (!viewClassOrInstance) { - viewClassOrInstance = getView(read(params[0]), env.owner); - } - - // if parentView exists, use its controller (the default - // behavior), otherwise use `scope.self` as the controller - var controller = scope.hasLocal('view') ? null : read(scope.getSelf()); - - return { - manager: state.manager, - parentView: env.view, - controller: controller, - targetObject: targetObject, - viewClassOrInstance: viewClassOrInstance - }; - }, - - rerender: function (morph, env, scope, params, hash, template, inverse, visitor) { - // If the hash is empty, the component cannot have extracted a part - // of a mutable param and used it in its layout, because there are - // no params at all. - if (Object.keys(hash).length) { - return morph.getState().manager.rerender(env, hash, visitor, true); - } - }, - - render: function (node, env, scope, params, hash, template, inverse, visitor) { - if (hash.tag) { - hash = swapKey(hash, 'tag', 'tagName'); - } - - if (hash.classNameBindings) { - hash.classNameBindings = hash.classNameBindings.split(' '); - } - - var state = node.getState(); - var parentView = state.parentView; - - var options = { - component: state.viewClassOrInstance, - layout: null - }; - - options.createOptions = {}; - if (state.controller) { - // Use `_controller` to avoid stomping on a CP - // that exists in the target view/component - options.createOptions._controller = state.controller; - } - - if (state.targetObject) { - // Use `_targetObject` to avoid stomping on a CP - // that exists in the target view/component - options.createOptions._targetObject = state.targetObject; - } - - if (state.manager) { - state.manager.destroy(); - state.manager = null; - } - - var nodeManager = _emberHtmlbarsNodeManagersViewNodeManager.default.create(node, env, hash, options, parentView, null, scope, template); - state.manager = nodeManager; - - nodeManager.render(env, hash, visitor); - } - }; - - function getView(viewPath, owner) { - var viewClassOrInstance; - - if (!viewPath) { - if (owner) { - viewClassOrInstance = owner._lookupFactory('view:toplevel'); - } else { - viewClassOrInstance = _emberViewsViewsView.default; - } - } else { - viewClassOrInstance = _emberHtmlbarsStreamsUtils.readViewFactory(viewPath, owner); - } - - return viewClassOrInstance; - } - - function swapKey(hash, original, update) { - var newHash = {}; - - for (var prop in hash) { - if (prop === original) { - newHash[update] = hash[prop]; - } else { - newHash[prop] = hash[prop]; - } - } - - return newHash; - } -}); enifed('ember-htmlbars/keywords/with', ['exports', 'ember-metal/debug', 'htmlbars-runtime'], function (exports, _emberMetalDebug, _htmlbarsRuntime) { /** @module ember @submodule ember-templates */ @@ -13736,18 +13037,72 @@ } return true; } }); -enifed('ember-htmlbars/morphs/attr-morph', ['exports', 'ember-metal/debug', 'dom-helper', 'ember-metal/is_none'], function (exports, _emberMetalDebug, _domHelper, _emberMetalIs_none) { +enifed('ember-htmlbars/make-bound-helper', ['exports', 'ember-metal/debug', 'ember-htmlbars/helper'], function (exports, _emberMetalDebug, _emberHtmlbarsHelper) { + /** + @module ember + @submodule ember-templates + */ 'use strict'; - var HTMLBarsAttrMorph = _domHelper.default.prototype.AttrMorphClass; + exports.default = makeBoundHelper; - var styleWarning = '' + 'Binding style attributes may introduce cross-site scripting vulnerabilities; ' + 'please ensure that values being bound are properly escaped. For more information, ' + 'including how to disable this warning, see ' + 'http://emberjs.com/deprecations/v1.x/#toc_binding-style-attributes.'; + /** + Create a bound helper. Accepts a function that receives the ordered and hash parameters + from the template. If a bound property was provided in the template, it will be resolved to its + value and any changes to the bound property cause the helper function to be re-run with the updated + values. + + * `params` - An array of resolved ordered parameters. + * `hash` - An object containing the hash parameters. + + For example: + + * With an unquoted ordered parameter: + + ```javascript + {{x-capitalize foo}} + ``` + + Assuming `foo` was set to `"bar"`, the bound helper would receive `["bar"]` as its first argument, and + an empty hash as its second. + + * With a quoted ordered parameter: + + ```javascript + {{x-capitalize "foo"}} + ``` + + The bound helper would receive `["foo"]` as its first argument, and an empty hash as its second. + + * With an unquoted hash parameter: + + ```javascript + {{x-repeat "foo" count=repeatCount}} + ``` + + Assuming that `repeatCount` resolved to 2, the bound helper would receive `["foo"]` as its first argument, + and { count: 2 } as its second. + + @private + @method makeBoundHelper + @for Ember.HTMLBars + @param {Function} fn + @since 1.10.0 + */ - exports.styleWarning = styleWarning; + function makeBoundHelper(fn) { + return _emberHtmlbarsHelper.helper(fn); + } +}); +enifed('ember-htmlbars/morphs/attr-morph', ['exports', 'ember-metal/debug', 'dom-helper', 'ember-metal/is_none', 'ember-views/system/utils'], function (exports, _emberMetalDebug, _domHelper, _emberMetalIs_none, _emberViewsSystemUtils) { + 'use strict'; + + var HTMLBarsAttrMorph = _domHelper.default.prototype.AttrMorphClass; + var proto = HTMLBarsAttrMorph.prototype; proto.didInit = function () { this.streamUnsubscribers = null; }; @@ -13763,10 +13118,12 @@ // SafeString enifed('ember-htmlbars/morphs/morph', ['exports', 'dom-helper', 'ember-metal/debug'], function (exports, _domHelper, _emberMetalDebug) { 'use strict'; + exports.default = EmberMorph; + var HTMLBarsMorph = _domHelper.default.prototype.MorphClass; var guid = 1; function EmberMorph(DOMHelper, contextualElement) { this.HTMLBarsMorph$constructor(DOMHelper, contextualElement); @@ -13789,25 +13146,16 @@ var proto = EmberMorph.prototype = Object.create(HTMLBarsMorph.prototype); proto.HTMLBarsMorph$constructor = HTMLBarsMorph; proto.HTMLBarsMorph$clear = HTMLBarsMorph.prototype.clear; proto.addDestruction = function (toDestroy) { + // called from Router.prototype._connectActiveComponentNode for {{render}} this.emberToDestroy = this.emberToDestroy || []; this.emberToDestroy.push(toDestroy); }; proto.cleanup = function () { - var view = this.emberView; - - if (view) { - var parentView = view.parentView; - - if (parentView && view.ownerView._destroyingSubtreeForView === parentView) { - parentView.removeChild(view); - } - } - var toDestroy = this.emberToDestroy; if (toDestroy) { for (var i = 0; i < toDestroy.length; i++) { toDestroy[i].destroy(); @@ -13818,14 +13166,12 @@ }; proto.didRender = function (env, scope) { env.renderedNodes.add(this); }; - - exports.default = EmberMorph; }); -enifed('ember-htmlbars/node-managers/component-node-manager', ['exports', 'ember-metal/debug', 'ember-htmlbars/system/build-component-template', 'ember-htmlbars/hooks/get-cell-or-value', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-views/compat/attrs-proxy', 'ember-htmlbars/system/instrumentation-support', 'ember-htmlbars/component', 'ember-htmlbars/utils/extract-positional-params', 'container/owner', 'ember-htmlbars/hooks/get-value'], function (exports, _emberMetalDebug, _emberHtmlbarsSystemBuildComponentTemplate, _emberHtmlbarsHooksGetCellOrValue, _emberMetalProperty_get, _emberMetalProperty_set, _emberViewsCompatAttrsProxy, _emberHtmlbarsSystemInstrumentationSupport, _emberHtmlbarsComponent, _emberHtmlbarsUtilsExtractPositionalParams, _containerOwner, _emberHtmlbarsHooksGetValue) { +enifed('ember-htmlbars/node-managers/component-node-manager', ['exports', 'ember-metal/debug', 'ember-htmlbars/system/build-component-template', 'ember-htmlbars/hooks/get-cell-or-value', 'ember-metal/property_get', 'ember-views/compat/attrs-proxy', 'ember-htmlbars/system/instrumentation-support', 'ember-htmlbars/component', 'ember-htmlbars/utils/extract-positional-params', 'container/owner', 'ember-htmlbars/hooks/get-value'], function (exports, _emberMetalDebug, _emberHtmlbarsSystemBuildComponentTemplate, _emberHtmlbarsHooksGetCellOrValue, _emberMetalProperty_get, _emberViewsCompatAttrsProxy, _emberHtmlbarsSystemInstrumentationSupport, _emberHtmlbarsComponent, _emberHtmlbarsUtilsExtractPositionalParams, _containerOwner, _emberHtmlbarsHooksGetValue) { 'use strict'; exports.default = ComponentNodeManager; exports.createComponent = createComponent; exports.takeLegacySnapshot = takeLegacySnapshot; @@ -13862,31 +13208,31 @@ // Map passed attributes (e.g. <my-component id="foo">) to component // properties ({ id: "foo" }). configureCreateOptions(attrs, createOptions); - // If there is a controller on the scope, pluck it off and save it on the - // component. This allows the component to target actions sent via - // `sendAction` correctly. - if (parentScope.hasLocal('controller')) { - createOptions._controller = _emberHtmlbarsHooksGetValue.default(parentScope.getLocal('controller')); - } else { - createOptions._targetObject = _emberHtmlbarsHooksGetValue.default(parentScope.getSelf()); - } + // This allows the component to target actions sent via `sendAction` correctly. + createOptions._targetObject = _emberHtmlbarsHooksGetValue.default(parentScope.getSelf()); _emberHtmlbarsUtilsExtractPositionalParams.default(renderNode, component, params, attrs); // Instantiate the component component = createComponent(component, createOptions, renderNode, env, attrs); + var layoutName = _emberMetalProperty_get.get(component, 'layoutName'); // If the component specifies its layout via the `layout` property // instead of using the template looked up in the container, get it // now that we have the component instance. if (!layout) { layout = _emberMetalProperty_get.get(component, 'layout'); } + if (!layout && layoutName) { + var owner = _containerOwner.getOwner(component); + layout = owner.lookup('template:' + layoutName); + } + var results = _emberHtmlbarsSystemBuildComponentTemplate.default({ layout: layout, component: component }, attrs, { templates: templates, scope: parentScope }); return new ComponentNodeManager(component, parentScope, renderNode, attrs, results.block, results.createdElement); }; @@ -13904,13 +13250,10 @@ createOptions.elementId = _emberHtmlbarsHooksGetValue.default(attrs.id); } if (attrs._defaultTagName) { createOptions._defaultTagName = _emberHtmlbarsHooksGetValue.default(attrs._defaultTagName); } - if (attrs.viewName) { - createOptions.viewName = _emberHtmlbarsHooksGetValue.default(attrs.viewName); - } } ComponentNodeManager.prototype.render = function ComponentNodeManager_render(_env, visitor) { var component = this.component; @@ -13989,20 +13332,15 @@ snapshotAndUpdateTarget(attrs, props); _containerOwner.setOwner(props, env.owner); props.renderer = props.parentView ? props.parentView.renderer : env.owner.lookup('renderer:-dom'); - props._viewRegistry = props.parentView ? props.parentView._viewRegistry : env.owner.lookup('-view-registry:main'); var component = _component.create(props); if (props.parentView) { props.parentView.appendChild(component); - - if (props.viewName) { - _emberMetalProperty_set.set(props.parentView, props.viewName, component); - } } component._renderNode = renderNode; renderNode.emberView = component; renderNode.buildChildEnv = buildChildEnv; @@ -14061,11 +13399,11 @@ // In theory this should come through the env, but it should // be safe to import this until we make the hook system public // and it gets actively used in addons or other downstream // libraries. -enifed('ember-htmlbars/node-managers/view-node-manager', ['exports', 'ember-metal/assign', 'ember-metal/debug', 'ember-htmlbars/system/build-component-template', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/set_properties', 'ember-views/views/view', 'ember-views/compat/attrs-proxy', 'ember-htmlbars/hooks/get-cell-or-value', 'ember-htmlbars/system/instrumentation-support', 'ember-htmlbars/node-managers/component-node-manager', 'container/owner', 'ember-htmlbars/hooks/get-value'], function (exports, _emberMetalAssign, _emberMetalDebug, _emberHtmlbarsSystemBuildComponentTemplate, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalSet_properties, _emberViewsViewsView, _emberViewsCompatAttrsProxy, _emberHtmlbarsHooksGetCellOrValue, _emberHtmlbarsSystemInstrumentationSupport, _emberHtmlbarsNodeManagersComponentNodeManager, _containerOwner, _emberHtmlbarsHooksGetValue) { +enifed('ember-htmlbars/node-managers/view-node-manager', ['exports', 'ember-metal/assign', 'ember-metal/debug', 'ember-htmlbars/system/build-component-template', 'ember-metal/property_get', 'ember-metal/set_properties', 'ember-views/compat/attrs-proxy', 'ember-htmlbars/hooks/get-cell-or-value', 'ember-htmlbars/system/instrumentation-support', 'ember-htmlbars/node-managers/component-node-manager', 'container/owner', 'ember-htmlbars/hooks/get-value'], function (exports, _emberMetalAssign, _emberMetalDebug, _emberHtmlbarsSystemBuildComponentTemplate, _emberMetalProperty_get, _emberMetalSet_properties, _emberViewsCompatAttrsProxy, _emberHtmlbarsHooksGetCellOrValue, _emberHtmlbarsSystemInstrumentationSupport, _emberHtmlbarsNodeManagersComponentNodeManager, _containerOwner, _emberHtmlbarsHooksGetValue) { 'use strict'; exports.default = ViewNodeManager; exports.createOrUpdateComponent = createOrUpdateComponent; @@ -14077,11 +13415,11 @@ this.expectElement = expectElement; } ViewNodeManager.create = function ViewNodeManager_create(renderNode, env, attrs, found, parentView, path, contentScope, contentTemplate) { - var component; + var component = undefined; var componentInfo = { layout: found.layout }; if (found.component) { var options = { parentView: parentView }; @@ -14092,25 +13430,11 @@ options.tagName = _emberHtmlbarsHooksGetValue.default(attrs.tagName); } if (attrs && attrs._defaultTagName) { options._defaultTagName = _emberHtmlbarsHooksGetValue.default(attrs._defaultTagName); } - if (attrs && attrs.viewName) { - options.viewName = _emberHtmlbarsHooksGetValue.default(attrs.viewName); - } - if (found.component.create && contentScope) { - var _self = contentScope.getSelf(); - if (_self) { - options._context = _emberHtmlbarsHooksGetValue.default(contentScope.getSelf()); - } - } - - if (found.self) { - options._context = _emberHtmlbarsHooksGetValue.default(found.self); - } - component = componentInfo.component = createOrUpdateComponent(found.component, options, found.createOptions, renderNode, env, attrs); var layout = _emberMetalProperty_get.get(component, 'layout'); if (layout) { componentInfo.layout = layout; @@ -14223,37 +13547,28 @@ function createOrUpdateComponent(component, options, createOptions, renderNode, env) { var attrs = arguments.length <= 5 || arguments[5] === undefined ? {} : arguments[5]; var snapshot = takeSnapshot(attrs); var props = _emberMetalAssign.default({}, options); - var defaultController = _emberViewsViewsView.default.proto().controller; - var hasSuppliedController = 'controller' in attrs || 'controller' in props; if (!props.ownerView && options.parentView) { props.ownerView = options.parentView.ownerView; } props.attrs = snapshot; if (component.create) { - var proto = component.proto(); - if (createOptions) { _emberMetalAssign.default(props, createOptions); } mergeBindings(props, snapshot); var owner = env.owner; _containerOwner.setOwner(props, owner); props.renderer = options.parentView ? options.parentView.renderer : owner && owner.lookup('renderer:-dom'); - props._viewRegistry = options.parentView ? options.parentView._viewRegistry : owner && owner.lookup('-view-registry:main'); - if (proto.controller !== defaultController || hasSuppliedController) { - delete props._context; - } - component = component.create(props); } else { env.renderer.componentUpdateAttrs(component, snapshot); _emberMetalSet_properties.default(component, props); @@ -14262,14 +13577,10 @@ } } if (options.parentView) { options.parentView.appendChild(component); - - if (options.viewName) { - _emberMetalProperty_set.set(options.parentView, options.viewName, component); - } } component._renderNode = renderNode; renderNode.emberView = component; @@ -14313,30 +13624,33 @@ // In theory this should come through the env, but it should // be safe to import this until we make the hook system public // and it gets actively used in addons or other downstream // libraries. -enifed('ember-htmlbars/renderer', ['exports', 'ember-metal/run_loop', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/assign', 'ember-metal/set_properties', 'ember-htmlbars/system/build-component-template', 'ember-environment', 'htmlbars-runtime', 'ember-htmlbars/system/render-view'], function (exports, _emberMetalRun_loop, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalAssign, _emberMetalSet_properties, _emberHtmlbarsSystemBuildComponentTemplate, _emberEnvironment, _htmlbarsRuntime, _emberHtmlbarsSystemRenderView) { +enifed('ember-htmlbars/renderer', ['exports', 'ember-metal/run_loop', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/assign', 'ember-metal/set_properties', 'ember-htmlbars/system/build-component-template', 'ember-environment', 'htmlbars-runtime', 'ember-htmlbars/system/render-view', 'ember-views/compat/fallback-view-registry', 'ember-metal/debug'], function (exports, _emberMetalRun_loop, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalAssign, _emberMetalSet_properties, _emberHtmlbarsSystemBuildComponentTemplate, _emberEnvironment, _htmlbarsRuntime, _emberHtmlbarsSystemRenderView, _emberViewsCompatFallbackViewRegistry, _emberMetalDebug) { 'use strict'; exports.Renderer = Renderer; exports.MorphSet = MorphSet; function Renderer(domHelper) { var _ref = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; var destinedForDOM = _ref.destinedForDOM; + var _viewRegistry = _ref._viewRegistry; this._dom = domHelper; // This flag indicates whether the resulting rendered element will be // inserted into the DOM. This should be set to `false` if the rendered // element is going to be serialized to HTML without being inserted into // the DOM (e.g., in FastBoot mode). By default, this flag is the same // as whether we are running in an environment with DOM, but may be // overridden. this._destinedForDOM = destinedForDOM === undefined ? _emberEnvironment.environment.hasDOM : destinedForDOM; + + this._viewRegistry = _viewRegistry || _emberViewsCompatFallbackViewRegistry.default; } Renderer.prototype.prerenderTopLevelView = function Renderer_prerenderTopLevelView(view, renderNode) { if (view._state === 'inDOM') { throw new Error('You cannot insert a View that has already been rendered'); @@ -14383,11 +13697,12 @@ Renderer.prototype.dispatchLifecycleHooks = function Renderer_dispatchLifecycleHooks(env) { var ownerView = env.view; var lifecycleHooks = env.lifecycleHooks; - var i, hook; + var i = undefined, + hook = undefined; for (i = 0; i < lifecycleHooks.length; i++) { hook = lifecycleHooks[i]; ownerView._dispatching = hook.type; @@ -14474,14 +13789,10 @@ if (view.trigger) { view.trigger('willInsertElement'); } }; // Will place into DOM. - Renderer.prototype.setAttrs = function (view, attrs) { - _emberMetalProperty_set.set(view, 'attrs', attrs); - }; // Set attrs the first time. - Renderer.prototype.componentInitAttrs = function (component, attrs) { component.trigger('didInitAttrs', { attrs: attrs }); component.trigger('didReceiveAttrs', { newAttrs: attrs }); }; // Set attrs the first time. @@ -14505,14 +13816,10 @@ if (view.trigger) { view.trigger('didRender'); } }; - Renderer.prototype.updateAttrs = function (view, attrs) { - this.setAttrs(view, attrs); - }; // Setting new attrs. - Renderer.prototype.componentUpdateAttrs = function (component, newAttrs) { var oldAttrs = null; if (component.attrs) { oldAttrs = _emberMetalAssign.default({}, component.attrs); @@ -14558,81 +13865,84 @@ renderNode.ownerNode.emberView.scheduleRevalidate(renderNode, view.toString(), 'rerendering'); }; Renderer.prototype.remove = function (view, shouldDestroy) { - this.willDestroyElement(view); + var renderNode = view._renderNode; + view._renderNode = null; + if (renderNode) { + renderNode.emberView = null; + this.willDestroyElement(view); + view._transitionTo('destroying'); - view._willRemoveElement = true; - _emberMetalRun_loop.default.schedule('render', this, this.renderElementRemoval, view); - }; - - Renderer.prototype.renderElementRemoval = function Renderer_renderElementRemoval(view) { - // Use the _willRemoveElement flag to avoid mulitple removal attempts in - // case many have been scheduled. This should be more performant than using - // `scheduleOnce`. - if (view._willRemoveElement) { - view._willRemoveElement = false; - - if (view._renderNode && view.element && view.element.parentNode) { - view._renderNode.clear(); + view._renderNode = null; + var _lastResult = renderNode.lastResult; + if (_lastResult) { + _htmlbarsRuntime.internal.clearMorph(renderNode, _lastResult.env, shouldDestroy !== false); } + if (!shouldDestroy) { + view._transitionTo('preRender'); + } this.didDestroyElement(view); } - }; - Renderer.prototype.willRemoveElement = function () /*view*/{}; + // toplevel view removed, remove insertion point + var lastResult = view.lastResult; + if (lastResult) { + view.lastResult = null; + lastResult.destroy(); + } - Renderer.prototype.willDestroyElement = function (view) { - if (view._willDestroyElement) { - view._willDestroyElement(); + if (shouldDestroy && !view.isDestroying) { + view.destroy(); } + }; + + Renderer.prototype.willDestroyElement = function (view) { if (view.trigger) { view.trigger('willDestroyElement'); view.trigger('willClearRender'); } - - if (view._transitionTo) { - view._transitionTo('destroying'); - } }; Renderer.prototype.didDestroyElement = function (view) { view.element = null; - // Views that are being destroyed should never go back to the preRender state. - // However if we're just destroying an element on a view (as is the case when - // using View#remove) then the view should go to a preRender state so that - // it can be rendered again later. - if (view._state !== 'destroying' && view._transitionTo) { - view._transitionTo('preRender'); - } - if (view.trigger) { view.trigger('didDestroyElement'); } - }; // Element destroyed so view.destroy shouldn't try to remove it removedFromDOM + }; + Renderer.prototype._register = function Renderer_register(view) { + this._viewRegistry[view.elementId] = view; + }; + + Renderer.prototype._unregister = function Renderer_unregister(view) { + delete this._viewRegistry[this.elementId]; + }; + var InertRenderer = { create: function (_ref2) { var dom = _ref2.dom; + var _viewRegistry = _ref2._viewRegistry; - return new Renderer(dom, { destinedForDOM: false }); + return new Renderer(dom, { destinedForDOM: false, _viewRegistry: _viewRegistry }); } }; exports.InertRenderer = InertRenderer; var InteractiveRenderer = { create: function (_ref3) { var dom = _ref3.dom; + var _viewRegistry = _ref3._viewRegistry; - return new Renderer(dom, { destinedForDOM: true }); + return new Renderer(dom, { destinedForDOM: true, _viewRegistry: _viewRegistry }); } }; exports.InteractiveRenderer = InteractiveRenderer; }); -enifed('ember-htmlbars/setup-registry', ['exports', 'ember-htmlbars/renderer', 'ember-htmlbars/system/dom-helper', 'ember-htmlbars/templates/top-level-view', 'ember-htmlbars/views/outlet', 'ember-views/views/view', 'ember-htmlbars/components/text_field', 'ember-htmlbars/components/text_area', 'ember-htmlbars/components/checkbox', 'ember-htmlbars/components/link-to'], function (exports, _emberHtmlbarsRenderer, _emberHtmlbarsSystemDomHelper, _emberHtmlbarsTemplatesTopLevelView, _emberHtmlbarsViewsOutlet, _emberViewsViewsView, _emberHtmlbarsComponentsText_field, _emberHtmlbarsComponentsText_area, _emberHtmlbarsComponentsCheckbox, _emberHtmlbarsComponentsLinkTo) { +enifed('ember-htmlbars/setup-registry', ['exports', 'ember-htmlbars/renderer', 'ember-htmlbars/system/dom-helper', 'ember-htmlbars/templates/top-level-view', 'ember-htmlbars/views/outlet', 'ember-views/views/view', 'ember-htmlbars/components/text_field', 'ember-htmlbars/components/text_area', 'ember-htmlbars/components/checkbox', 'ember-htmlbars/components/link-to', 'ember-views/mixins/template_support'], function (exports, _emberHtmlbarsRenderer, _emberHtmlbarsSystemDomHelper, _emberHtmlbarsTemplatesTopLevelView, _emberHtmlbarsViewsOutlet, _emberViewsViewsView, _emberHtmlbarsComponentsText_field, _emberHtmlbarsComponentsText_area, _emberHtmlbarsComponentsCheckbox, _emberHtmlbarsComponentsLinkTo, _emberViewsMixinsTemplate_support) { 'use strict'; exports.setupApplicationRegistry = setupApplicationRegistry; exports.setupEngineRegistry = setupEngineRegistry; @@ -14651,22 +13961,22 @@ function setupEngineRegistry(registry) { registry.optionsForType('template', { instantiate: false }); registry.register('view:-outlet', _emberHtmlbarsViewsOutlet.OutletView); registry.register('template:-outlet', _emberHtmlbarsTemplatesTopLevelView.default); - registry.register('view:toplevel', _emberViewsViewsView.default.extend()); + registry.register('view:toplevel', _emberViewsViewsView.default.extend(_emberViewsMixinsTemplate_support.default)); registry.register('component:-text-field', _emberHtmlbarsComponentsText_field.default); registry.register('component:-text-area', _emberHtmlbarsComponentsText_area.default); registry.register('component:-checkbox', _emberHtmlbarsComponentsCheckbox.default); registry.register('component:link-to', _emberHtmlbarsComponentsLinkTo.default); } }); enifed('ember-htmlbars/streams/built-in-helper', ['exports', 'ember-htmlbars/streams/stream', 'ember-htmlbars/streams/utils'], function (exports, _emberHtmlbarsStreamsStream, _emberHtmlbarsStreamsUtils) { 'use strict'; - var BuiltInHelperStream = _emberHtmlbarsStreamsStream.default.extend({ + exports.default = _emberHtmlbarsStreamsStream.default.extend({ init: function (helper, params, hash, templates, env, scope, label) { this.helper = helper; this.params = params; this.templates = templates; this.env = env; @@ -14677,12 +13987,10 @@ compute: function () { return this.helper(_emberHtmlbarsStreamsUtils.getArrayValues(this.params), _emberHtmlbarsStreamsUtils.getHashValues(this.hash), this.templates, this.env, this.scope); } }); - - exports.default = BuiltInHelperStream; }); enifed('ember-htmlbars/streams/class_name_binding', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/utils', 'ember-htmlbars/streams/utils', 'ember-runtime/system/string'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalUtils, _emberHtmlbarsStreamsUtils, _emberRuntimeSystemString) { 'use strict'; exports.parsePropertyPath = parsePropertyPath; @@ -14711,11 +14019,12 @@ function parsePropertyPath(path) { var split = path.split(':'); var propertyPath = split[0]; var classNames = ''; - var className, falsyClassName; + var className = undefined, + falsyClassName = undefined; // check if the property is defined as prop:class or prop:trueClass:falseClass if (split.length > 1) { className = split[1]; if (split.length === 3) { @@ -14803,30 +14112,95 @@ var parsedPath = parsePropertyPath(classNameBinding); if (parsedPath.path === '') { return classStringForValue(parsedPath.path, true, parsedPath.className, parsedPath.falsyClassName); } else { - var pathValue = view.getStream(prefix + parsedPath.path); - return _emberHtmlbarsStreamsUtils.chain(pathValue, function () { - return classStringForValue(parsedPath.path, _emberHtmlbarsStreamsUtils.read(pathValue), parsedPath.className, parsedPath.falsyClassName); - }); + var _ret = (function () { + var pathValue = view.getStream(prefix + parsedPath.path); + return { + v: _emberHtmlbarsStreamsUtils.chain(pathValue, function () { + return classStringForValue(parsedPath.path, _emberHtmlbarsStreamsUtils.read(pathValue), parsedPath.className, parsedPath.falsyClassName); + }) + }; + })(); + + if (typeof _ret === 'object') return _ret.v; } } }); +enifed('ember-htmlbars/streams/concat', ['exports', 'ember-htmlbars/streams/stream', 'ember-htmlbars/streams/utils'], function (exports, _emberHtmlbarsStreamsStream, _emberHtmlbarsStreamsUtils) { + 'use strict'; + + exports.default = concat; + + var ConcatStream = _emberHtmlbarsStreamsStream.default.extend({ + init: function (array, separator) { + this.array = array; + this.separator = separator; + + // Used by angle bracket components to detect an attribute was provided + // as a string literal. + this.isConcat = true; + }, + + label: function () { + var labels = _emberHtmlbarsStreamsUtils.labelsFor(this.array); + return 'concat([' + labels.join(', ') + ']; separator=' + _emberHtmlbarsStreamsUtils.inspect(this.separator) + ')'; + }, + + compute: function () { + return concat(_emberHtmlbarsStreamsUtils.readArray(this.array), this.separator); + } + }); + + /* + Join an array, with any streams replaced by their current values. + + @private + @for Ember.stream + @function concat + @param {Array} array An array containing zero or more stream objects and + zero or more non-stream objects. + @param {String} separator String to be used to join array elements. + @return {String} String with array elements concatenated and joined by the + provided separator, and any stream array members having been + replaced by the current value of the stream. + */ + + function concat(array, separator) { + // TODO: Create subclass ConcatStream < Stream. Defer + // subscribing to streams until the value() is called. + var hasStream = _emberHtmlbarsStreamsUtils.scanArray(array); + if (hasStream) { + var stream = new ConcatStream(array, separator); + + for (var i = 0; i < array.length; i++) { + _emberHtmlbarsStreamsUtils.addDependency(stream, array[i]); + } + + return stream; + } else { + return array.join(separator); + } + } +}); enifed('ember-htmlbars/streams/dependency', ['exports', 'ember-metal/debug', 'ember-metal/assign', 'ember-htmlbars/streams/utils'], function (exports, _emberMetalDebug, _emberMetalAssign, _emberHtmlbarsStreamsUtils) { 'use strict'; + exports.default = Dependency; + /** @module ember-metal */ /** @private @class Dependency @namespace Ember.streams @constructor */ + function Dependency(depender, dependee) { this.next = null; this.prev = null; this.depender = depender; @@ -14885,17 +14259,15 @@ // } // this.unsubscribe(); // } }); - - exports.default = Dependency; }); enifed('ember-htmlbars/streams/helper-factory', ['exports', 'ember-htmlbars/streams/stream', 'ember-htmlbars/streams/utils'], function (exports, _emberHtmlbarsStreamsStream, _emberHtmlbarsStreamsUtils) { 'use strict'; - var HelperFactoryStream = _emberHtmlbarsStreamsStream.default.extend({ + exports.default = _emberHtmlbarsStreamsStream.default.extend({ init: function (helperFactory, params, hash, label) { this.helperFactory = helperFactory; this.params = params; this.hash = hash; this.linkable = true; @@ -14917,17 +14289,15 @@ this.helper = null; } }, super$deactivate: _emberHtmlbarsStreamsStream.default.prototype.deactivate }); - - exports.default = HelperFactoryStream; }); enifed('ember-htmlbars/streams/helper-instance', ['exports', 'ember-htmlbars/streams/stream', 'ember-htmlbars/streams/utils'], function (exports, _emberHtmlbarsStreamsStream, _emberHtmlbarsStreamsUtils) { 'use strict'; - var HelperInstanceStream = _emberHtmlbarsStreamsStream.default.extend({ + exports.default = _emberHtmlbarsStreamsStream.default.extend({ init: function (helper, params, hash, label) { this.helper = helper; this.params = params; this.hash = hash; this.linkable = true; @@ -14936,12 +14306,10 @@ compute: function () { return this.helper.compute(_emberHtmlbarsStreamsUtils.getArrayValues(this.params), _emberHtmlbarsStreamsUtils.getHashValues(this.hash)); } }); - - exports.default = HelperInstanceStream; }); enifed('ember-htmlbars/streams/key-stream', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/observer', 'ember-htmlbars/streams/stream', 'ember-htmlbars/streams/utils'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalObserver, _emberHtmlbarsStreamsStream, _emberHtmlbarsStreamsUtils) { 'use strict'; function labelFor(source, key) { @@ -15124,10 +14492,11 @@ } }); enifed('ember-htmlbars/streams/stream', ['exports', 'ember-metal/assign', 'ember-metal/debug', 'ember-metal/path_cache', 'ember-metal/observer', 'ember-htmlbars/streams/utils', 'ember-metal/empty_object', 'ember-htmlbars/streams/subscriber', 'ember-htmlbars/streams/dependency', 'ember-metal/utils', 'require', 'ember-metal/symbol'], function (exports, _emberMetalAssign, _emberMetalDebug, _emberMetalPath_cache, _emberMetalObserver, _emberHtmlbarsStreamsUtils, _emberMetalEmpty_object, _emberHtmlbarsStreamsSubscriber, _emberHtmlbarsStreamsDependency, _emberMetalUtils, _require, _emberMetalSymbol) { 'use strict'; + exports.default = BasicStream; exports.wrap = wrap; var IS_STREAM = _emberMetalSymbol.default('IS_STREAM'); exports.IS_STREAM = IS_STREAM; /** @@ -15138,16 +14507,18 @@ @private @class Stream @namespace Ember.stream @constructor */ + function BasicStream(label) { this._init(label); } - var KeyStream; - var ProxyMixin; + // lazy + var KeyStream = undefined; + var ProxyMixin = undefined; BasicStream.prototype = { _init: function (label) { this[IS_STREAM] = true; this.label = makeLabel(label); @@ -15449,10 +14820,12 @@ compute: function () { return this._compute(); } }); + exports.Stream = Stream; + function wrap(value, Kind, param) { if (_emberHtmlbarsStreamsUtils.isStream(value)) { return value; } else { return new Kind(value, param); @@ -15464,27 +14837,27 @@ return '(no label)'; } else { return label; } } - - exports.default = BasicStream; - exports.Stream = Stream; }); enifed('ember-htmlbars/streams/subscriber', ['exports', 'ember-metal/assign'], function (exports, _emberMetalAssign) { 'use strict'; + exports.default = Subscriber; + /** @module ember-metal */ /** @private @class Subscriber @namespace Ember.streams @constructor */ + function Subscriber(callback, context) { this.next = null; this.prev = null; this.callback = callback; this.context = context; @@ -15508,12 +14881,10 @@ } stream.maybeDeactivate(); } }); - - exports.default = Subscriber; }); enifed('ember-htmlbars/streams/utils', ['exports', 'ember-htmlbars/hooks/get-value', 'ember-metal/debug', 'ember-htmlbars/streams/stream', 'ember-metal/property_get', 'ember-runtime/mixins/controller'], function (exports, _emberHtmlbarsHooksGetValue, _emberMetalDebug, _emberHtmlbarsStreamsStream, _emberMetalProperty_get, _emberRuntimeMixinsController) { 'use strict'; exports.getArrayValues = getArrayValues; @@ -15524,11 +14895,10 @@ exports.read = read; exports.readArray = readArray; exports.readHash = readHash; exports.scanArray = scanArray; exports.scanHash = scanHash; - exports.concat = concat; exports.labelsFor = labelsFor; exports.labelsForObject = labelsForObject; exports.labelFor = labelFor; exports.or = or; exports.addDependency = addDependency; @@ -15721,61 +15091,10 @@ } return containsStream; } - var ConcatStream = _emberHtmlbarsStreamsStream.default.extend({ - init: function (array, separator) { - this.array = array; - this.separator = separator; - - // Used by angle bracket components to detect an attribute was provided - // as a string literal. - this.isConcat = true; - }, - - label: function () { - var labels = labelsFor(this.array); - return 'concat([' + labels.join(', ') + ']; separator=' + inspect(this.separator) + ')'; - }, - - compute: function () { - return concat(readArray(this.array), this.separator); - } - }); - - /* - Join an array, with any streams replaced by their current values. - - @private - @for Ember.stream - @function concat - @param {Array} array An array containing zero or more stream objects and - zero or more non-stream objects. - @param {String} separator String to be used to join array elements. - @return {String} String with array elements concatenated and joined by the - provided separator, and any stream array members having been - replaced by the current value of the stream. - */ - - function concat(array, separator) { - // TODO: Create subclass ConcatStream < Stream. Defer - // subscribing to streams until the value() is called. - var hasStream = scanArray(array); - if (hasStream) { - var stream = new ConcatStream(array, separator); - - for (var i = 0; i < array.length; i++) { - addDependency(stream, array[i]); - } - - return stream; - } else { - return array.join(separator); - } - } - function labelsFor(streams) { var labels = []; for (var i = 0; i < streams.length; i++) { var stream = streams[i]; @@ -15875,14 +15194,14 @@ The value to transform would typically be available to the function you pass to `chain()` via scope. For example: ```javascript - var source = ...; // stream returning a number + let source = ...; // stream returning a number // or a numeric (non-stream) object - var result = chain(source, function() { - var currentValue = read(source); + let result = chain(source, function() { + let currentValue = read(source); return currentValue + 1; }); ``` In the example, result is a stream if source is a stream, or a number of @@ -15919,11 +15238,11 @@ } } function readViewFactory(object, owner) { var value = read(object); - var viewClass; + var viewClass = undefined; if (typeof value === 'string') { viewClass = owner._lookupFactory('view:' + value); } else { viewClass = value; @@ -15947,43 +15266,10 @@ } else { return object; } } }); -enifed('ember-htmlbars/system/append-templated-view', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-views/views/view'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberViewsViewsView) { - /** - @module ember - @submodule ember-htmlbars - */ - - 'use strict'; - - exports.default = appendTemplatedView; - - function appendTemplatedView(parentView, morph, viewClassOrInstance, props) { - var viewProto; - if (_emberViewsViewsView.default.detectInstance(viewClassOrInstance)) { - viewProto = viewClassOrInstance; - } else { - viewProto = viewClassOrInstance.proto(); - } - - // We only want to override the `_context` computed property if there is - // no specified controller. See View#_context for more information. - var noControllerInProto = !viewProto.controller; - if (viewProto.controller && viewProto.controller.isDescriptor) { - noControllerInProto = true; - } - if (noControllerInProto && !viewProto.controllerBinding && !props.controller && !props.controllerBinding) { - props._context = _emberMetalProperty_get.get(parentView, 'context'); // TODO: is this right?! - } - - props._morph = morph; - - return parentView.appendChild(viewClassOrInstance, props); - } -}); enifed('ember-htmlbars/system/build-component-template', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'htmlbars-runtime', 'htmlbars-util/template-utils', 'ember-htmlbars/hooks/get-value', 'ember-htmlbars/streams/utils'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _htmlbarsRuntime, _htmlbarsUtilTemplateUtils, _emberHtmlbarsHooksGetValue, _emberHtmlbarsStreamsUtils) { 'use strict'; exports.default = buildComponentTemplate; exports.buildHTMLTemplate = buildHTMLTemplate; @@ -16072,15 +15358,15 @@ function createContentBlocks(templates, scope, self, component) { if (!templates) { return; } var output = {}; - for (var name in templates) { - if (templates.hasOwnProperty(name)) { - var template = templates[name]; + for (var _name in templates) { + if (templates.hasOwnProperty(_name)) { + var template = templates[_name]; if (template) { - output[name] = createContentBlock(templates[name], scope, self, component); + output[_name] = createContentBlock(templates[_name], scope, self, component); } } } return output; } @@ -16108,14 +15394,10 @@ } function tagNameFor(view) { var tagName = view.tagName; - if (tagName !== null && typeof tagName === 'object' && tagName.isDescriptor) { - tagName = _emberMetalProperty_get.get(view, 'tagName'); - } - if (tagName === null || tagName === undefined) { tagName = view._defaultTagName || 'div'; } return tagName; @@ -16185,11 +15467,10 @@ return normalized; } function normalizeClass(component, attrs, streamBasePath) { - var i; var normalizedClass = []; var classNames = _emberMetalProperty_get.get(component, 'classNames'); var classNameBindings = _emberMetalProperty_get.get(component, 'classNameBindings'); if (attrs.class) { @@ -16203,11 +15484,11 @@ if (attrs.classBinding) { normalizeClasses(attrs.classBinding.split(' '), normalizedClass, streamBasePath); } if (classNames) { - for (i = 0; i < classNames.length; i++) { + for (var i = 0; i < classNames.length; i++) { normalizedClass.push(classNames[i]); } } if (classNameBindings) { @@ -16218,13 +15499,11 @@ return _htmlbarsUtilTemplateUtils.buildStatement('subexpr', '-join-classes', normalizedClass, []); } } function normalizeClasses(classes, output, streamBasePath) { - var i; - - for (i = 0; i < classes.length; i++) { + for (var i = 0; i < classes.length; i++) { var className = classes[i]; var _className$split = className.split(':'); var propName = _className$split[0]; @@ -16250,19 +15529,19 @@ function validateTaglessComponent(component) {} }); enifed('ember-htmlbars/system/dom-helper', ['exports', 'dom-helper', 'ember-htmlbars/morphs/morph', 'ember-htmlbars/morphs/attr-morph'], function (exports, _domHelper, _emberHtmlbarsMorphsMorph, _emberHtmlbarsMorphsAttrMorph) { 'use strict'; + exports.default = EmberDOMHelper; + function EmberDOMHelper(_document) { _domHelper.default.call(this, _document); } var proto = EmberDOMHelper.prototype = Object.create(_domHelper.default.prototype); proto.MorphClass = _emberHtmlbarsMorphsMorph.default; proto.AttrMorphClass = _emberHtmlbarsMorphsAttrMorph.default; - - exports.default = EmberDOMHelper; }); enifed('ember-htmlbars/system/instrumentation-support', ['exports', 'ember-metal/instrumentation'], function (exports, _emberMetalInstrumentation) { 'use strict'; exports.instrument = instrument; @@ -16279,11 +15558,14 @@ @return {Object} Return value from the invoked callback. @private */ function instrument(component, callback, context) { - var instrumentName, val, details, end; + var instrumentName = undefined, + val = undefined, + details = undefined, + end = undefined; // Only instrument if there's at least one subscriber. if (_emberMetalInstrumentation.subscribers.length) { if (component) { instrumentName = component.instrumentName; } else { @@ -16336,11 +15618,10 @@ exports.findHelper = findHelper; exports.default = lookupHelper; var CONTAINS_DASH_CACHE = new _emberMetalCache.default(1000, function (key) { return key.indexOf('-') !== -1; }); - exports.CONTAINS_DASH_CACHE = CONTAINS_DASH_CACHE; var CONTAINS_DOT_CACHE = new _emberMetalCache.default(1000, function (key) { return key.indexOf('.') !== -1; }); @@ -16405,67 +15686,10 @@ var helper = findHelper(name, view, env); return helper; } }); -enifed('ember-htmlbars/system/make_bound_helper', ['exports', 'ember-metal/debug', 'ember-htmlbars/helper'], function (exports, _emberMetalDebug, _emberHtmlbarsHelper) { - /** - @module ember - @submodule ember-htmlbars - */ - 'use strict'; - - exports.default = makeBoundHelper; - - /** - Create a bound helper. Accepts a function that receives the ordered and hash parameters - from the template. If a bound property was provided in the template, it will be resolved to its - value and any changes to the bound property cause the helper function to be re-run with the updated - values. - - * `params` - An array of resolved ordered parameters. - * `hash` - An object containing the hash parameters. - - For example: - - * With an unquoted ordered parameter: - - ```javascript - {{x-capitalize foo}} - ``` - - Assuming `foo` was set to `"bar"`, the bound helper would receive `["bar"]` as its first argument, and - an empty hash as its second. - - * With a quoted ordered parameter: - - ```javascript - {{x-capitalize "foo"}} - ``` - - The bound helper would receive `["foo"]` as its first argument, and an empty hash as its second. - - * With an unquoted hash parameter: - - ```javascript - {{x-repeat "foo" count=repeatCount}} - ``` - - Assuming that `repeatCount` resolved to 2, the bound helper would receive `["foo"]` as its first argument, - and { count: 2 } as its second. - - @private - @method makeBoundHelper - @for Ember.HTMLBars - @param {Function} fn - @since 1.10.0 - */ - - function makeBoundHelper(fn) { - return _emberHtmlbarsHelper.helper(fn); - } -}); enifed('ember-htmlbars/system/render-env', ['exports', 'ember-htmlbars/env', 'ember-htmlbars/renderer', 'container/owner'], function (exports, _emberHtmlbarsEnv, _emberHtmlbarsRenderer, _containerOwner) { 'use strict'; exports.default = RenderEnv; @@ -16566,14 +15790,30 @@ var nodeManager = new _emberHtmlbarsNodeManagersViewNodeManager.default(view, null, renderNode, block, view.tagName !== ''); nodeManager.render(env, {}); } }); -enifed("ember-htmlbars/templates/component", ["exports", "ember-htmlbars-template-compiler"], function (exports, _emberHtmlbarsTemplateCompiler) { +enifed('ember-htmlbars/system/template', ['exports', 'htmlbars-runtime/hooks'], function (exports, _htmlbarsRuntimeHooks) { + 'use strict'; + + exports.default = template; + + function template(templateSpec) { + if (!templateSpec.render) { + templateSpec = _htmlbarsRuntimeHooks.wrap(templateSpec); + } + + templateSpec.isTop = true; + templateSpec.isMethod = false; + + return templateSpec; + } +}); +enifed("ember-htmlbars/templates/component", ["exports", "ember-htmlbars"], function (exports, _emberHtmlbars) { "use strict"; - exports.default = _emberHtmlbarsTemplateCompiler.template((function () { + exports.default = _emberHtmlbars.template((function () { return { meta: {}, isEmpty: false, arity: 0, cachedFragment: null, @@ -16595,14 +15835,14 @@ locals: [], templates: [] }; })()); }); -enifed("ember-htmlbars/templates/empty", ["exports", "ember-htmlbars-template-compiler"], function (exports, _emberHtmlbarsTemplateCompiler) { +enifed("ember-htmlbars/templates/empty", ["exports", "ember-htmlbars"], function (exports, _emberHtmlbars) { "use strict"; - exports.default = _emberHtmlbarsTemplateCompiler.template((function () { + exports.default = _emberHtmlbars.template((function () { return { meta: {}, isEmpty: true, arity: 0, cachedFragment: null, @@ -16618,14 +15858,14 @@ locals: [], templates: [] }; })()); }); -enifed("ember-htmlbars/templates/link-to", ["exports", "ember-htmlbars-template-compiler"], function (exports, _emberHtmlbarsTemplateCompiler) { +enifed("ember-htmlbars/templates/link-to", ["exports", "ember-htmlbars"], function (exports, _emberHtmlbars) { "use strict"; - exports.default = _emberHtmlbarsTemplateCompiler.template((function () { + exports.default = _emberHtmlbars.template((function () { var child0 = (function () { return { meta: {}, isEmpty: false, arity: 0, @@ -16697,14 +15937,14 @@ locals: [], templates: [child0, child1] }; })()); }); -enifed("ember-htmlbars/templates/top-level-view", ["exports", "ember-htmlbars-template-compiler"], function (exports, _emberHtmlbarsTemplateCompiler) { +enifed("ember-htmlbars/templates/top-level-view", ["exports", "ember-htmlbars"], function (exports, _emberHtmlbars) { "use strict"; - exports.default = _emberHtmlbarsTemplateCompiler.template((function () { + exports.default = _emberHtmlbars.template((function () { return { meta: {}, isEmpty: false, arity: 0, cachedFragment: null, @@ -16745,11 +15985,11 @@ return key; } function decodeEachKey(item, keyPath, index) { - var key; + var key = undefined; switch (keyPath) { case '@index': key = index; break; @@ -16889,37 +16129,10 @@ return hasComponentOrTemplate(owner, path, options); } } } }); -enifed('ember-htmlbars/utils/lookup-component', ['exports'], function (exports) { - 'use strict'; - - exports.default = lookupComponent; - function lookupComponentPair(componentLookup, owner, name, options) { - return { - component: componentLookup.componentFor(name, owner, options), - layout: componentLookup.layoutFor(name, owner, options) - }; - } - - function lookupComponent(owner, name, options) { - var componentLookup = owner.lookup('component-lookup:main'); - - var source = options && options.source; - - if (source) { - var localResult = lookupComponentPair(componentLookup, owner, name, options); - - if (localResult.component || localResult.layout) { - return localResult; - } - } - - return lookupComponentPair(componentLookup, owner, name); - } -}); enifed('ember-htmlbars/utils/new-stream', ['exports', 'ember-htmlbars/streams/proxy-stream', 'ember-htmlbars/utils/subscribe'], function (exports, _emberHtmlbarsStreamsProxyStream, _emberHtmlbarsUtilsSubscribe) { 'use strict'; exports.default = newStream; @@ -16942,18 +16155,92 @@ } else { return self; } } }); -enifed('ember-htmlbars/utils/string', ['exports', 'ember-environment', 'ember-runtime/system/string', 'htmlbars-util'], function (exports, _emberEnvironment, _emberRuntimeSystemString, _htmlbarsUtil) { +enifed('ember-htmlbars/utils/string', ['exports', 'ember-metal/features', 'ember-metal/debug'], function (exports, _emberMetalFeatures, _emberMetalDebug) { /** @module ember - @submodule ember-htmlbars + @submodule ember-glimmer */ 'use strict'; + exports.getSafeString = getSafeString; + exports.escapeExpression = escapeExpression; + exports.htmlSafe = htmlSafe; + exports.isHTMLSafe = isHTMLSafe; + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + var SafeString = (function () { + function SafeString(string) { + _classCallCheck(this, SafeString); + + this.string = string; + } + + SafeString.prototype.toString = function toString() { + return '' + this.string; + }; + + SafeString.prototype.toHTML = function toHTML() { + return this.toString(); + }; + + return SafeString; + })(); + + exports.SafeString = SafeString; + + function getSafeString() { + + return SafeString; + } + + var escape = { + '&': '&amp;', + '<': '&lt;', + '>': '&gt;', + '"': '&quot;', + // jscs:disable + "'": '&#x27;', + // jscs:enable + '`': '&#x60;', + '=': '&#x3D;' + }; + + var possible = /[&<>"'`=]/; + var badChars = /[&<>"'`=]/g; + + function escapeChar(chr) { + return escape[chr]; + } + + function escapeExpression(string) { + if (typeof string !== 'string') { + // don't escape SafeStrings, since they're already safe + if (string && string.toHTML) { + return string.toHTML(); + } else if (string == null) { + return ''; + } else if (!string) { + return string + ''; + } + + // Force a string conversion as this will be done by the append regardless and + // the regex test will do this transparently behind the scenes, causing issues if + // an object's to string has escaped characters in it. + string = '' + string; + } + + if (!possible.test(string)) { + return string; + } + return string.replace(badChars, escapeChar); + } + /** Mark a string as safe for unescaped output with Ember templates. If you return HTML from a helper, use this function to ensure Ember's rendering layer does not escape the HTML. @@ -16965,29 +16252,41 @@ @for Ember.String @static @return {Handlebars.SafeString} A string that will not be HTML escaped by Handlebars. @public */ + function htmlSafe(str) { if (str === null || str === undefined) { str = ''; } else if (typeof str !== 'string') { str = '' + str; } - return new _htmlbarsUtil.SafeString(str); + return new SafeString(str); } - _emberRuntimeSystemString.default.htmlSafe = htmlSafe; - if (_emberEnvironment.ENV.EXTEND_PROTOTYPES.String) { - String.prototype.htmlSafe = function () { - return htmlSafe(this); - }; - } + /** + Detects if a string was decorated using `Ember.String.htmlSafe`. + + ```javascript + var plainString = 'plain string', + safeString = Ember.String.htmlSafe('<div>someValue</div>'); + + Ember.String.isHTMLSafe(plainString); // false + Ember.String.isHTMLSafe(safeString); // true + ``` + + @method isHTMLSafe + @for Ember.String + @static + @return {Boolean} `true` if the string was decorated with `htmlSafe`, `false` otherwise. + @public + */ - exports.SafeString = _htmlbarsUtil.SafeString; - exports.htmlSafe = htmlSafe; - exports.escapeExpression = _htmlbarsUtil.escapeExpression; + function isHTMLSafe(str) { + return str && typeof str.toHTML === 'function'; + } }); enifed('ember-htmlbars/utils/subscribe', ['exports', 'ember-htmlbars/streams/utils'], function (exports, _emberHtmlbarsStreamsUtils) { 'use strict'; exports.default = subscribe; @@ -17036,19 +16335,19 @@ } scope[key] = stream; } } }); -enifed('ember-htmlbars/views/outlet', ['exports', 'ember-views/views/view', 'ember-htmlbars/templates/top-level-view'], function (exports, _emberViewsViewsView, _emberHtmlbarsTemplatesTopLevelView) { +enifed('ember-htmlbars/views/outlet', ['exports', 'ember-views/views/view', 'ember-htmlbars/templates/top-level-view', 'ember-views/mixins/template_support'], function (exports, _emberViewsViewsView, _emberHtmlbarsTemplatesTopLevelView, _emberViewsMixinsTemplate_support) { /** @module ember @submodule ember-templates */ 'use strict'; - var CoreOutletView = _emberViewsViewsView.default.extend({ + var CoreOutletView = _emberViewsViewsView.default.extend(_emberViewsMixinsTemplate_support.default, { defaultTemplate: _emberHtmlbarsTemplatesTopLevelView.default, init: function () { this._super(); this._outlets = []; @@ -17155,14 +16454,14 @@ enifed("ember-metal/assign", ["exports"], function (exports) { /** Copy properties from a source object to a target object. ```javascript - var a = {first: 'Yehuda'}; - var b = {last: 'Katz'}; - var c = {company: 'Tilde Inc.'}; - Ember.assign(a, b, c); // a === {first: 'Yehuda', last: 'Katz', company: 'Tilde Inc.'}, b === {last: 'Katz'}, c === {company: 'Tilde Inc.'} + var a = { first: 'Yehuda' }; + var b = { last: 'Katz' }; + var c = { company: 'Tilde Inc.' }; + Ember.assign(a, b, c); // a === { first: 'Yehuda', last: 'Katz', company: 'Tilde Inc.' }, b === { last: 'Katz' }, c === { company: 'Tilde Inc.' } ``` @method assign @for Ember @param {Object} original The object to assign into @@ -17354,11 +16653,11 @@ _emberMetalObserver.addObserver(obj, this._to, this, 'toDidChange'); } _emberMetalEvents.addListener(obj, 'willDestroy', this, 'disconnect'); - fireDeprecations(obj, this._to, this._from, possibleGlobal, this._oneWay, !possibleGlobal && !this._oneWay); + fireDeprecations(possibleGlobal, this._oneWay, !possibleGlobal && !this._oneWay); this._readyToSync = true; this._fromObj = fromObj; this._fromPath = fromPath; this._toObj = obj; @@ -17462,16 +16761,14 @@ } } }; - function fireDeprecations(obj, toPath, fromPath, deprecateGlobal, deprecateOneWay, deprecateAlias) { + function fireDeprecations(deprecateGlobal, deprecateOneWay, deprecateAlias) { var deprecateGlobalMessage = '`Ember.Binding` is deprecated. Since you' + ' are binding to a global consider using a service instead.'; var deprecateOneWayMessage = '`Ember.Binding` is deprecated. Since you' + ' are using a `oneWay` binding consider using a `readOnly` computed' + ' property instead.'; var deprecateAliasMessage = '`Ember.Binding` is deprecated. Consider' + ' using an `alias` computed property instead.'; - - var objectInfo = 'The `' + toPath + '` property of `' + obj + '` is an `Ember.Binding` connected to `' + fromPath + '`, but '; } function mixinProperties(to, from) { for (var key in from) { if (from.hasOwnProperty(key)) { @@ -17656,61 +16953,90 @@ exports.Binding = Binding; }); enifed('ember-metal/cache', ['exports', 'ember-metal/empty_object'], function (exports, _emberMetalEmpty_object) { 'use strict'; - exports.default = Cache; + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - function Cache(limit, func) { - this.store = new _emberMetalEmpty_object.default(); - this.size = 0; - this.misses = 0; - this.hits = 0; - this.limit = limit; - this.func = func; - } + var Cache = (function () { + function Cache(limit, func, key, store) { + _classCallCheck(this, Cache); - var UNDEFINED = function () {}; + this.size = 0; + this.misses = 0; + this.hits = 0; + this.limit = limit; + this.func = func; + this.key = key; + this.store = store || new DefaultStore(); + } - Cache.prototype = { - set: function (key, value) { + Cache.prototype.set = function set(obj, value) { if (this.limit > this.size) { + var key = this.key === undefined ? obj : this.key(obj); this.size++; if (value === undefined) { - this.store[key] = UNDEFINED; + this.store.set(key, UNDEFINED); } else { - this.store[key] = value; + this.store.set(key, value); } } - return value; - }, + }; - get: function (key) { - var value = this.store[key]; - + Cache.prototype.get = function get(obj) { + var key = this.key === undefined ? obj : this.key(obj); + var value = this.store.get(key); if (value === undefined) { this.misses++; - value = this.set(key, this.func(key)); + value = this.set(key, this.func(obj)); } else if (value === UNDEFINED) { this.hits++; value = undefined; } else { this.hits++; // nothing to translate } return value; - }, + }; - purge: function () { - this.store = new _emberMetalEmpty_object.default(); + Cache.prototype.purge = function purge() { + this.store.clear(); this.size = 0; this.hits = 0; this.misses = 0; + }; + + return Cache; + })(); + + exports.default = Cache; + + function UNDEFINED() {} + + var DefaultStore = (function () { + function DefaultStore() { + _classCallCheck(this, DefaultStore); + + this.data = new _emberMetalEmpty_object.default(); } - }; + + DefaultStore.prototype.get = function get(key) { + return this.data[key]; + }; + + DefaultStore.prototype.set = function set(key, value) { + this.data[key] = value; + }; + + DefaultStore.prototype.clear = function clear() { + this.data = new _emberMetalEmpty_object.default(); + }; + + return DefaultStore; + })(); }); enifed('ember-metal/chains', ['exports', 'ember-metal/property_get', 'ember-metal/meta', 'ember-metal/watch_key', 'ember-metal/empty_object', 'ember-metal/watch_path'], function (exports, _emberMetalProperty_get, _emberMetalMeta, _emberMetalWatch_key, _emberMetalEmpty_object, _emberMetalWatch_path) { 'use strict'; exports.finishChains = finishChains; @@ -17921,11 +17247,11 @@ // copies a top level object only copy: function (obj) { var ret = new ChainNode(null, null, obj); var paths = this._paths; - var path; + var path = undefined; for (path in paths) { // this check will also catch non-number vals. if (paths[path] <= 0) { continue; @@ -17961,11 +17287,11 @@ this.unchain(key, tail); }, chain: function (key, path) { var chains = this._chains; - var node; + var node = undefined; if (chains === undefined) { chains = this._chains = new _emberMetalEmpty_object.default(); } else { node = chains[key]; } @@ -18014,11 +17340,11 @@ this._value = undefined; } // then notify chains... var chains = this._chains; - var node; + var node = undefined; if (chains) { for (var key in chains) { node = chains[key]; if (node !== undefined) { node.notify(revalidate, affected); @@ -18289,17 +17615,16 @@ @return {Ember.ComputedProperty} this @chainable @public */ ComputedPropertyPrototype.property = function () { - var args; + var args = []; - var addArg = function (property) { + function addArg(property) { args.push(property); - }; + } - args = []; for (var i = 0; i < arguments.length; i++) { _emberMetalExpand_properties.default(arguments[i], addArg); } this._dependentKeys = args; @@ -18573,11 +17898,11 @@ @return {Ember.ComputedProperty} property descriptor instance @public */ function computed(func) { - var args; + var args = undefined; if (arguments.length > 1) { args = [].slice.call(arguments); func = args.pop(); } @@ -18768,11 +18093,12 @@ // function addDependentKeys(desc, obj, keyName, meta) { // the descriptor has a list of dependent keys, so // add all of its dependent keys. - var idx, depKey; + var idx = undefined, + depKey = undefined; var depKeys = desc._dependentKeys; if (!depKeys) { return; } @@ -18787,17 +18113,16 @@ function removeDependentKeys(desc, obj, keyName, meta) { // the descriptor has a list of dependent keys, so // remove all of its dependent keys. var depKeys = desc._dependentKeys; - var idx, depKey; if (!depKeys) { return; } - for (idx = 0; idx < depKeys.length; idx++) { - depKey = depKeys[idx]; + for (var idx = 0; idx < depKeys.length; idx++) { + var depKey = depKeys[idx]; // Decrement the number of times depKey depends on keyName. meta.writeDeps(depKey, keyName, (meta.peekDeps(depKey, keyName) || 0) - 1); // Unwatch the depKey _emberMetalWatching.unwatch(obj, depKey, meta); } @@ -18852,11 +18177,11 @@ // appears worthwhile in some usecases. Please note, these deletes do increase // the cost of creation dramatically over a plain Object.create. And as this // only makes sense for long-lived dictionaries that aren't instantiated often. function makeDictionary(parent) { - var dict; + var dict = undefined; if (parent === null) { dict = new _emberMetalEmpty_object.default(); } else { dict = Object.create(parent); } @@ -18931,10 +18256,22 @@ exports.getOnerror = getOnerror; exports.setOnerror = setOnerror; exports.dispatchError = dispatchError; exports.setDispatchOverride = setDispatchOverride; + // To maintain stacktrace consistency across browsers + var getStack = function (error) { + var stack = error.stack; + var message = error.message; + + if (stack.indexOf(message) === -1) { + stack = message + '\n' + stack; + } + + return stack; + }; + var onerror = undefined; // Ember.onerror getter function getOnerror() { return onerror; @@ -18968,11 +18305,11 @@ throw error; } if (onerror) { onerror(error); } else { - _emberConsole.default.error(error.stack); + _emberConsole.default.error(getStack(error)); } } }); enifed('ember-metal/events', ['exports', 'ember-metal/debug', 'ember-metal/utils', 'ember-metal/meta', 'ember-metal/meta_listeners'], function (exports, _emberMetalDebug, _emberMetalUtils, _emberMetalMeta, _emberMetalMeta_listeners) { 'no use strict'; @@ -19274,17 +18611,17 @@ Define a property as a function that should be executed when a specified event or events are triggered. ``` javascript - var Job = Ember.Object.extend({ + let Job = Ember.Object.extend({ logCompleted: Ember.on('completed', function() { console.log('Job completed!'); }) }); - var job = Job.create(); + let job = Job.create(); Ember.sendEvent(job, 'completed'); // Logs 'Job completed!' ``` @method on @@ -19472,11 +18809,11 @@ ret[propertyNames[i]] = _emberMetalProperty_get.get(obj, propertyNames[i]); } return ret; } }); -enifed('ember-metal/index', ['exports', 'require', 'ember-environment', 'ember/version', 'ember-metal/core', 'ember-metal/debug', 'ember-metal/features', 'ember-metal/assign', 'ember-metal/merge', 'ember-metal/instrumentation', 'ember-metal/utils', 'ember-metal/meta', 'ember-metal/error', 'ember-metal/cache', 'ember-console', 'ember-metal/property_get', 'ember-metal/events', 'ember-metal/observer_set', 'ember-metal/property_events', 'ember-metal/properties', 'ember-metal/property_set', 'ember-metal/map', 'ember-metal/get_properties', 'ember-metal/set_properties', 'ember-metal/watch_key', 'ember-metal/chains', 'ember-metal/watch_path', 'ember-metal/watching', 'ember-metal/expand_properties', 'ember-metal/computed', 'ember-metal/alias', 'ember-metal/observer', 'ember-metal/mixin', 'ember-metal/binding', 'ember-metal/path_cache', 'ember-metal/testing', 'ember-metal/error_handler', 'ember-metal/run_loop', 'ember-metal/libraries', 'ember-metal/is_none', 'ember-metal/is_empty', 'ember-metal/is_blank', 'ember-metal/is_present', 'backburner'], function (exports, _require, _emberEnvironment, _emberVersion, _emberMetalCore, _emberMetalDebug, _emberMetalFeatures, _emberMetalAssign, _emberMetalMerge, _emberMetalInstrumentation, _emberMetalUtils, _emberMetalMeta, _emberMetalError, _emberMetalCache, _emberConsole, _emberMetalProperty_get, _emberMetalEvents, _emberMetalObserver_set, _emberMetalProperty_events, _emberMetalProperties, _emberMetalProperty_set, _emberMetalMap, _emberMetalGet_properties, _emberMetalSet_properties, _emberMetalWatch_key, _emberMetalChains, _emberMetalWatch_path, _emberMetalWatching, _emberMetalExpand_properties, _emberMetalComputed, _emberMetalAlias, _emberMetalObserver, _emberMetalMixin, _emberMetalBinding, _emberMetalPath_cache, _emberMetalTesting, _emberMetalError_handler, _emberMetalRun_loop, _emberMetalLibraries, _emberMetalIs_none, _emberMetalIs_empty, _emberMetalIs_blank, _emberMetalIs_present, _backburner) { +enifed('ember-metal/index', ['exports', 'require', 'ember-environment', 'ember/version', 'ember-metal/core', 'ember-metal/debug', 'ember-metal/features', 'ember-metal/assign', 'ember-metal/merge', 'ember-metal/instrumentation', 'ember-metal/utils', 'ember-metal/meta', 'ember-metal/error', 'ember-metal/cache', 'ember-console', 'ember-metal/property_get', 'ember-metal/events', 'ember-metal/observer_set', 'ember-metal/property_events', 'ember-metal/properties', 'ember-metal/property_set', 'ember-metal/weak_map', 'ember-metal/map', 'ember-metal/get_properties', 'ember-metal/set_properties', 'ember-metal/watch_key', 'ember-metal/chains', 'ember-metal/watch_path', 'ember-metal/watching', 'ember-metal/expand_properties', 'ember-metal/computed', 'ember-metal/alias', 'ember-metal/observer', 'ember-metal/mixin', 'ember-metal/binding', 'ember-metal/path_cache', 'ember-metal/testing', 'ember-metal/error_handler', 'ember-metal/run_loop', 'ember-metal/libraries', 'ember-metal/is_none', 'ember-metal/is_empty', 'ember-metal/is_blank', 'ember-metal/is_present', 'backburner'], function (exports, _require, _emberEnvironment, _emberVersion, _emberMetalCore, _emberMetalDebug, _emberMetalFeatures, _emberMetalAssign, _emberMetalMerge, _emberMetalInstrumentation, _emberMetalUtils, _emberMetalMeta, _emberMetalError, _emberMetalCache, _emberConsole, _emberMetalProperty_get, _emberMetalEvents, _emberMetalObserver_set, _emberMetalProperty_events, _emberMetalProperties, _emberMetalProperty_set, _emberMetalWeak_map, _emberMetalMap, _emberMetalGet_properties, _emberMetalSet_properties, _emberMetalWatch_key, _emberMetalChains, _emberMetalWatch_path, _emberMetalWatching, _emberMetalExpand_properties, _emberMetalComputed, _emberMetalAlias, _emberMetalObserver, _emberMetalMixin, _emberMetalBinding, _emberMetalPath_cache, _emberMetalTesting, _emberMetalError_handler, _emberMetalRun_loop, _emberMetalLibraries, _emberMetalIs_none, _emberMetalIs_empty, _emberMetalIs_blank, _emberMetalIs_present, _backburner) { /** @module ember @submodule ember-metal */ @@ -19551,10 +18888,13 @@ _emberMetalCore.default.defineProperty = _emberMetalProperties.defineProperty; _emberMetalCore.default.set = _emberMetalProperty_set.set; _emberMetalCore.default.trySet = _emberMetalProperty_set.trySet; + if (false) { + _emberMetalCore.default.WeakMap = _emberMetalWeak_map.default; + } _emberMetalCore.default.OrderedSet = _emberMetalMap.OrderedSet; _emberMetalCore.default.Map = _emberMetalMap.Map; _emberMetalCore.default.MapWithDefault = _emberMetalMap.MapWithDefault; _emberMetalCore.default.getProperties = _emberMetalGet_properties.default; @@ -19586,11 +18926,10 @@ _emberMetalCore.default.observersFor = _emberMetalObserver.observersFor; _emberMetalCore.default.removeObserver = _emberMetalObserver.removeObserver; _emberMetalCore.default._suspendObserver = _emberMetalObserver._suspendObserver; _emberMetalCore.default._suspendObservers = _emberMetalObserver._suspendObservers; - _emberMetalCore.default.IS_BINDING = _emberMetalMixin.IS_BINDING; _emberMetalCore.default.required = _emberMetalMixin.required; _emberMetalCore.default.aliasMethod = _emberMetalMixin.aliasMethod; _emberMetalCore.default.observer = _emberMetalMixin.observer; _emberMetalCore.default.immediateObserver = _emberMetalMixin._immediateObserver; _emberMetalCore.default.mixin = _emberMetalMixin.mixin; @@ -19615,10 +18954,11 @@ BackburnerAlias.prototype = _backburner.default.prototype; return new BackburnerAlias(arguments); }; + _emberMetalCore.default._Backburner = _backburner.default; /** The semantic version @property VERSION @@ -19648,41 +18988,41 @@ Object.defineProperty(_emberMetalCore.default, 'LOG_STACKTRACE_ON_DEPRECATION', { get: function () { return _emberEnvironment.ENV.LOG_STACKTRACE_ON_DEPRECATION; }, set: function (value) { - return _emberEnvironment.ENV.LOG_STACKTRACE_ON_DEPRECATION = !!value; + _emberEnvironment.ENV.LOG_STACKTRACE_ON_DEPRECATION = !!value; }, enumerable: false }); Object.defineProperty(_emberMetalCore.default, 'LOG_VERSION', { get: function () { return _emberEnvironment.ENV.LOG_VERSION; }, set: function (value) { - return _emberEnvironment.ENV.LOG_VERSION = !!value; + _emberEnvironment.ENV.LOG_VERSION = !!value; }, enumerable: false }); Object.defineProperty(_emberMetalCore.default, 'MODEL_FACTORY_INJECTIONS', { get: function () { return _emberEnvironment.ENV.MODEL_FACTORY_INJECTIONS; }, set: function (value) { - return _emberEnvironment.ENV.MODEL_FACTORY_INJECTIONS = !!value; + _emberEnvironment.ENV.MODEL_FACTORY_INJECTIONS = !!value; }, enumerable: false }); Object.defineProperty(_emberMetalCore.default, 'LOG_BINDINGS', { get: function () { return _emberEnvironment.ENV.LOG_BINDINGS; }, set: function (value) { - return _emberEnvironment.ENV.LOG_BINDINGS = !!value; + _emberEnvironment.ENV.LOG_BINDINGS = !!value; }, enumerable: false }); Object.defineProperty(_emberMetalCore.default, 'ENV', { @@ -19700,11 +19040,11 @@ Object.defineProperty(_emberMetalCore.default, 'lookup', { get: function () { return _emberEnvironment.context.lookup; }, set: function (value) { - return _emberEnvironment.context.lookup = value; + _emberEnvironment.context.lookup = value; }, enumerable: false }); Object.defineProperty(_emberMetalCore.default, 'testing', { @@ -19787,10 +19127,12 @@ }); // reexports enifed('ember-metal/injected_property', ['exports', 'ember-metal/debug', 'ember-metal/computed', 'ember-metal/alias', 'ember-metal/properties', 'container/owner'], function (exports, _emberMetalDebug, _emberMetalComputed, _emberMetalAlias, _emberMetalProperties, _containerOwner) { 'use strict'; + exports.default = InjectedProperty; + /** Read-only property that returns the result of a container lookup. @class InjectedProperty @namespace Ember @@ -19798,10 +19140,11 @@ @param {String} type The container type the property will lookup @param {String} name (optional) The name the property will lookup, defaults to the property's name @private */ + function InjectedProperty(type, name) { this.type = type; this.name = name; this._super$Constructor(injectedPropertyGet); @@ -19823,14 +19166,11 @@ InjectedPropertyPrototype._super$Constructor = _emberMetalComputed.ComputedProperty; InjectedPropertyPrototype.get = ComputedPropertyPrototype.get; InjectedPropertyPrototype.readOnly = ComputedPropertyPrototype.readOnly; - InjectedPropertyPrototype.teardown = ComputedPropertyPrototype.teardown; - - exports.default = InjectedProperty; }); enifed('ember-metal/instrumentation', ['exports', 'ember-environment', 'ember-metal/features'], function (exports, _emberEnvironment, _emberMetalFeatures) { 'use strict'; exports.instrument = instrument; @@ -19846,15 +19186,15 @@ Subscribe to a listener by using `Ember.subscribe`: ```javascript Ember.subscribe("render", { - before: function(name, timestamp, payload) { + before(name, timestamp, payload) { }, - after: function(name, timestamp, payload) { + after(name, timestamp, payload) { } }); ``` @@ -19888,24 +19228,24 @@ */ var subscribers = []; exports.subscribers = subscribers; var cache = {}; - var populateListeners = function (name) { + function populateListeners(name) { var listeners = []; - var subscriber; + var subscriber = undefined; for (var i = 0; i < subscribers.length; i++) { subscriber = subscribers[i]; if (subscriber.regex.test(name)) { listeners.push(subscriber.object); } } cache[name] = listeners; return listeners; - }; + } var time = (function () { var perf = 'undefined' !== typeof window ? window.performance || {} : {}; var fn = perf.now || perf.mozNow || perf.webkitNow || perf.msNow || perf.oNow; // fn.bind will be available in all the browsers that support the advanced window.performance... ;-) @@ -19946,11 +19286,11 @@ } else { return callback.call(binding); } } - var flaggedInstrument; + var flaggedInstrument = undefined; if (false) { exports.flaggedInstrument = flaggedInstrument = instrument; } else { exports.flaggedInstrument = flaggedInstrument = function (name, payload, callback) { return callback(); @@ -19985,26 +19325,28 @@ } var payload = _payload(); var STRUCTURED_PROFILE = _emberEnvironment.ENV.STRUCTURED_PROFILE; - var timeName; + var timeName = undefined; if (STRUCTURED_PROFILE) { timeName = name + ': ' + payload.object; console.time(timeName); } var beforeValues = new Array(listeners.length); - var i, listener; + var i = undefined, + listener = undefined; var timestamp = time(); for (i = 0; i < listeners.length; i++) { listener = listeners[i]; beforeValues[i] = listener.before(name, timestamp, payload); } return function _instrumentEnd() { - var i, listener; + var i = undefined, + listener = undefined; var timestamp = time(); for (i = 0; i < listeners.length; i++) { listener = listeners[i]; if (typeof listener.after === 'function') { listener.after(name, timestamp, payload, beforeValues[i]); @@ -20030,11 +19372,11 @@ @private */ function subscribe(pattern, object) { var paths = pattern.split('.'); - var path; + var path = undefined; var regex = []; for (var i = 0; i < paths.length; i++) { path = paths[i]; if (path === '*') { @@ -20068,11 +19410,11 @@ @param {Object} [subscriber] @private */ function unsubscribe(subscriber) { - var index; + var index = undefined; for (var i = 0; i < subscribers.length; i++) { if (subscribers[i] === subscriber) { index = i; } @@ -20130,10 +19472,12 @@ } }); enifed('ember-metal/is_empty', ['exports', 'ember-metal/property_get', 'ember-metal/is_none'], function (exports, _emberMetalProperty_get, _emberMetalIs_none) { 'use strict'; + exports.default = isEmpty; + /** Verifies that a value is `null` or an empty string, empty array, or empty function. Constrains the rules on `Ember.isNone` by returning true for empty @@ -20156,10 +19500,11 @@ @for Ember @param {Object} obj Value to test @return {Boolean} @public */ + function isEmpty(obj) { var none = _emberMetalIs_none.default(obj); if (none) { return none; } @@ -20180,20 +19525,18 @@ if (typeof obj.length === 'number' && objectType !== 'function') { return !obj.length; } if (objectType === 'object') { - var length = _emberMetalProperty_get.get(obj, 'length'); - if (typeof length === 'number') { - return !length; + var _length = _emberMetalProperty_get.get(obj, 'length'); + if (typeof _length === 'number') { + return !_length; } } return false; } - - exports.default = isEmpty; }); enifed("ember-metal/is_none", ["exports"], function (exports) { /** Returns true if the passed value is null or undefined. This avoids errors from JSLint complaining about use of ==, which can be technically @@ -20311,11 +19654,11 @@ this.register(name, version, true); }, deRegister: function (name) { var lib = this._getLibraryByName(name); - var index; + var index = undefined; if (lib) { index = this._registry.indexOf(lib); this._registry.splice(index, 1); } @@ -20514,18 +19857,17 @@ if (this.size === 0) { return; } var list = this.list; - var i; if (arguments.length === 2) { - for (i = 0; i < list.length; i++) { + for (var i = 0; i < list.length; i++) { fn.call(arguments[1], list[i]); } } else { - for (i = 0; i < list.length; i++) { + for (var i = 0; i < list.length; i++) { fn(list[i]); } } }, @@ -20711,20 +20053,21 @@ if (this.size === 0) { return; } var map = this; - var cb, thisArg; + var cb = undefined, + thisArg = undefined; if (arguments.length === 2) { thisArg = arguments[1]; cb = function (key) { - callback.call(thisArg, map.get(key), key, map); + return callback.call(thisArg, map.get(key), key, map); }; } else { cb = function (key) { - callback(map.get(key), key, map); + return callback(map.get(key), key, map); }; } this._keys.forEach(cb); }, @@ -20825,14 +20168,14 @@ enifed('ember-metal/merge', ['exports'], function (exports) { /** Merge the contents of two objects together into the first object. ```javascript - Ember.merge({first: 'Tom'}, {last: 'Dale'}); // {first: 'Tom', last: 'Dale'} - var a = {first: 'Yehuda'}; - var b = {last: 'Katz'}; - Ember.merge(a, b); // a == {first: 'Yehuda', last: 'Katz'}, b == {last: 'Katz'} + Ember.merge({ first: 'Tom' }, { last: 'Dale' }); // { first: 'Tom', last: 'Dale' } + var a = { first: 'Yehuda' }; + var b = { last: 'Katz' }; + Ember.merge(a, b); // a == { first: 'Yehuda', last: 'Katz' }, b == { last: 'Katz' } ``` @method merge @for Ember @param {Object} original The object to merge into @@ -20848,11 +20191,11 @@ if (!updates || typeof updates !== 'object') { return original; } var props = Object.keys(updates); - var prop; + var prop = undefined; for (var i = 0; i < props.length; i++) { prop = props[i]; original[prop] = updates[prop]; } @@ -21455,10 +20798,11 @@ /** @module ember @submodule ember-metal */ + exports.detectBinding = detectBinding; exports.mixin = mixin; exports.default = Mixin; exports.hasUnprocessedMixins = hasUnprocessedMixins; exports.clearUnprocessedMixins = clearUnprocessedMixins; exports.required = required; @@ -21468,21 +20812,20 @@ exports._beforeObserver = _beforeObserver; function ROOT() {} ROOT.__hasSuper = false; - var REQUIRED; var a_slice = [].slice; function isMethod(obj) { return 'function' === typeof obj && obj.isMethod !== false && obj !== Boolean && obj !== Object && obj !== Number && obj !== Array && obj !== Date && obj !== String; } var CONTINUE = {}; function mixinProperties(mixinsMeta, mixin) { - var guid; + var guid = undefined; if (mixin instanceof Mixin) { guid = _emberMetalUtils.guidFor(mixin); if (mixinsMeta.peekMixins(guid)) { return CONTINUE; @@ -21493,11 +20836,11 @@ return mixin; // apply anonymous mixin properties } } function concatenatedMixinProperties(concatProp, props, values, base) { - var concats; + var concats = undefined; // reset before adding each new mixin to pickup concats from previous concats = values[concatProp] || base[concatProp]; if (props[concatProp]) { concats = concats ? concats.concat(props[concatProp]) : props[concatProp]; @@ -21505,11 +20848,11 @@ return concats; } function giveDescriptorSuper(meta, key, property, values, descs, base) { - var superProperty; + var superProperty = undefined; // Computed properties override methods, and do not call super to them if (values[key] === undefined) { // Find the original descriptor in a parent mixin superProperty = descs[key]; @@ -21543,11 +20886,11 @@ return property; } function giveMethodSuper(obj, key, method, values, descs) { - var superMethod; + var superMethod = undefined; // Methods overwrite computed properties, and do not call super to them. if (descs[key] === undefined) { // Find the original method in a parent mixin superMethod = values[key]; @@ -21642,11 +20985,16 @@ values[key] = value; } } function mergeMixins(mixins, m, descs, values, base, keys) { - var currentMixin, props, key, concats, mergings, meta; + var currentMixin = undefined, + props = undefined, + key = undefined, + concats = undefined, + mergings = undefined, + meta = undefined; function removeKeys(keyName) { delete descs[keyName]; delete values[keyName]; } @@ -21686,18 +21034,20 @@ } } } } - var IS_BINDING = /^.+Binding$/; + function detectBinding(key) { + var length = key.length; - function detectBinding(obj, key, value, m) { - if (IS_BINDING.test(key)) { - m.writeBindings(key, value); - } + return length > 7 && key.charCodeAt(length - 7) === 66 && key.indexOf('inding', length - 6) !== -1; } + // warm both paths of above function + detectBinding('notbound'); + detectBinding('fooBinding'); + function connectBindings(obj, m) { // TODO Mixin.apply(instance) should disconnect binding if exists m.forEachBindings(function (key, binding) { if (binding) { var to = key.slice(0, -7); // strip Binding off end @@ -21721,12 +21071,12 @@ return obj; } function followAlias(obj, desc, m, descs, values) { var altKey = desc.methodName; - var value; - var possibleDesc; + var value = undefined; + var possibleDesc = undefined; if (descs[altKey] || values[altKey]) { value = values[altKey]; desc = descs[altKey]; } else if ((possibleDesc = obj[altKey]) && possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor) { desc = possibleDesc; @@ -21768,11 +21118,13 @@ function applyMixin(obj, mixins, partial) { var descs = {}; var values = {}; var m = _emberMetalMeta.meta(obj); var keys = []; - var key, value, desc; + var key = undefined, + value = undefined, + desc = undefined; obj._super = ROOT; // Go through all mixins and hashes passed in, and: // @@ -21805,11 +21157,15 @@ if (desc === undefined && value === undefined) { continue; } replaceObserversAndListeners(obj, key, value); - detectBinding(obj, key, value, m); + + if (detectBinding(key)) { + m.writeBindings(key, value); + } + _emberMetalProperties.defineProperty(obj, key, desc, value, m); } if (!partial) { // don't apply to prototype @@ -21966,22 +21322,22 @@ @method reopen @param arguments* @private */ MixinPrototype.reopen = function () { - var currentMixin; + var currentMixin = undefined; if (this.properties) { currentMixin = new Mixin(undefined, this.properties); this.properties = undefined; this.mixins = [currentMixin]; } else if (!this.mixins) { this.mixins = []; } var mixins = this.mixins; - var idx; + var idx = undefined; for (idx = 0; idx < arguments.length; idx++) { currentMixin = arguments[idx]; if (currentMixin instanceof Mixin) { @@ -22107,11 +21463,11 @@ }); return ret; }; - exports.REQUIRED = REQUIRED = new _emberMetalProperties.Descriptor(); + var REQUIRED = new _emberMetalProperties.Descriptor(); REQUIRED.toString = function () { return '(Required Property)'; }; /** @@ -22142,11 +21498,11 @@ return 'Tomhuda Katzdale'; }, moniker: Ember.aliasMethod('name') }); - var goodGuy = App.Person.create(); + let goodGuy = App.Person.create(); goodGuy.name(); // 'Tomhuda Katzdale' goodGuy.moniker(); // 'Tomhuda Katzdale' ``` @@ -22190,11 +21546,11 @@ for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { args[_key4] = arguments[_key4]; } var func = args.slice(-1)[0]; - var paths; + var paths = undefined; var addWatchedProperty = function (path) { paths.push(path); }; var _paths = args.slice(0, -1); @@ -22271,11 +21627,11 @@ friends: [{ name: 'Tom' }, { name: 'Stefan' }, { name: 'Kris' }], valueDidChange: Ember.observer('content.value', function(obj, keyName) { // only run if updating a value already in the DOM if (this.get('state') === 'inDOM') { - var color = obj.get(keyName) > this.changingFrom ? 'green' : 'red'; + let color = obj.get(keyName) > this.changingFrom ? 'green' : 'red'; // logic } }), friendsDidChange: Ember.observer('friends.@each.name', function(obj, keyName) { @@ -22301,11 +21657,11 @@ for (var _len5 = arguments.length, args = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) { args[_key5] = arguments[_key5]; } var func = args.slice(-1)[0]; - var paths; + var paths = undefined; var addWatchedProperty = function (path) { paths.push(path); }; @@ -22330,11 +21686,10 @@ func.__ember_observesBefore__ = paths; return func; } - exports.IS_BINDING = IS_BINDING; exports.Mixin = Mixin; exports.required = required; exports.REQUIRED = REQUIRED; }); // use conditional to avoid stringifying every time @@ -22453,10 +21808,12 @@ } }); enifed('ember-metal/observer_set', ['exports', 'ember-metal/utils', 'ember-metal/events'], function (exports, _emberMetalUtils, _emberMetalEvents) { 'use strict'; + exports.default = ObserverSet; + /* this.observerSet = { [senderGuid]: { // variable name: `keySet` [keyName]: listIndex } @@ -22471,22 +21828,21 @@ ] }, ... ] */ - exports.default = ObserverSet; function ObserverSet() { this.clear(); } ObserverSet.prototype.add = function (sender, keyName, eventName) { var observerSet = this.observerSet; var observers = this.observers; var senderGuid = _emberMetalUtils.guidFor(sender); var keySet = observerSet[senderGuid]; - var index; + var index = undefined; if (!keySet) { observerSet[senderGuid] = keySet = {}; } index = keySet[keyName]; @@ -22502,11 +21858,13 @@ return observers[index].listeners; }; ObserverSet.prototype.flush = function () { var observers = this.observers; - var i, observer, sender; + var i = undefined, + observer = undefined, + sender = undefined; this.clear(); for (i = 0; i < observers.length; ++i) { observer = observers[i]; sender = observer.sender; if (sender.isDestroying || sender.isDestroyed) { @@ -22536,19 +21894,16 @@ var HAS_THIS = 'this.'; var isGlobalCache = new _emberMetalCache.default(1000, function (key) { return IS_GLOBAL.test(key); }); - var isGlobalPathCache = new _emberMetalCache.default(1000, function (key) { return IS_GLOBAL_PATH.test(key); }); - var hasThisCache = new _emberMetalCache.default(1000, function (key) { return key.lastIndexOf(HAS_THIS, 0) === 0; }); - var firstDotIndexCache = new _emberMetalCache.default(1000, function (key) { return key.indexOf('.'); }); var firstKeyCache = new _emberMetalCache.default(1000, function (path) { @@ -22732,11 +22087,14 @@ @param {*} [data] something other than a descriptor, that will become the explicit value of this property. */ function defineProperty(obj, keyName, desc, data, meta) { - var possibleDesc, existingDesc, watching, value; + var possibleDesc = undefined, + existingDesc = undefined, + watching = undefined, + value = undefined; if (!meta) { meta = _emberMetalMeta.meta(obj); } var watchEntry = meta.peekWatching(keyName); @@ -22921,28 +22279,29 @@ } _emberMetalTags.markObjectAsDirty(m); } - var WILL_SEEN, DID_SEEN; + var WILL_SEEN = undefined, + DID_SEEN = undefined; // called whenever a property is about to change to clear the cache of any dependent keys (and notify those properties of changes, etc...) function dependentKeysWillChange(obj, depKey, meta) { if (obj.isDestroying) { return; } if (meta && meta.hasDeps(depKey)) { var seen = WILL_SEEN; - var top = !seen; + var _top = !seen; - if (top) { + if (_top) { seen = WILL_SEEN = {}; } iterDeps(propertyWillChange, obj, depKey, seen, meta); - if (top) { + if (_top) { WILL_SEEN = null; } } } @@ -22952,26 +22311,27 @@ return; } if (meta && meta.hasDeps(depKey)) { var seen = DID_SEEN; - var top = !seen; + var _top2 = !seen; - if (top) { + if (_top2) { seen = DID_SEEN = {}; } iterDeps(propertyDidChange, obj, depKey, seen, meta); - if (top) { + if (_top2) { DID_SEEN = null; } } } function iterDeps(method, obj, depKey, seen, meta) { - var possibleDesc, desc; + var possibleDesc = undefined, + desc = undefined; var guid = _emberMetalUtils.guidFor(obj); var current = seen[guid]; if (!current) { current = seen[guid] = {}; @@ -23070,11 +22430,12 @@ if (obj.isDestroying) { return; } var eventName = keyName + ':before'; - var listeners, added; + var listeners = undefined, + added = undefined; if (deferred) { listeners = beforeObserverSet.add(obj, keyName, eventName); added = _emberMetalEvents.accumulateListeners(obj, eventName, listeners); _emberMetalEvents.sendEvent(obj, eventName, [obj, keyName], added); } else { @@ -23086,11 +22447,11 @@ if (obj.isDestroying) { return; } var eventName = keyName + ':change'; - var listeners; + var listeners = undefined; if (deferred) { listeners = observerSet.add(obj, keyName, eventName); _emberMetalEvents.accumulateListeners(obj, eventName, listeners); } else { _emberMetalEvents.sendEvent(obj, eventName, [obj, keyName]); @@ -23161,11 +22522,11 @@ return obj; } var value = obj[keyName]; var desc = value !== null && typeof value === 'object' && value.isDescriptor ? value : undefined; - var ret; + var ret = undefined; if (desc === undefined && _emberMetalPath_cache.isPath(keyName)) { return _getPath(obj, keyName); } @@ -23318,14 +22679,12 @@ } }; } function setPath(root, path, value, tolerant) { - var keyName; - // get the last part of the path - keyName = path.slice(path.lastIndexOf('.') + 1); + var keyName = path.slice(path.lastIndexOf('.') + 1); // get the first part of the part path = path === keyName ? keyName : path.slice(0, path.length - (keyName.length + 1)); // unless the path is this, look up the first part to @@ -23379,11 +22738,12 @@ var ret = []; // https://code.google.com/p/chromium/issues/detail?id=56588 var size = 60000; var start = idx; var ends = amt; - var count, chunk; + var count = undefined, + chunk = undefined; while (args.length) { count = ends > size ? size : ends; if (count <= 0) { count = 0; @@ -23891,47 +23251,47 @@ Cancels a scheduled item. Must be a value returned by `run.later()`, `run.once()`, `run.scheduleOnce()`, `run.next()`, `run.debounce()`, or `run.throttle()`. ```javascript - var runNext = run.next(myContext, function() { + let runNext = run.next(myContext, function() { // will not be executed }); run.cancel(runNext); - var runLater = run.later(myContext, function() { + let runLater = run.later(myContext, function() { // will not be executed }, 500); run.cancel(runLater); - var runScheduleOnce = run.scheduleOnce('afterRender', myContext, function() { + let runScheduleOnce = run.scheduleOnce('afterRender', myContext, function() { // will not be executed }); run.cancel(runScheduleOnce); - var runOnce = run.once(myContext, function() { + let runOnce = run.once(myContext, function() { // will not be executed }); run.cancel(runOnce); - var throttle = run.throttle(myContext, function() { + let throttle = run.throttle(myContext, function() { // will not be executed }, 1, false); run.cancel(throttle); - var debounce = run.debounce(myContext, function() { + let debounce = run.debounce(myContext, function() { // will not be executed }, 1); run.cancel(debounce); - var debounceImmediate = run.debounce(myContext, function() { + let debounceImmediate = run.debounce(myContext, function() { // will be executed since we passed in true (immediate) }, 100, true); // the 100ms delay until this method can be called again will be cancelled run.cancel(debounceImmediate); @@ -23960,11 +23320,11 @@ ```javascript function whoRan() { console.log(this.name + ' ran.'); } - var myContext = { name: 'debounce' }; + let myContext = { name: 'debounce' }; run.debounce(myContext, whoRan, 150); // less than 150ms passes run.debounce(myContext, whoRan, 150); @@ -23983,11 +23343,11 @@ ```javascript function whoRan() { console.log(this.name + ' ran.'); } - var myContext = { name: 'debounce' }; + let myContext = { name: 'debounce' }; run.debounce(myContext, whoRan, 150, true); // console logs 'debounce ran.' one time immediately. // 100ms passes @@ -24026,11 +23386,11 @@ ```javascript function whoRan() { console.log(this.name + ' ran.'); } - var myContext = { name: 'throttle' }; + let myContext = { name: 'throttle' }; run.throttle(myContext, whoRan, 150); // whoRan is invoked with context myContext // console logs 'throttle ran.' @@ -24087,11 +23447,11 @@ Set a list of properties on an object. These properties are set inside a single `beginPropertyChanges` and `endPropertyChanges` batch, so observers will be buffered. ```javascript - var anObject = Ember.Object.create(); + let anObject = Ember.Object.create(); anObject.setProperties({ firstName: 'Stanley', lastName: 'Stuart', age: 21 @@ -24109,11 +23469,11 @@ if (!properties || typeof properties !== 'object') { return properties; } _emberMetalProperty_events.changeProperties(function () { var props = Object.keys(properties); - var propertyName; + var propertyName = undefined; for (var i = 0; i < props.length; i++) { propertyName = props[i]; _emberMetalProperty_set.set(obj, propertyName, properties[propertyName]); @@ -24429,11 +23789,11 @@ if (obj === null) { return '(null)'; } - var ret; + var ret = undefined; var type = typeof obj; // Don't allow prototype changes to String etc. to change the guidFor switch (type) { case 'number': @@ -24556,11 +23916,11 @@ /** Checks to see if the `methodName` exists on the `obj`. ```javascript - var foo = { bar: function() { return 'bar'; }, baz: null }; + let foo = { bar: function() { return 'bar'; }, baz: null }; Ember.canInvoke(foo, 'bar'); // true Ember.canInvoke(foo, 'baz'); // false Ember.canInvoke(foo, 'bat'); // false ``` @@ -24579,11 +23939,11 @@ /** Checks to see if the `methodName` exists on the `obj`, and if it does, invokes it with the arguments passed. ```javascript - var d = new Date('03/15/2013'); + let d = new Date('03/15/2013'); Ember.tryInvoke(d, 'getTime'); // 1363320000000 Ember.tryInvoke(d, 'setFullYear', [2014]); // 1394856000000 Ember.tryInvoke(d, 'noSuchMethod', [2014]); // undefined ``` @@ -24619,11 +23979,11 @@ Ember.makeArray(null); // [] Ember.makeArray(undefined); // [] Ember.makeArray('lindsay'); // ['lindsay'] Ember.makeArray([1, 2, 42]); // [1, 2, 42] - var controller = Ember.ArrayProxy.create({ content: [] }); + let controller = Ember.ArrayProxy.create({ content: [] }); Ember.makeArray(controller) === controller; // true ``` @method makeArray @@ -24674,11 +24034,11 @@ if (typeof obj.toString === 'function' && obj.toString !== objectToString) { return obj.toString(); } // Object.prototype.toString === {}.toString - var v; + var v = undefined; var ret = []; for (var key in obj) { if (obj.hasOwnProperty(key)) { v = obj[key]; if (v === 'toString') { @@ -24998,11 +24358,14 @@ @private */ function destroy(obj) { var meta = _emberMetalMeta.peekMeta(obj); - var node, nodes, key, nodeObject; + var node = undefined, + nodes = undefined, + key = undefined, + nodeObject = undefined; if (meta) { _emberMetalMeta.deleteMeta(obj); // remove chainWatchers to remove circular references that would prevent GC node = meta.readableChains(); @@ -25030,42 +24393,69 @@ } } } } }); -enifed('ember-metal/weak_map', ['exports', 'ember-metal/debug', 'ember-metal/utils', 'ember-metal/meta'], function (exports, _emberMetalDebug, _emberMetalUtils, _emberMetalMeta) { +enifed('ember-metal/weak_map', ['exports', 'ember-metal/utils', 'ember-metal/meta'], function (exports, _emberMetalUtils, _emberMetalMeta) { 'use strict'; exports.default = WeakMap; var id = 0; function UNDEFINED() {} + // Returns whether Type(value) is Object according to the terminology in the spec + function isObject(value) { + return typeof value === 'object' && value !== null || typeof value === 'function'; + } + /* - * @private * @class Ember.WeakMap + * @public + * @category ember-metal-weakmap * * A partial polyfill for [WeakMap](http://www.ecma-international.org/ecma-262/6.0/#sec-weakmap-objects). * * There is a small but important caveat. This implementation assumes that the * weak map will live longer (in the sense of garbage collection) than all of its * keys, otherwise it is possible to leak the values stored in the weak map. In * practice, most use cases satisfy this limitation which is why it is included * in ember-metal. */ - function WeakMap() { + function WeakMap(iterable) { + if (!(this instanceof WeakMap)) { + throw new TypeError('Constructor WeakMap requires \'new\''); + } this._id = _emberMetalUtils.GUID_KEY + id++; + + if (iterable === null || iterable === undefined) { + return; + } else if (Array.isArray(iterable)) { + for (var i = 0; i < iterable.length; i++) { + var _iterable$i = iterable[i]; + var key = _iterable$i[0]; + var value = _iterable$i[1]; + + this.set(key, value); + } + } else { + throw new TypeError('The weak map constructor polyfill only supports an array argument'); + } } /* * @method get * @param key {Object | Function} * @return {Any} stored value */ WeakMap.prototype.get = function (obj) { + if (!isObject(obj)) { + return undefined; + } + var meta = _emberMetalMeta.peekMeta(obj); if (meta) { var map = meta.readableWeak(); if (map) { if (map[this._id] === UNDEFINED) { @@ -25082,10 +24472,13 @@ * @param key {Object | Function} * @param value {Any} * @return {WeakMap} the weak map */ WeakMap.prototype.set = function (obj, value) { + if (!isObject(obj)) { + throw new TypeError('Invalid value used as weak map key'); + } if (value === undefined) { value = UNDEFINED; } @@ -25098,10 +24491,14 @@ * @method has * @param key {Object | Function} * @return {boolean} if the key exists */ WeakMap.prototype.has = function (obj) { + if (!isObject(obj)) { + return false; + } + var meta = _emberMetalMeta.peekMeta(obj); if (meta) { var map = meta.readableWeak(); if (map) { return map[this._id] !== undefined; @@ -25122,10 +24519,18 @@ return true; } else { return false; } }; + + /* + * @method toString + * @return {String} + */ + WeakMap.prototype.toString = function () { + return '[object WeakMap]'; + }; }); enifed('ember-routing/ext/controller', ['exports', 'ember-metal/property_get', 'ember-runtime/mixins/controller'], function (exports, _emberMetalProperty_get, _emberRuntimeMixinsController) { 'use strict'; /** @@ -25204,14 +24609,14 @@ ``` An options hash with a `queryParams` property may be provided as the final argument to add query parameters to the destination URL. ```javascript aController.transitionToRoute('blogPost', 1, { - queryParams: {showComments: 'true'} + queryParams: { showComments: 'true' } }); // if you just want to transition the query parameters without changing the route - aController.transitionToRoute({queryParams: {sort: 'date'}}); + aController.transitionToRoute({ queryParams: { sort: 'date' } }); ``` See also [replaceRoute](/api/classes/Ember.ControllerMixin.html#method_replaceRoute). @param {String} name the name of the route or a URL @param {...Object} models the model(s) or identifier(s) to be used while transitioning to the route. @@ -25726,11 +25131,12 @@ function getHistoryPath(rootURL, location) { var path = _emberRoutingLocationUtil.getPath(location); var hash = _emberRoutingLocationUtil.getHash(location); var query = _emberRoutingLocationUtil.getQuery(location); var rootURLIndex = path.indexOf(rootURL); - var routeHash, hashParts; + var routeHash = undefined, + hashParts = undefined; // By convention, Ember.js routes using HashLocation are required to start // with `#/`. Anything else should NOT be considered a route and should // be passed straight through, without transformation. if (hash.substr(0, 2) === '#/') { @@ -26511,12 +25917,11 @@ if (prop in bucket) { return bucket[prop]; } else { return defaultValue; } - }, - cache: null + } }); }); enifed("ember-routing/system/controller_for", ["exports"], function (exports) { /** @module ember @@ -26536,11 +25941,11 @@ function controllerFor(container, controllerName, lookupOptions) { return container.lookup("controller:" + controllerName, lookupOptions); } }); -enifed('ember-routing/system/dsl', ['exports', 'ember-metal/debug', 'ember-metal/features'], function (exports, _emberMetalDebug, _emberMetalFeatures) { +enifed('ember-routing/system/dsl', ['exports', 'ember-metal/debug', 'ember-metal/assign', 'ember-metal/features'], function (exports, _emberMetalDebug, _emberMetalAssign, _emberMetalFeatures) { 'use strict'; /** @module ember @submodule ember-routing @@ -26550,14 +25955,10 @@ this.parent = name; this.enableLoadingSubstates = options && options.enableLoadingSubstates; this.matches = []; this.explicitIndex = undefined; this.options = options; - - if (false) { - this.router = options && options.router; - } } exports.default = DSL; DSL.prototype = { @@ -26575,14 +25976,10 @@ if (this.enableLoadingSubstates) { createRoute(this, name + '_loading', { resetNamespace: options.resetNamespace }); createRoute(this, name + '_error', { path: dummyErrorRoute }); } - if (false && options.serialize && this.router) { - this.router._serializeMethods[name] = options.serialize; - } - if (callback) { var fullName = getFullName(this, name, options.resetNamespace); var dsl = new DSL(fullName, this.options); createRoute(dsl, 'loading'); @@ -26594,12 +25991,28 @@ } else { createRoute(this, name, options); } }, - push: function (url, name, callback) { + push: function (url, name, callback, serialize) { var parts = name.split('.'); + + if (true) { + if (this.options.engineInfo) { + var localFullName = name.slice(this.options.engineInfo.fullName.length + 1); + var routeInfo = _emberMetalAssign.default({ localFullName: localFullName }, this.options.engineInfo); + + if (serialize) { + routeInfo.serializeMethod = serialize; + } + + this.options.addRouteForEngine(name, routeInfo); + } else if (serialize) { + throw new Error('Defining a route serializer on route \'' + name + '\' outside an Engine is not allowed.'); + } + } + if (url === '' || url === '/' || parts[parts.length - 1] === 'index') { this.explicitIndex = true; } this.matches.push([url, name, callback]); @@ -26655,18 +26068,83 @@ if (typeof options.path !== 'string') { options.path = '/' + name; } - dsl.push(options.path, fullName, callback); + dsl.push(options.path, fullName, callback, options.serialize); } DSL.map = function (callback) { var dsl = new DSL(); callback.call(dsl); return dsl; }; + + if (true) { + (function () { + var uuid = 0; + + DSL.prototype.mount = function (_name, _options) { + var options = _options || {}; + var engineRouteMap = this.options.resolveRouteMap(_name); + var name = _name; + + if (options.as) { + name = options.as; + } + + var fullName = getFullName(this, name, options.resetNamespace); + + var engineInfo = { + name: _name, + instanceId: uuid++, + mountPoint: fullName, + fullName: fullName + }; + + var path = options.path; + + if (typeof path !== 'string') { + path = '/' + name; + } + + var callback = undefined; + if (engineRouteMap) { + var shouldResetEngineInfo = false; + var oldEngineInfo = this.options.engineInfo; + if (oldEngineInfo) { + shouldResetEngineInfo = true; + this.options.engineInfo = engineInfo; + } + + var optionsForChild = _emberMetalAssign.default({ engineInfo: engineInfo }, this.options); + var childDSL = new DSL(fullName, optionsForChild); + + engineRouteMap.call(childDSL); + + callback = childDSL.generate(); + + if (shouldResetEngineInfo) { + this.options.engineInfo = oldEngineInfo; + } + } + + if (this.enableLoadingSubstates) { + var dummyErrorRoute = '/_unused_dummy_error_path_route_' + name + '/:error'; + createRoute(this, name + '_loading', { resetNamespace: options.resetNamespace }); + createRoute(this, name + '_error', { path: dummyErrorRoute }); + } + + var localFullName = 'application'; + var routeInfo = _emberMetalAssign.default({ localFullName: localFullName }, engineInfo); + + this.options.addRouteForEngine(fullName, routeInfo); + + this.push(path, fullName, callback); + }; + })(); + } }); enifed('ember-routing/system/generate_controller', ['exports', 'ember-metal/debug', 'ember-metal/property_get'], function (exports, _emberMetalDebug, _emberMetalProperty_get) { 'use strict'; exports.generateControllerFactory = generateControllerFactory; @@ -26684,20 +26162,18 @@ @method generateControllerFactory @private */ function generateControllerFactory(owner, controllerName, context) { - var Factory, fullName; - - Factory = owner._lookupFactory('controller:basic').extend({ + var Factory = owner._lookupFactory('controller:basic').extend({ isGenerated: true, toString: function () { return '(generated ' + controllerName + ' controller)'; } }); - fullName = 'controller:' + controllerName; + var fullName = 'controller:' + controllerName; owner.register(fullName, Factory); return Factory; } @@ -26736,12 +26212,12 @@ }); }); enifed('ember-routing/system/route', ['exports', 'ember-metal/debug', 'ember-metal/testing', 'ember-metal/features', 'ember-metal/error', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/get_properties', 'ember-metal/is_none', 'ember-metal/computed', 'ember-metal/assign', 'ember-runtime/utils', 'ember-metal/run_loop', 'ember-runtime/copy', 'ember-runtime/system/string', 'ember-runtime/system/object', 'ember-runtime/system/native_array', 'ember-runtime/mixins/evented', 'ember-runtime/mixins/action_handler', 'ember-routing/system/generate_controller', 'ember-routing/utils', 'container/owner', 'ember-metal/is_empty', 'ember-metal/symbol'], function (exports, _emberMetalDebug, _emberMetalTesting, _emberMetalFeatures, _emberMetalError, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalGet_properties, _emberMetalIs_none, _emberMetalComputed, _emberMetalAssign, _emberRuntimeUtils, _emberMetalRun_loop, _emberRuntimeCopy, _emberRuntimeSystemString, _emberRuntimeSystemObject, _emberRuntimeSystemNative_array, _emberRuntimeMixinsEvented, _emberRuntimeMixinsAction_handler, _emberRoutingSystemGenerate_controller, _emberRoutingUtils, _containerOwner, _emberMetalIs_empty, _emberMetalSymbol) { 'use strict'; + exports.defaultSerialize = defaultSerialize; exports.hasDefaultSerialize = hasDefaultSerialize; - var slice = Array.prototype.slice; function K() { return this; } @@ -26770,11 +26246,11 @@ return object; } var DEFAULT_SERIALIZE = _emberMetalSymbol.default('DEFAULT_SERIALIZE'); - if (false) { + if (true) { defaultSerialize[DEFAULT_SERIALIZE] = true; } function hasDefaultSerialize(route) { return !!route.serialize[DEFAULT_SERIALIZE]; @@ -26853,11 +26329,12 @@ @property _qp */ _qp: _emberMetalComputed.computed(function () { var _this = this; - var controllerProto, combinedQueryParameterConfiguration; + var controllerProto = undefined, + combinedQueryParameterConfiguration = undefined; var controllerName = this.controllerName || this.routeName; var definedControllerClass = _containerOwner.getOwner(this)._lookupFactory('controller:' + controllerName); var queryParameterConfiguraton = _emberMetalProperty_get.get(this, 'queryParams'); var hasRouterDefinedQueryParams = !!Object.keys(queryParameterConfiguraton).length; @@ -26914,11 +26391,11 @@ } } } var scope = desc.scope || 'model'; - var parts; + var parts = undefined; if (scope === 'controller') { parts = []; } @@ -27067,11 +26544,18 @@ var transition = this.router.router.activeTransition; var state = transition ? transition.state : this.router.router.state; var params = {}; - _emberMetalAssign.default(params, state.params[name]); + var fullName = name; + + if (true) { + fullName = getEngineRouteName(_containerOwner.getOwner(this), name); + } + + _emberMetalAssign.default(params, state.params[fullName]); + _emberMetalAssign.default(params, getQueryParamsFor(route, state)); return params; }, @@ -27189,39 +26673,14 @@ this.activate(); this.trigger('activate'); }, /** - The name of the view to use by default when rendering this routes template. - When rendering a template, the route will, by default, determine the - template and view to use from the name of the route itself. If you need to - define a specific view, set this property. - This is useful when multiple routes would benefit from using the same view - because it doesn't require a custom `renderTemplate` method. For example, - the following routes will all render using the `App.PostsListView` view: - ```javascript - var PostsList = Ember.Route.extend({ - viewName: 'postsList' - }); - App.PostsIndexRoute = PostsList.extend(); - App.PostsArchivedRoute = PostsList.extend(); - ``` - @property viewName - @type String - @default null - @since 1.4.0 - @public - */ - viewName: null, - - /** The name of the template to use by default when rendering this routes template. - This is similar with `viewName`, but is useful when you just want a custom - template without a view. ```javascript - var PostsList = Ember.Route.extend({ + let PostsList = Ember.Route.extend({ templateName: 'posts/list' }); App.PostsIndexRoute = PostsList.extend(); App.PostsArchivedRoute = PostsList.extend(); ``` @@ -27239,11 +26698,11 @@ of the route (i.e. `App.PostController` for `App.PostRoute`). However, if you would like to define a specific controller to use, you can do so using this property. This is useful in many ways, as the controller specified will be: * passed to the `setupController` method. - * used as the controller for the view being rendered by the route. + * used as the controller for the template being rendered by the route. * returned from a call to `controllerFor` for the route. @property controllerName @type String @default null @since 1.4.0 @@ -27441,11 +26900,11 @@ /** This action is called when one or more query params have changed. Bubbles. @method queryParamsDidChange @param changed {Object} Keys are names of query params that have changed. - @param totalPresent {Object} Keys are names of query params that are currently set. + @param totalPresent {Number} @param removed {Object} Keys are names of query params that have been removed. @returns {boolean} @private */ queryParamsDidChange: function (changed, totalPresent, removed) { @@ -27474,11 +26933,11 @@ var handlerInfos = transition.state.handlerInfos; var router = this.router; var qpMeta = router._queryParamsFor(handlerInfos[handlerInfos.length - 1].name); var changes = router._qpUpdates; - var replaceUrl; + var replaceUrl = undefined; _emberRoutingUtils.stashParamNames(router, handlerInfos); for (var i = 0; i < qpMeta.qps.length; ++i) { var qp = qpMeta.qps[i]; @@ -27487,11 +26946,12 @@ var presentKey = qp.urlKey in params && qp.urlKey; // Do a reverse lookup to see if the changed query // param URL key corresponds to a QP property on // this controller. - var value, svalue; + var value = undefined, + svalue = undefined; if (changes && qp.urlKey in changes) { // Value updated in/before setupController value = _emberMetalProperty_get.get(controller, qp.prop); svalue = route.serializeQueryParam(value, qp.urlKey, qp.type); } else { @@ -27606,14 +27066,14 @@ ``` An options hash with a `queryParams` property may be provided as the final argument to add query parameters to the destination URL. ```javascript this.transitionTo('blogPost', 1, { - queryParams: {showComments: 'true'} + queryParams: { showComments: 'true' } }); // if you just want to transition the query parameters without changing the route - this.transitionTo({queryParams: {sort: 'date'}}); + this.transitionTo({ queryParams: { sort: 'date' } }); ``` See also [replaceWith](#method_replaceWith). Simple Transition Example ```javascript App.Router.map(function() { @@ -27657,12 +27117,12 @@ }); }); App.IndexRoute = Ember.Route.extend({ actions: { moveToChocolateCereal: function() { - var cereal = { cerealId: 'ChocolateYumminess' }; - var breakfast = { breakfastId: 'CerealAndMilk' }; + let cereal = { cerealId: 'ChocolateYumminess' }; + let breakfast = { breakfastId: 'CerealAndMilk' }; this.transitionTo('cereal', breakfast, cereal); } } }); ``` @@ -27674,11 +27134,11 @@ }); }); App.IndexRoute = Ember.Route.extend({ actions: { transitionToApples: function() { - this.transitionTo('fruits.apples', {queryParams: {color: 'red'}}); + this.transitionTo('fruits.apples', { queryParams: { color: 'red' } }); } } }); ``` @method transitionTo @@ -27809,27 +27269,29 @@ if (this.router && this.router.router || !_emberMetalTesting.isTesting()) { var _router; (_router = this.router).send.apply(_router, args); } else { - var name = args[0]; + var _name2 = args[0]; args = slice.call(args, 1); - var action = this.actions[name]; + var action = this.actions[_name2]; if (action) { - return this.actions[name].apply(this, args); + return this.actions[_name2].apply(this, args); } } }, /** This hook is the entry point for router.js @private @method setup */ setup: function (context, transition) { - var controller; + var _this2 = this; + var controller = undefined; + var controllerName = this.controllerName || this.routeName; var definedController = this.controllerFor(controllerName, true); if (!definedController) { controller = this.generateController(controllerName, context); @@ -27847,28 +27309,30 @@ var queryParams = _emberMetalProperty_get.get(this, '_qp'); var states = queryParams.states; if (transition) { - // Update the model dep values used to calculate cache keys. - _emberRoutingUtils.stashParamNames(this.router, transition.state.handlerInfos); + (function () { + // Update the model dep values used to calculate cache keys. + _emberRoutingUtils.stashParamNames(_this2.router, transition.state.handlerInfos); - var params = transition.params; - var allParams = queryParams.propertyNames; - var cache = this._bucketCache; + var params = transition.params; + var allParams = queryParams.propertyNames; + var cache = _this2._bucketCache; - allParams.forEach(function (prop) { - var aQp = queryParams.map[prop]; + allParams.forEach(function (prop) { + var aQp = queryParams.map[prop]; - aQp.values = params; - var cacheKey = _emberRoutingUtils.calculateCacheKey(aQp.prefix, aQp.parts, aQp.values); + aQp.values = params; + var cacheKey = _emberRoutingUtils.calculateCacheKey(aQp.prefix, aQp.parts, aQp.values); - if (cache) { - var value = cache.lookup(cacheKey, prop, aQp.undecoratedDefaultValue); - _emberMetalProperty_set.set(controller, prop, value); - } - }); + if (cache) { + var value = cache.lookup(cacheKey, prop, aQp.undecoratedDefaultValue); + _emberMetalProperty_set.set(controller, prop, value); + } + }); + })(); } controller._qpDelegate = states.allowOverrides; if (transition) { @@ -27941,11 +27405,11 @@ hook): ```javascript App.PostRoute = Ember.Route.extend({ beforeModel: function(transition) { if (!App.Post) { - var self = this; + let self = this; return Ember.$.getScript('post.js').then(null, function(e) { self.transitionTo('help'); // Note that the above transitionTo will implicitly // halt the transition. If you were to return // nothing from this promise reject handler, @@ -28089,11 +27553,14 @@ the promise resolves, and the resolved value of the promise will be used as the model for this route. @public */ model: function (params, transition) { - var match, name, sawParams, value; + var match = undefined, + name = undefined, + sawParams = undefined, + value = undefined; var queryParams = _emberMetalProperty_get.get(this, '_qp.map'); for (var prop in params) { if (prop === 'queryParams' || queryParams && prop in queryParams) { continue; @@ -28277,11 +27744,11 @@ @public */ controllerFor: function (name, _skipAssert) { var owner = _containerOwner.getOwner(this); var route = owner.lookup('route:' + name); - var controller; + var controller = undefined; if (route && route.controllerName) { name = route.controllerName; } @@ -28369,11 +27836,11 @@ This method can be overridden to set up and render additional or alternative templates. ```javascript App.PostsRoute = Ember.Route.extend({ renderTemplate: function(controller, model) { - var favController = this.controllerFor('favoritePost'); + let favController = this.controllerFor('favoritePost'); // Render the `favoritePost` template into // the outlet `posts`, and display the `favoritePost` // controller. this.render('favoritePost', { outlet: 'posts', @@ -28423,33 +27890,32 @@ outlet: 'anOutletName' }) } }); ``` - `render` additionally allows you to supply which `view`, `controller`, and + `render` additionally allows you to supply which `controller` and `model` objects should be loaded and associated with the rendered template. ```javascript // posts route Ember.Route.extend({ renderTemplate: function(controller, model){ this.render('posts', { // the template to render, referenced by name into: 'application', // the template to render into, referenced by name outlet: 'anOutletName', // the outlet inside `options.template` to render into. - view: 'aViewName', // the view to use for this template, referenced by name controller: 'someControllerName', // the controller to use for this template, referenced by name model: model // the model to set on `options.controller`. }) } }); ``` - The string values provided for the template name, view, and controller + The string values provided for the template name, and controller will eventually pass through to the resolver for lookup. See Ember.Resolver for how these are mapped to JavaScript objects in your application. Not all options need to be passed to `render`. Default values will be used based on the name of the route specified in the router or the Route's - `controllerName`, `viewName` and `templateName` properties. + `controllerName` and `templateName` properties. For example: ```javascript // router Router.map(function() { this.route('index'); @@ -28470,11 +27936,10 @@ ```javascript // this.render('post', { // the template name associated with 'post' Route into: 'application', // the parent route to 'post' Route outlet: 'main', // {{outlet}} and {{outlet 'main'}} are synonymous, - view: 'post', // the view associated with the 'post' Route controller: 'post', // the controller associated with the 'post' Route }) ``` By default the controller's `model` will be the route's model, so it does not need to be passed unless you wish to change which model is being used. @@ -28493,11 +27958,11 @@ */ render: function (_name, options) { var namePassed = typeof _name === 'string' && !!_name; var isDefaultRender = arguments.length === 0 || _emberMetalIs_empty.default(arguments[0]); - var name; + var name = undefined; if (typeof _name === 'object' && !options) { name = this.routeName; options = _name; } else { @@ -28544,12 +28009,12 @@ @method disconnectOutlet @param {Object|String} options the options hash or outlet name @public */ disconnectOutlet: function (options) { - var outletName; - var parentView; + var outletName = undefined; + var parentView = undefined; if (!options || typeof options === 'string') { outletName = options; } else { outletName = options.outlet; parentView = options.parentView; @@ -28629,11 +28094,11 @@ if (!handlerInfos) { return; } var offset = _offset || 0; - var current; + var current = undefined; for (var i = 0; i < handlerInfos.length; i++) { current = handlerInfos[i].handler; if (current === route) { return handlerInfos[i + offset]; } @@ -28678,12 +28143,10 @@ if (options && options.model) { controller.set('model', options.model); } - var viewName = options && options.view || namePassed && name || route.viewName || name; - var ViewClass = owner._lookupFactory('view:' + viewName); var template = owner.lookup('template:' + templateName); var parent = undefined; if (into && (parent = parentRoute(route)) && into === parentRoute(route).routeName) { into = undefined; @@ -28693,16 +28156,16 @@ owner: owner, into: into, outlet: outlet, name: name, controller: controller, - ViewClass: ViewClass, - template: template || route._topLevelViewTemplate + template: template || route._topLevelViewTemplate, + ViewClass: undefined }; var LOG_VIEW_LOOKUPS = _emberMetalProperty_get.get(route.router, 'namespace.LOG_VIEW_LOOKUPS'); - if (LOG_VIEW_LOOKUPS && !ViewClass && !template) {} + if (LOG_VIEW_LOOKUPS && !template) {} return renderOptions; } function getFullQueryParams(router, state) { @@ -28720,10 +28183,14 @@ function getQueryParamsFor(route, state) { state.queryParamsFor = state.queryParamsFor || {}; var name = route.routeName; + if (true) { + name = getEngineRouteName(_containerOwner.getOwner(route), name); + } + if (state.queryParamsFor[name]) { return state.queryParamsFor[name]; } var fullQueryParams = getFullQueryParams(route.router, state); @@ -28755,11 +28222,11 @@ Merges all query parameters from a controller with those from a route, returning a new object and avoiding any mutations to the existing objects. */ function mergeEachQueryParams(controllerQP, routeQP) { - var keysAlreadyMergedOrSkippable; + var keysAlreadyMergedOrSkippable = undefined; var qps = {}; if (false) { keysAlreadyMergedOrSkippable = {}; } else { @@ -28809,10 +28276,99 @@ }); } function deprecateQueryParamDefaultValuesSetOnController(controllerName, routeName, propName) {} + /* + Returns an arguments array where the route name arg is prefixed based on the mount point + + @private + */ + function prefixRouteNameArg() { + for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + var routeName = args[0]; + var owner = _containerOwner.getOwner(this); + var prefix = owner.mountPoint; + + // only alter the routeName if it's actually referencing a route. + if (owner.routable && typeof routeName === 'string') { + if (resemblesURL(routeName)) { + throw new _emberMetalError.default('Route#transitionTo cannot be used for URLs. Please use the route name instead.'); + } else { + routeName = prefix + '.' + routeName; + args[0] = routeName; + } + } + + return args; + } + + /* + Check if a routeName resembles a url instead + + @private + */ + function resemblesURL(str) { + return typeof str === 'string' && (str === '' || str.charAt(0) === '/'); + } + + if (true) { + Route.reopen({ + replaceWith: function () { + for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args[_key3] = arguments[_key3]; + } + + return this._super.apply(this, prefixRouteNameArg.call.apply(prefixRouteNameArg, [this].concat(args))); + }, + + transitionTo: function () { + for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + args[_key4] = arguments[_key4]; + } + + return this._super.apply(this, prefixRouteNameArg.call.apply(prefixRouteNameArg, [this].concat(args))); + }, + + modelFor: function (_routeName) { + var routeName = undefined; + var owner = _containerOwner.getOwner(this); + + if (owner.routable && this.router && this.router.router.activeTransition) { + // only change the routeName when there is an active transition. + // otherwise, we need the passed in route name. + routeName = getEngineRouteName(owner, _routeName); + } else { + routeName = _routeName; + } + + for (var _len5 = arguments.length, args = Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) { + args[_key5 - 1] = arguments[_key5]; + } + + return this._super.apply(this, [routeName].concat(args)); + } + }); + } + + function getEngineRouteName(engine, routeName) { + if (engine.routable) { + var prefix = engine.mountPoint; + + if (routeName === 'application') { + return prefix; + } else { + return prefix + '.' + routeName; + } + } + + return routeName; + } + exports.default = Route; }); enifed('ember-routing/system/router', ['exports', 'ember-console', 'ember-metal/debug', 'ember-metal/error', 'ember-metal/features', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/properties', 'ember-metal/empty_object', 'ember-metal/computed', 'ember-metal/assign', 'ember-metal/run_loop', 'ember-runtime/system/object', 'ember-runtime/mixins/evented', 'ember-routing/system/route', 'ember-routing/system/dsl', 'ember-routing/location/api', 'ember-routing/utils', 'ember-metal/utils', 'ember-routing/system/router_state', 'container/owner', 'ember-metal/dictionary', 'router', 'router/transition'], function (exports, _emberConsole, _emberMetalDebug, _emberMetalError, _emberMetalFeatures, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalProperties, _emberMetalEmpty_object, _emberMetalComputed, _emberMetalAssign, _emberMetalRun_loop, _emberRuntimeSystemObject, _emberRuntimeMixinsEvented, _emberRoutingSystemRoute, _emberRoutingSystemDsl, _emberRoutingLocationApi, _emberRoutingUtils, _emberMetalUtils, _emberRoutingSystemRouter_state, _containerOwner, _emberMetalDictionary, _router4, _routerTransition) { 'use strict'; @@ -28820,11 +28376,11 @@ function K() { return this; } - var slice = [].slice; + var slice = Array.prototype.slice; /** The `Ember.Router` class manages the application state and URLs. Refer to the [routing guide](http://emberjs.com/guides/routing/) for documentation. @@ -28882,17 +28438,34 @@ router.map(dsl.generate()); }, _buildDSL: function () { + var _this = this; + var moduleBasedResolver = this._hasModuleBasedResolver(); var options = { enableLoadingSubstates: !!moduleBasedResolver }; - if (false) { - options.router = this; + if (true) { + (function () { + var owner = _containerOwner.getOwner(_this); + var router = _this; + + options.enableLoadingSubstates = !!moduleBasedResolver; + + options.resolveRouteMap = function (name) { + return owner._lookupFactory('route-map:' + name); + }; + + options.addRouteForEngine = function (name, engineInfo) { + if (!router._engineInfoByRoute[name]) { + router._engineInfoByRoute[name] = engineInfo; + } + }; + })(); } return new _emberRoutingSystemDsl.default(null, options); }, @@ -28902,12 +28475,13 @@ this._activeViews = {}; this._qpCache = new _emberMetalEmpty_object.default(); this._resetQueuedQueryParameterChanges(); this._handledErrors = _emberMetalDictionary.default(null); - if (false) { - this._serializeMethods = new _emberMetalEmpty_object.default(); + if (true) { + this._engineInstances = new _emberMetalEmpty_object.default(); + this._engineInfoByRoute = new _emberMetalEmpty_object.default(); } }, /* Resets all pending query paramter changes. @@ -28965,11 +28539,11 @@ } } }, setupRouter: function () { - var _this = this; + var _this2 = this; this._initRouterJs(); this._setupLocation(); var router = this.router; @@ -28982,11 +28556,11 @@ } this._setupRouter(router, location); location.onUpdateURL(function (url) { - _this.handleURL(url); + _this2.handleURL(url); }); return true; }, @@ -28995,11 +28569,11 @@ change. Triggers the router level `didTransition` hook. For example, to notify google analytics when the route changes, you could use this hook. (Note: requires also including GA scripts, etc.) ```javascript - var Router = Ember.Router.extend({ + let Router = Ember.Router.extend({ location: config.locationType, didTransition: function() { this._super(...arguments); return ga('send', 'pageview', { 'page': this.get('url'), @@ -29029,22 +28603,22 @@ } }, _setOutlets: function () { var handlerInfos = this.router.currentHandlerInfos; - var route; - var defaultParentState; + var route = undefined; + var defaultParentState = undefined; var liveRoutes = null; if (!handlerInfos) { return; } for (var i = 0; i < handlerInfos.length; i++) { route = handlerInfos[i].handler; var connections = route.connections; - var ownState; + var ownState = undefined; for (var j = 0; j < connections.length; j++) { var appended = appendLiveRoute(liveRoutes, defaultParentState, connections[j]); liveRoutes = appended.liveRoutes; if (appended.ownState.render.name === route.routeName || appended.ownState.render.outlet === 'main') { ownState = appended.ownState; @@ -29109,11 +28683,11 @@ @return {Transition} the transition object associated with this attempted transition @public */ transitionTo: function () { - var queryParams; + var queryParams = undefined; for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } @@ -29216,10 +28790,20 @@ if (this._toplevelView) { this._toplevelView.destroy(); this._toplevelView = null; } this._super.apply(this, arguments); + + if (true) { + var instances = this._engineInstances; + for (var _name in instances) { + for (var id in instances[_name]) { + _emberMetalRun_loop.default(instances[_name][id], 'destroy'); + } + } + } + this.reset(); }, _lookupActiveComponentNode: function (templateName) { return this._activeViews[templateName]; @@ -29246,13 +28830,13 @@ Triggers a transition to a route based on query parameter changes. This is called once per runloop, to batch changes. e.g. if these methods are called in succession: this._activeQPChanged('foo', '10'); - // results in _queuedQPChanges = {foo: '10'} + // results in _queuedQPChanges = { foo: '10' } this._activeQPChanged('bar', false); - // results in _queuedQPChanges = {foo: '10', bar: false} + // results in _queuedQPChanges = { foo: '10', bar: false } _queuedQPChanges will represent both of these changes and the transition using `transitionTo` will be triggered once. */ _fireQueryParamTransition: function () { @@ -29310,61 +28894,82 @@ } } }, _getHandlerFunction: function () { - var _this2 = this; + var _this3 = this; var seen = new _emberMetalEmpty_object.default(); var owner = _containerOwner.getOwner(this); - var DefaultRoute = owner._lookupFactory('route:basic'); return function (name) { - var routeName = 'route:' + name; - var handler = owner.lookup(routeName); + var routeName = name; + var routeOwner = owner; + var engineInfo = undefined; + if (true) { + engineInfo = _this3._engineInfoByRoute[routeName]; + + if (engineInfo) { + var engineInstance = _this3._getEngineInstance(engineInfo); + + routeOwner = engineInstance; + routeName = engineInfo.localFullName; + } + } + + var fullRouteName = 'route:' + routeName; + + var handler = routeOwner.lookup(fullRouteName); + if (seen[name]) { return handler; } seen[name] = true; if (!handler) { - owner.register(routeName, DefaultRoute.extend()); - handler = owner.lookup(routeName); + var DefaultRoute = routeOwner._lookupFactory('route:basic'); - if (_emberMetalProperty_get.get(_this2, 'namespace.LOG_ACTIVE_GENERATION')) {} + routeOwner.register(fullRouteName, DefaultRoute.extend()); + handler = routeOwner.lookup(fullRouteName); + + if (_emberMetalProperty_get.get(_this3, 'namespace.LOG_ACTIVE_GENERATION')) {} } - handler.routeName = name; + handler.routeName = routeName; + + if (engineInfo && !_emberRoutingSystemRoute.hasDefaultSerialize(handler)) { + throw new Error('Defining a custom serialize method on an Engine route is not supported.'); + } + return handler; }; }, _getSerializerFunction: function () { - var _this3 = this; + var _this4 = this; return function (name) { - var serializer = _this3._serializeMethods[name]; + var engineInfo = _this4._engineInfoByRoute[name]; - if (!serializer) { - var handler = _this3.router.getHandler(name); - - _this3._serializeMethods[name] = handler.serialize; + // If this is not an Engine route, we fall back to the handler for serialization + if (!engineInfo) { + return; } - return serializer; + return engineInfo.serializeMethod || _emberRoutingSystemRoute.defaultSerialize; }; }, _setupRouter: function (router, location) { - var lastURL; + var lastURL = undefined; var emberRouter = this; router.getHandler = this._getHandlerFunction(); - if (false) { + if (true) { router.getSerializer = this._getSerializerFunction(); } var doUpdateURL = function () { location.setURL(lastURL); @@ -29374,18 +28979,20 @@ lastURL = path; _emberMetalRun_loop.default.once(doUpdateURL); }; if (location.replaceURL) { - var doReplaceURL = function () { - location.replaceURL(lastURL); - }; + (function () { + var doReplaceURL = function () { + location.replaceURL(lastURL); + }; - router.replaceURL = function (path) { - lastURL = path; - _emberMetalRun_loop.default.once(doReplaceURL); - }; + router.replaceURL = function (path) { + lastURL = path; + _emberMetalRun_loop.default.once(doReplaceURL); + }; + })(); } router.didTransition = function (infos) { emberRouter.didTransition(infos); }; @@ -29629,11 +29236,12 @@ @private */ function forEachRouteAbove(originRoute, transition, callback) { var handlerInfos = transition.state.handlerInfos; var originRouteFound = false; - var handlerInfo, route; + var handlerInfo = undefined, + route = undefined; for (var i = handlerInfos.length - 1; i >= 0; --i) { handlerInfo = handlerInfos[i]; route = handlerInfo.handler; @@ -29711,11 +29319,11 @@ } }; function logError(_error, initialMessage) { var errorArgs = []; - var error; + var error = undefined; if (_error && typeof _error === 'object' && typeof _error.errorThrown === 'object') { error = _error.errorThrown; } else { error = _error; } @@ -29740,12 +29348,22 @@ _emberConsole.default.error.apply(this, errorArgs); } function findChildRouteName(parentRoute, originatingChildRoute, name) { var router = parentRoute.router; - var childName; - var targetChildRouteName = originatingChildRoute.routeName.split('.').pop(); + var childName = undefined; + var originatingChildRouteName = originatingChildRoute.routeName; + + if (true) { + // The only time the originatingChildRoute's name should be 'application' + // is if we're entering an engine + if (originatingChildRouteName === 'application') { + originatingChildRouteName = _containerOwner.getOwner(originatingChildRoute).mountPoint; + } + } + + var targetChildRouteName = originatingChildRouteName.split('.').pop(); var namespace = parentRoute.routeName === 'application' ? '' : parentRoute.routeName + '.'; // First, try a named loading state, e.g. 'foo_loading' childName = namespace + targetChildRouteName + '_' + name; if (routeHasBeenDefined(router, childName)) { @@ -29773,11 +29391,12 @@ } throw new _emberMetalError.default('Can\'t trigger action \'' + name + '\' because your app hasn\'t finished transitioning into its first route. To trigger an action on destination routes during a transition, you can call `.send()` on the `Transition` object passed to the `model/beforeModel/afterModel` hooks.'); } var eventWasHandled = false; - var handlerInfo, handler; + var handlerInfo = undefined, + handler = undefined; for (var i = handlerInfos.length - 1; i >= 0; i--) { handlerInfo = handlerInfos[i]; handler = handlerInfo.handler; @@ -29917,11 +29536,13 @@ } } return true; } - var name, nameParts, oldNameParts; + var name = undefined, + nameParts = undefined, + oldNameParts = undefined; for (var i = 1; i < handlerInfos.length; i++) { name = handlerInfos[i].name; nameParts = name.split('.'); oldNameParts = slice.call(path); @@ -29998,25 +29619,26 @@ } } } function appendLiveRoute(liveRoutes, defaultParentState, renderOptions) { - var target; + var target = undefined; var myState = { render: renderOptions, - outlets: new _emberMetalEmpty_object.default() + outlets: new _emberMetalEmpty_object.default(), + wasUsed: false }; if (renderOptions.into) { target = findLiveRoute(liveRoutes, renderOptions.into); } else { target = defaultParentState; } if (target) { _emberMetalProperty_set.set(target.outlets, renderOptions.outlet, myState); } else { if (renderOptions.into) { - // Megahax time. Post-2.0-breaking-changes, we will just assert + // Megahax time. Post-3.0-breaking-changes, we will just assert // right here that the user tried to target a nonexistent // thing. But for now we still need to support the `render` // helper, and people are allowed to target templates rendered // by the render helper. So instead we defer doing anyting with // these orphan renders until afterRender. @@ -30065,37 +29687,67 @@ }; return defaultParentState; } } + if (true) { + EmberRouter.reopen({ + _getEngineInstance: function (_ref) { + var name = _ref.name; + var instanceId = _ref.instanceId; + var mountPoint = _ref.mountPoint; + + var engineInstances = this._engineInstances; + + if (!engineInstances[name]) { + engineInstances[name] = new _emberMetalEmpty_object.default(); + } + + var engineInstance = engineInstances[name][instanceId]; + + if (!engineInstance) { + var owner = _containerOwner.getOwner(this); + + engineInstance = owner.buildChildEngineInstance(name, { + routable: true, + mountPoint: mountPoint + }); + + engineInstance.boot(); + + engineInstances[name][instanceId] = engineInstance; + } + + return engineInstance; + } + }); + } + exports.default = EmberRouter; }); /** @module ember @submodule ember-routing */ -// `wasUsed` gets set by the render helper. See the function -// `impersonateAnOutlet`. +// `wasUsed` gets set by the render helper. enifed('ember-routing/system/router_state', ['exports', 'ember-metal/is_empty', 'ember-runtime/system/object', 'ember-metal/assign'], function (exports, _emberMetalIs_empty, _emberRuntimeSystemObject, _emberMetalAssign) { 'use strict'; - var keys = Object.keys; - - var RouterState = _emberRuntimeSystemObject.default.extend({ + exports.default = _emberRuntimeSystemObject.default.extend({ emberRouter: null, routerJs: null, routerJsState: null, isActiveIntent: function (routeName, models, queryParams, queryParamsMustMatch) { var state = this.routerJsState; if (!this.routerJs.isActiveIntent(routeName, models, null, state)) { return false; } - var emptyQueryParams = _emberMetalIs_empty.default(keys(queryParams)); + var emptyQueryParams = _emberMetalIs_empty.default(Object.keys(queryParams)); if (queryParamsMustMatch && !emptyQueryParams) { var visibleQueryParams = {}; _emberMetalAssign.default(visibleQueryParams, queryParams); @@ -30106,11 +29758,11 @@ return true; } }); function shallowEqual(a, b) { - var k; + var k = undefined; for (k in a) { if (a.hasOwnProperty(k) && a[k] !== b[k]) { return false; } } @@ -30119,22 +29771,22 @@ return false; } } return true; } - - exports.default = RouterState; }); enifed('ember-routing/utils', ['exports', 'ember-metal/assign', 'ember-metal/property_get'], function (exports, _emberMetalAssign, _emberMetalProperty_get) { 'use strict'; exports.routeArgs = routeArgs; exports.getActiveTargetName = getActiveTargetName; exports.stashParamNames = stashParamNames; exports.calculateCacheKey = calculateCacheKey; exports.normalizeControllerQueryParams = normalizeControllerQueryParams; + var ALL_PERIODS_REGEX = /\./g; + function routeArgs(targetRouteName, models, queryParams) { var args = []; if (typeof targetRouteName === 'string') { args.push('' + targetRouteName); } @@ -30210,11 +29862,11 @@ var parts = _parts || []; var suffixes = ''; for (var i = 0; i < parts.length; ++i) { var part = parts[i]; var cacheValuePrefix = _calculateCacheValuePrefix(prefix, part); - var value; + var value = undefined; if (values) { if (cacheValuePrefix && cacheValuePrefix in values) { var partRemovedPrefix = part.indexOf(cacheValuePrefix) === 0 ? part.substr(cacheValuePrefix.length + 1) : part; value = _emberMetalProperty_get.get(values[cacheValuePrefix], partRemovedPrefix); } else { @@ -30224,12 +29876,10 @@ suffixes += '::' + part + ':' + value; } return prefix + suffixes.replace(ALL_PERIODS_REGEX, '-'); } - var ALL_PERIODS_REGEX = /\./g; - /* Controller-defined query parameters can come in three shapes: Array queryParams: ['foo', 'bar'] @@ -30275,11 +29925,11 @@ return qpMap; } function accumulateQueryParamDescriptors(_desc, accum) { var desc = _desc; - var tmp; + var tmp = undefined; if (typeof desc === 'string') { tmp = {}; tmp[desc] = { as: null }; desc = tmp; } @@ -30516,15 +30166,15 @@ property is null, an empty string, empty array, or empty function. Example ```javascript - var ToDoList = Ember.Object.extend({ + let ToDoList = Ember.Object.extend({ isDone: Ember.computed.empty('todos') }); - var todoList = ToDoList.create({ + let todoList = ToDoList.create({ todos: ['Unit Test', 'Documentation', 'Release'] }); todoList.get('isDone'); // false todoList.get('todos').clear(); @@ -30551,15 +30201,15 @@ property is NOT null, an empty string, empty array, or empty function. Example ```javascript - var Hamster = Ember.Object.extend({ + let Hamster = Ember.Object.extend({ hasStuff: Ember.computed.notEmpty('backpack') }); - var hamster = Hamster.create({ backpack: ['Food', 'Sleeping Bag', 'Tent'] }); + let hamster = Hamster.create({ backpack: ['Food', 'Sleeping Bag', 'Tent'] }); hamster.get('hasStuff'); // true hamster.get('backpack').clear(); // [] hamster.get('hasStuff'); // false ``` @@ -30584,15 +30234,15 @@ about use of ==, which can be technically confusing. Example ```javascript - var Hamster = Ember.Object.extend({ + let Hamster = Ember.Object.extend({ isHungry: Ember.computed.none('food') }); - var hamster = Hamster.create(); + let hamster = Hamster.create(); hamster.get('isHungry'); // true hamster.set('food', 'Banana'); hamster.get('isHungry'); // false hamster.set('food', null); @@ -30618,15 +30268,15 @@ of the original value for the dependent property. Example ```javascript - var User = Ember.Object.extend({ + let User = Ember.Object.extend({ isAnonymous: Ember.computed.not('loggedIn') }); - var user = User.create({loggedIn: false}); + let user = User.create({loggedIn: false}); user.get('isAnonymous'); // true user.set('loggedIn', true); user.get('isAnonymous'); // false ``` @@ -30648,15 +30298,15 @@ /** A computed property that converts the provided dependent property into a boolean value. ```javascript - var Hamster = Ember.Object.extend({ + let Hamster = Ember.Object.extend({ hasBananas: Ember.computed.bool('numBananas') }); - var hamster = Hamster.create(); + let hamster = Hamster.create(); hamster.get('hasBananas'); // false hamster.set('numBananas', 0); hamster.get('hasBananas'); // false hamster.set('numBananas', 1); @@ -30685,15 +30335,15 @@ if the value matches the RegExp and `false` if it does not. Example ```javascript - var User = Ember.Object.extend({ + let User = Ember.Object.extend({ hasValidEmail: Ember.computed.match('email', /^.+@.+\..+$/) }); - var user = User.create({loggedIn: false}); + let user = User.create({loggedIn: false}); user.get('hasValidEmail'); // false user.set('email', ''); user.get('hasValidEmail'); // false user.set('email', 'ember_hamster@example.com'); @@ -30722,15 +30372,15 @@ is equal to the given value. Example ```javascript - var Hamster = Ember.Object.extend({ + let Hamster = Ember.Object.extend({ napTime: Ember.computed.equal('state', 'sleepy') }); - var hamster = Hamster.create(); + let hamster = Hamster.create(); hamster.get('napTime'); // false hamster.set('state', 'sleepy'); hamster.get('napTime'); // true hamster.set('state', 'hungry'); @@ -30757,15 +30407,15 @@ is greater than the provided value. Example ```javascript - var Hamster = Ember.Object.extend({ + let Hamster = Ember.Object.extend({ hasTooManyBananas: Ember.computed.gt('numBananas', 10) }); - var hamster = Hamster.create(); + let hamster = Hamster.create(); hamster.get('hasTooManyBananas'); // false hamster.set('numBananas', 3); hamster.get('hasTooManyBananas'); // false hamster.set('numBananas', 11); @@ -30792,15 +30442,15 @@ is greater than or equal to the provided value. Example ```javascript - var Hamster = Ember.Object.extend({ + let Hamster = Ember.Object.extend({ hasTooManyBananas: Ember.computed.gte('numBananas', 10) }); - var hamster = Hamster.create(); + let hamster = Hamster.create(); hamster.get('hasTooManyBananas'); // false hamster.set('numBananas', 3); hamster.get('hasTooManyBananas'); // false hamster.set('numBananas', 10); @@ -30827,15 +30477,15 @@ is less than the provided value. Example ```javascript - var Hamster = Ember.Object.extend({ + let Hamster = Ember.Object.extend({ needsMoreBananas: Ember.computed.lt('numBananas', 3) }); - var hamster = Hamster.create(); + let hamster = Hamster.create(); hamster.get('needsMoreBananas'); // true hamster.set('numBananas', 3); hamster.get('needsMoreBananas'); // false hamster.set('numBananas', 2); @@ -30862,15 +30512,15 @@ is less than or equal to the provided value. Example ```javascript - var Hamster = Ember.Object.extend({ + let Hamster = Ember.Object.extend({ needsMoreBananas: Ember.computed.lte('numBananas', 3) }); - var hamster = Hamster.create(); + let hamster = Hamster.create(); hamster.get('needsMoreBananas'); // true hamster.set('numBananas', 5); hamster.get('needsMoreBananas'); // false hamster.set('numBananas', 3); @@ -30897,21 +30547,21 @@ original values for the provided dependent properties. You may pass in more than two properties and even use property brace expansion. The computed property will return the first falsy value or last truthy value - just like JavaScript's `||` operator. + just like JavaScript's `&&` operator. Example ```javascript - var Hamster = Ember.Object.extend({ + let Hamster = Ember.Object.extend({ readyForCamp: Ember.computed.and('hasTent', 'hasBackpack'), readyForHike: Ember.computed.and('hasWalkingStick', 'hasBackpack') }); - var tomster = Hamster.create(); + let tomster = Hamster.create(); tomster.get('readyForCamp'); // false tomster.set('hasTent', true); tomster.get('readyForCamp'); // false tomster.set('hasBackpack', true); @@ -30944,16 +30594,16 @@ like JavaScript's `||` operator. Example ```javascript - var Hamster = Ember.Object.extend({ + let Hamster = Ember.Object.extend({ readyForRain: Ember.computed.or('hasJacket', 'hasUmbrella'), readyForBeach: Ember.computed.or('{hasSunscreen,hasUmbrella}') }); - var tomster = Hamster.create(); + let tomster = Hamster.create(); tomster.get('readyForRain'); // undefined tomster.set('hasUmbrella', true); tomster.get('readyForRain'); // true tomster.set('hasJacket', 'Yes'); @@ -30978,16 +30628,16 @@ Creates a new property that is an alias for another property on an object. Calls to `get` or `set` this property behave as though they were called on the original property. ```javascript - var Person = Ember.Object.extend({ + let Person = Ember.Object.extend({ name: 'Alex Matchneer', nomen: Ember.computed.alias('name') }); - var alex = Person.create(); + let alex = Person.create(); alex.get('nomen'); // 'Alex Matchneer' alex.get('name'); // 'Alex Matchneer' alex.set('nomen', '@machty'); @@ -31010,17 +30660,17 @@ diverge from the upstream property. Example ```javascript - var User = Ember.Object.extend({ + let User = Ember.Object.extend({ firstName: null, lastName: null, nickName: Ember.computed.oneWay('firstName') }); - var teddy = User.create({ + let teddy = User.create({ firstName: 'Teddy', lastName: 'Zeenny' }); teddy.get('nickName'); // 'Teddy' @@ -31060,17 +30710,17 @@ This prevents the reverse flow, and also throws an exception when it occurs. Example ```javascript - var User = Ember.Object.extend({ + let User = Ember.Object.extend({ firstName: null, lastName: null, nickName: Ember.computed.readOnly('firstName') }); - var teddy = User.create({ + let teddy = User.create({ firstName: 'Teddy', lastName: 'Zeenny' }); teddy.get('nickName'); // 'Teddy' @@ -31096,13 +30746,28 @@ Creates a new property that is an alias for another property on an object. Calls to `get` or `set` this property behave as though they were called on the original property, but also print a deprecation warning. + ```javascript + let Hamster = Ember.Object.extend({ + bananaCount: Ember.computed.deprecatingAlias('cavendishCount', { + id: 'hamster.deprecate-banana', + until: '3.0.0' + }) + }); + + let hamster = Hamster.create(); + + hamster.set('bananaCount', 5); // Prints a deprecation warning. + hamster.get('cavendishCount'); // 5 + ``` + @method deprecatingAlias @for Ember.computed @param {String} dependentKey + @param {Object} options Options for `Ember.deprecate`. @return {Ember.ComputedProperty} computed property which creates an alias with a deprecation to the original value for property. @since 1.7.0 @public */ @@ -31157,11 +30822,11 @@ }).readOnly(); } function arrayMacro(dependentKey, callback) { // This is a bit ugly - var propertyName; + var propertyName = undefined; if (/@each/.test(dependentKey)) { propertyName = dependentKey.replace(/\.@each.*$/, ''); } else { propertyName = dependentKey; dependentKey += '.[]'; @@ -31211,16 +30876,16 @@ A computed property that calculates the maximum value in the dependent array. This will return `-Infinity` when the dependent array is empty. ```javascript - var Person = Ember.Object.extend({ + let Person = Ember.Object.extend({ childAges: Ember.computed.mapBy('children', 'age'), maxChildAge: Ember.computed.max('childAges') }); - var lordByron = Person.create({ children: [] }); + let lordByron = Person.create({ children: [] }); lordByron.get('maxChildAge'); // -Infinity lordByron.get('children').pushObject({ name: 'Augusta Ada Byron', age: 7 }); @@ -31259,16 +30924,16 @@ A computed property that calculates the minimum value in the dependent array. This will return `Infinity` when the dependent array is empty. ```javascript - var Person = Ember.Object.extend({ + let Person = Ember.Object.extend({ childAges: Ember.computed.mapBy('children', 'age'), minChildAge: Ember.computed.min('childAges') }); - var lordByron = Person.create({ children: [] }); + let lordByron = Person.create({ children: [] }); lordByron.get('minChildAge'); // Infinity lordByron.get('children').pushObject({ name: 'Augusta Ada Byron', age: 7 }); @@ -31315,17 +30980,17 @@ ``` Example ```javascript - var Hamster = Ember.Object.extend({ + let Hamster = Ember.Object.extend({ excitingChores: Ember.computed.map('chores', function(chore, index) { return chore.toUpperCase() + '!'; }) }); - var hamster = Hamster.create({ + let hamster = Hamster.create({ chores: ['clean', 'write more unit tests'] }); hamster.get('excitingChores'); // ['CLEAN!', 'WRITE MORE UNIT TESTS!'] ``` @@ -31346,15 +31011,15 @@ /** Returns an array mapped to the specified key. ```javascript - var Person = Ember.Object.extend({ + let Person = Ember.Object.extend({ childAges: Ember.computed.mapBy('children', 'age') }); - var lordByron = Person.create({ children: [] }); + let lordByron = Person.create({ children: [] }); lordByron.get('childAges'); // [] lordByron.get('children').pushObject({ name: 'Augusta Ada Byron', age: 7 }); lordByron.get('childAges'); // [7] lordByron.get('children').pushObjects([{ @@ -31393,17 +31058,17 @@ ```javascript function(item, index, array); ``` ```javascript - var Hamster = Ember.Object.extend({ + let Hamster = Ember.Object.extend({ remainingChores: Ember.computed.filter('chores', function(chore, index, array) { return !chore.done; }) }); - var hamster = Hamster.create({ + let hamster = Hamster.create({ chores: [ { name: 'cook', done: true }, { name: 'clean', done: true }, { name: 'write more unit tests', done: false } ] @@ -31428,15 +31093,15 @@ /** Filters the array by the property and value ```javascript - var Hamster = Ember.Object.extend({ + let Hamster = Ember.Object.extend({ remainingChores: Ember.computed.filterBy('chores', 'done', false) }); - var hamster = Hamster.create({ + let hamster = Hamster.create({ chores: [ { name: 'cook', done: true }, { name: 'clean', done: true }, { name: 'write more unit tests', done: false } ] @@ -31453,11 +31118,11 @@ @return {Ember.ComputedProperty} the filtered array @public */ function filterBy(dependentKey, propertyKey, value) { - var callback; + var callback = undefined; if (arguments.length === 2) { callback = function (item) { return _emberMetalProperty_get.get(item, propertyKey); }; @@ -31475,15 +31140,15 @@ elements from one or more dependent arrays. Example ```javascript - var Hamster = Ember.Object.extend({ + let Hamster = Ember.Object.extend({ uniqueFruits: Ember.computed.uniq('fruits') }); - var hamster = Hamster.create({ + let hamster = Hamster.create({ fruits: [ 'banana', 'grape', 'kale', 'banana' @@ -31527,25 +31192,28 @@ } /** A computed property which returns a new array with all the unique elements from an array, with uniqueness determined by specific key. + Example + ```javascript - var Hamster = Ember.Object.extend({ + let Hamster = Ember.Object.extend({ uniqueFruits: Ember.computed.uniqBy('fruits', 'id') }); - var hamster = Hamster.create({ + let hamster = Hamster.create({ fruits: [ { id: 1, 'banana' }, { id: 2, 'grape' }, { id: 3, 'peach' }, { id: 1, 'banana' } ] }); hamster.get('uniqueFruits'); // [ { id: 1, 'banana' }, { id: 2, 'grape' }, { id: 3, 'peach' }] ``` + @method uniqBy @for Ember.computed @param {String} dependentKey @param {String} propertyKey @return {Ember.ComputedProperty} computes a new array with all the @@ -31589,11 +31257,11 @@ elements from two or more dependent arrays. Example ```javascript - var obj = Ember.Object.extend({ + let obj = Ember.Object.extend({ friendsInCommon: Ember.computed.intersect('adaFriends', 'charlesFriends') }).create({ adaFriends: ['Charles Babbage', 'John Hobhouse', 'William King', 'Mary Somerville'], charlesFriends: ['William King', 'Mary Somerville', 'Ada Lovelace', 'George Peacock'] }); @@ -31652,16 +31320,16 @@ dependent array. Example ```javascript - var Hamster = Ember.Object.extend({ + let Hamster = Ember.Object.extend({ likes: ['banana', 'grape', 'kale'], wants: Ember.computed.setDiff('likes', 'fruits') }); - var hamster = Hamster.create({ + let hamster = Hamster.create({ fruits: [ 'grape', 'kale', ] }); @@ -31706,15 +31374,15 @@ for the provided dependent properties. Example ```javascript - var Hamster = Ember.Object.extend({ + let Hamster = Ember.Object.extend({ clothes: Ember.computed.collect('hat', 'shirt') }); - var hamster = Hamster.create(); + let hamster = Hamster.create(); hamster.get('clothes'); // [null, null] hamster.set('hat', 'Camp Hat'); hamster.set('shirt', 'Camp Shirt'); hamster.get('clothes'); // ['Camp Hat', 'Camp Shirt'] @@ -31771,11 +31439,11 @@ `itemA.get( 'foo' ) - itemB.get( 'foo' )` can be used instead of series of `if`. Example ```javascript - var ToDoList = Ember.Object.extend({ + let ToDoList = Ember.Object.extend({ // using standard ascending sort todosSorting: ['name'], sortedTodos: Ember.computed.sort('todos', 'todosSorting'), // using descending sort @@ -31792,11 +31460,11 @@ return 0; }) }); - var todoList = ToDoList.create({todos: [ + let todoList = ToDoList.create({todos: [ { name: 'Unit Test', priority: 2 }, { name: 'Documentation', priority: 3 }, { name: 'Release', priority: 1 } ]}); @@ -31849,11 +31517,11 @@ var activeObserversMap = cp._activeObserverMap || (cp._activeObserverMap = new _emberMetalWeak_map.default()); var activeObservers = activeObserversMap.get(this); if (activeObservers) { activeObservers.forEach(function (args) { - _emberMetalObserver.removeObserver.apply(null, args); + return _emberMetalObserver.removeObserver.apply(null, args); }); } function sortPropertyDidChange() { this.notifyPropertyChange(key); @@ -31975,11 +31643,13 @@ 'use strict'; exports.default = copy; function _copy(obj, deep, seen, copies) { - var ret, loc, key; + var ret = undefined, + loc = undefined, + key = undefined; // primitive data types are immutable, just return them. if (typeof obj !== 'object' || obj === null) { return obj; } @@ -32087,11 +31757,11 @@ lastName: '', fullName: function() { return this.get('firstName') + ' ' + this.get('lastName'); }.property() // Call this flag to mark the function as a property }); - var president = MyApp.President.create({ + let president = MyApp.President.create({ firstName: 'Barack', lastName: 'Obama' }); president.get('fullName'); // 'Barack Obama' ``` @@ -32592,22 +32262,21 @@ */ function validatePropertyInjections(factory) { var proto = factory.proto(); var types = []; - var key, desc, validator, i; - for (key in proto) { - desc = proto[key]; + for (var key in proto) { + var desc = proto[key]; if (desc instanceof _emberMetalInjected_property.default && types.indexOf(desc.type) === -1) { types.push(desc.type); } } if (types.length) { - for (i = 0; i < types.length; i++) { - validator = typeValidators[types[i]]; + for (var i = 0; i < types.length; i++) { + var validator = typeValidators[types[i]]; if (typeof validator === 'function') { validator(factory); } } @@ -32783,18 +32452,18 @@ the `actions` hash defined on extended parent classes or mixins rather than just replace the entire hash, e.g.: ```js App.CanDisplayBanner = Ember.Mixin.create({ actions: { - displayBanner: function(msg) { + displayBanner(msg) { // ... } } }); App.WelcomeRoute = Ember.Route.extend(App.CanDisplayBanner, { actions: { - playMusic: function() { + playMusic() { // ... } } }); // `WelcomeRoute`, when active, will be able to respond @@ -32807,11 +32476,11 @@ the value of the `this` context is the Controller, Route, View or Component object: ```js App.SongRoute = Ember.Route.extend({ actions: { - myAction: function() { + myAction() { this.controllerFor("song"); this.transitionTo("other.route"); ... } } @@ -32822,18 +32491,18 @@ class or mixin: Take for example the following routes: ```js App.DebugRoute = Ember.Mixin.create({ actions: { - debugRouteInformation: function() { + debugRouteInformation() { console.debug("trololo"); } } }); App.AnnoyingDebugRoute = Ember.Route.extend(App.DebugRoute, { actions: { - debugRouteInformation: function() { + debugRouteInformation() { // also call the debugRouteInformation of mixed in App.DebugRoute this._super(...arguments); // show additional annoyance window.alert(...); } @@ -32856,11 +32525,11 @@ } } }); App.AlbumSongRoute = Ember.Route.extend({ actions: { - startPlaying: function() { + startPlaying() { // ... if (actionShouldAlsoBeTriggeredOnParentRoute) { return true; } } @@ -32883,14 +32552,14 @@ action target function returns `true`. Example ```js App.WelcomeRoute = Ember.Route.extend({ actions: { - playTheme: function() { + playTheme() { this.send('playMusic', 'theme.mp3'); }, - playMusic: function(track) { + playMusic(track) { // ... } } }); ``` @@ -32902,11 +32571,11 @@ send: function (actionName) { for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } - var target; + var target = undefined; if (this.actions && this.actions[actionName]) { var shouldBubble = this.actions[actionName].apply(this, args) === true; if (!shouldBubble) { return; @@ -32957,10 +32626,12 @@ var _Mixin$create; exports.addArrayObserver = addArrayObserver; exports.removeArrayObserver = removeArrayObserver; exports.objectAt = objectAt; + exports.arrayContentWillChange = arrayContentWillChange; + exports.arrayContentDidChange = arrayContentDidChange; exports.isEmberArray = isEmberArray; function arrayObserversHelper(obj, target, opts, operation, notify) { var willChange = opts && opts.willChange || 'arrayWillChange'; var didChange = opts && opts.didChange || 'arrayDidChange'; @@ -32994,10 +32665,104 @@ } return content[idx]; } + function arrayContentWillChange(array, startIdx, removeAmt, addAmt) { + var removing = undefined, + lim = undefined; + + // if no args are passed assume everything changes + if (startIdx === undefined) { + startIdx = 0; + removeAmt = addAmt = -1; + } else { + if (removeAmt === undefined) { + removeAmt = -1; + } + + if (addAmt === undefined) { + addAmt = -1; + } + } + + if (array.__each) { + array.__each.arrayWillChange(array, startIdx, removeAmt, addAmt); + } + + _emberMetalEvents.sendEvent(array, '@array:before', [array, startIdx, removeAmt, addAmt]); + + if (startIdx >= 0 && removeAmt >= 0 && _emberMetalProperty_get.get(array, 'hasEnumerableObservers')) { + removing = []; + lim = startIdx + removeAmt; + + for (var idx = startIdx; idx < lim; idx++) { + removing.push(objectAt(array, idx)); + } + } else { + removing = removeAmt; + } + + array.enumerableContentWillChange(removing, addAmt); + + return array; + } + + function arrayContentDidChange(array, startIdx, removeAmt, addAmt) { + _emberMetalTags.markObjectAsDirty(_emberMetalMeta.meta(array)); + + // if no args are passed assume everything changes + if (startIdx === undefined) { + startIdx = 0; + removeAmt = addAmt = -1; + } else { + if (removeAmt === undefined) { + removeAmt = -1; + } + + if (addAmt === undefined) { + addAmt = -1; + } + } + + var adding = undefined; + if (startIdx >= 0 && addAmt >= 0 && _emberMetalProperty_get.get(array, 'hasEnumerableObservers')) { + adding = []; + var lim = startIdx + addAmt; + + for (var idx = startIdx; idx < lim; idx++) { + adding.push(objectAt(array, idx)); + } + } else { + adding = addAmt; + } + + array.enumerableContentDidChange(removeAmt, adding); + + if (array.__each) { + array.__each.arrayDidChange(array, startIdx, removeAmt, addAmt); + } + + _emberMetalEvents.sendEvent(array, '@array:change', [array, startIdx, removeAmt, addAmt]); + + var length = _emberMetalProperty_get.get(array, 'length'); + var cachedFirst = _emberMetalComputed.cacheFor(array, 'firstObject'); + var cachedLast = _emberMetalComputed.cacheFor(array, 'lastObject'); + + if (objectAt(array, 0) !== cachedFirst) { + _emberMetalProperty_events.propertyWillChange(array, 'firstObject'); + _emberMetalProperty_events.propertyDidChange(array, 'firstObject'); + } + + if (objectAt(array, length - 1) !== cachedLast) { + _emberMetalProperty_events.propertyWillChange(array, 'lastObject'); + _emberMetalProperty_events.propertyDidChange(array, 'lastObject'); + } + + return array; + } + var EMBER_ARRAY = _emberMetalSymbol.default('EMBER_ARRAY'); function isEmberArray(obj) { return obj && !!obj[EMBER_ARRAY]; } @@ -33067,11 +32832,11 @@ }), _Mixin$create.firstObject = _emberMetalComputed.computed(function () { return objectAt(this, 0); }).readOnly(), _Mixin$create.lastObject = _emberMetalComputed.computed(function () { return objectAt(this, _emberMetalProperty_get.get(this, 'length') - 1); }).readOnly(), _Mixin$create.contains = function (obj) { - if (false) {} + if (true) {} return this.indexOf(obj) >= 0; }, _Mixin$create.slice = function (beginIndex, endIndex) { var ret = _emberMetalCore.default.A(); var length = _emberMetalProperty_get.get(this, 'length'); @@ -33097,40 +32862,38 @@ } return ret; }, _Mixin$create.indexOf = function (object, startAt) { var len = _emberMetalProperty_get.get(this, 'length'); - var idx; if (startAt === undefined) { startAt = 0; } if (startAt < 0) { startAt += len; } - for (idx = startAt; idx < len; idx++) { + for (var idx = startAt; idx < len; idx++) { if (objectAt(this, idx) === object) { return idx; } } return -1; }, _Mixin$create.lastIndexOf = function (object, startAt) { var len = _emberMetalProperty_get.get(this, 'length'); - var idx; if (startAt === undefined || startAt >= len) { startAt = len - 1; } if (startAt < 0) { startAt += len; } - for (idx = startAt; idx >= 0; idx--) { + for (var idx = startAt; idx >= 0; idx--) { if (objectAt(this, idx) === object) { return idx; } } @@ -33140,109 +32903,23 @@ }, _Mixin$create.removeArrayObserver = function (target, opts) { return removeArrayObserver(this, target, opts); }, _Mixin$create.hasArrayObservers = _emberMetalComputed.computed(function () { return _emberMetalEvents.hasListeners(this, '@array:change') || _emberMetalEvents.hasListeners(this, '@array:before'); }), _Mixin$create.arrayContentWillChange = function (startIdx, removeAmt, addAmt) { - var removing, lim; - - // if no args are passed assume everything changes - if (startIdx === undefined) { - startIdx = 0; - removeAmt = addAmt = -1; - } else { - if (removeAmt === undefined) { - removeAmt = -1; - } - - if (addAmt === undefined) { - addAmt = -1; - } - } - - if (this.__each) { - this.__each.arrayWillChange(this, startIdx, removeAmt, addAmt); - } - - _emberMetalEvents.sendEvent(this, '@array:before', [this, startIdx, removeAmt, addAmt]); - - if (startIdx >= 0 && removeAmt >= 0 && _emberMetalProperty_get.get(this, 'hasEnumerableObservers')) { - removing = []; - lim = startIdx + removeAmt; - - for (var idx = startIdx; idx < lim; idx++) { - removing.push(objectAt(this, idx)); - } - } else { - removing = removeAmt; - } - - this.enumerableContentWillChange(removing, addAmt); - - return this; + return arrayContentWillChange(this, startIdx, removeAmt, addAmt); }, _Mixin$create.arrayContentDidChange = function (startIdx, removeAmt, addAmt) { - var adding, lim; - - _emberMetalTags.markObjectAsDirty(_emberMetalMeta.meta(this)); - - // if no args are passed assume everything changes - if (startIdx === undefined) { - startIdx = 0; - removeAmt = addAmt = -1; - } else { - if (removeAmt === undefined) { - removeAmt = -1; - } - - if (addAmt === undefined) { - addAmt = -1; - } - } - - if (startIdx >= 0 && addAmt >= 0 && _emberMetalProperty_get.get(this, 'hasEnumerableObservers')) { - adding = []; - lim = startIdx + addAmt; - - for (var idx = startIdx; idx < lim; idx++) { - adding.push(objectAt(this, idx)); - } - } else { - adding = addAmt; - } - - this.enumerableContentDidChange(removeAmt, adding); - - if (this.__each) { - this.__each.arrayDidChange(this, startIdx, removeAmt, addAmt); - } - - _emberMetalEvents.sendEvent(this, '@array:change', [this, startIdx, removeAmt, addAmt]); - - var length = _emberMetalProperty_get.get(this, 'length'); - var cachedFirst = _emberMetalComputed.cacheFor(this, 'firstObject'); - var cachedLast = _emberMetalComputed.cacheFor(this, 'lastObject'); - - if (objectAt(this, 0) !== cachedFirst) { - _emberMetalProperty_events.propertyWillChange(this, 'firstObject'); - _emberMetalProperty_events.propertyDidChange(this, 'firstObject'); - } - - if (objectAt(this, length - 1) !== cachedLast) { - _emberMetalProperty_events.propertyWillChange(this, 'lastObject'); - _emberMetalProperty_events.propertyDidChange(this, 'lastObject'); - } - - return this; + return arrayContentDidChange(this, startIdx, removeAmt, addAmt); }, _Mixin$create['@each'] = _emberMetalComputed.computed(function () { // TODO use Symbol or add to meta if (!this.__each) { this.__each = new _emberRuntimeSystemEach_proxy.default(this); } return this.__each; }).volatile(), _Mixin$create)); - if (false) { + if (true) { ArrayMixin.reopen({ /** Returns `true` if the passed object can be found in the array. This method is a Polyfill for ES 2016 Array.includes. If no `startAt` argument is given, the starting location to @@ -33264,22 +32941,21 @@ @return {Boolean} `true` if object is found in the array. @public */ includes: function (obj, startAt) { var len = _emberMetalProperty_get.get(this, 'length'); - var idx, currentObj; if (startAt === undefined) { startAt = 0; } if (startAt < 0) { startAt += len; } - for (idx = startAt; idx < len; idx++) { - currentObj = objectAt(this, idx); + for (var idx = startAt; idx < len; idx++) { + var currentObj = objectAt(this, idx); // SameValueZero comparison (NaN !== NaN) if (obj === currentObj || obj !== obj && currentObj !== currentObj) { return true; } @@ -33308,11 +32984,11 @@ This is one of the primitives you must implement to support `Ember.Array`. If your object supports retrieving the value of an array item using `get()` (i.e. `myArray.get(0)`), then you do not need to implement this method yourself. ```javascript - var arr = ['a', 'b', 'c', 'd']; + let arr = ['a', 'b', 'c', 'd']; arr.objectAt(0); // 'a' arr.objectAt(3); // 'd' arr.objectAt(-1); // undefined arr.objectAt(4); // undefined arr.objectAt(5); // undefined @@ -33324,11 +33000,11 @@ */ /** This returns the objects at the specified indexes, using `objectAt`. ```javascript - var arr = ['a', 'b', 'c', 'd']; + let arr = ['a', 'b', 'c', 'd']; arr.objectsAt([0, 1, 2]); // ['a', 'b', 'c'] arr.objectsAt([2, 3, 4]); // ['c', 'd', undefined] ``` @method objectsAt @param {Array} indexes An array of indexes of items to return. @@ -33354,11 +33030,11 @@ /** Returns a new array that is a slice of the receiver. This implementation uses the observable array methods to retrieve the objects for the new slice. ```javascript - var arr = ['red', 'green', 'blue']; + let arr = ['red', 'green', 'blue']; arr.slice(0); // ['red', 'green', 'blue'] arr.slice(0, 2); // ['red', 'green'] arr.slice(1, 100); // ['green', 'blue'] ``` @method slice @@ -33372,11 +33048,11 @@ Returns the index of the given object's first occurrence. If no `startAt` argument is given, the starting location to search is 0. If it's negative, will count backward from the end of the array. Returns -1 if no match is found. ```javascript - var arr = ['a', 'b', 'c', 'd', 'a']; + let arr = ['a', 'b', 'c', 'd', 'a']; arr.indexOf('a'); // 0 arr.indexOf('z'); // -1 arr.indexOf('a', 2); // 4 arr.indexOf('a', -1); // 4 arr.indexOf('b', 3); // -1 @@ -33393,11 +33069,11 @@ Returns the index of the given object's last occurrence. If no `startAt` argument is given, the search starts from the last position. If it's negative, will count backward from the end of the array. Returns -1 if no match is found. ```javascript - var arr = ['a', 'b', 'c', 'd', 'a']; + let arr = ['a', 'b', 'c', 'd', 'a']; arr.lastIndexOf('a'); // 4 arr.lastIndexOf('z'); // -1 arr.lastIndexOf('a', 2); // 0 arr.lastIndexOf('a', -1); // 4 arr.lastIndexOf('b', 3); // 1 @@ -33591,27 +33267,27 @@ Given a fullName return a corresponding instance. The default behaviour is for lookup to return a singleton instance. The singleton is scoped to the container, allowing multiple containers to all have their own locally scoped singletons. ```javascript - var registry = new Registry(); - var container = registry.container(); + let registry = new Registry(); + let container = registry.container(); registry.register('api:twitter', Twitter); - var twitter = container.lookup('api:twitter'); + let twitter = container.lookup('api:twitter'); twitter instanceof Twitter; // => true // by default the container will return singletons - var twitter2 = container.lookup('api:twitter'); + let twitter2 = container.lookup('api:twitter'); twitter2 instanceof Twitter; // => true twitter === twitter2; //=> true ``` If singletons are not wanted an optional flag can be provided at lookup. ```javascript - var registry = new Registry(); - var container = registry.container(); + let registry = new Registry(); + let container = registry.container(); registry.register('api:twitter', Twitter); - var twitter = container.lookup('api:twitter', { singleton: false }); - var twitter2 = container.lookup('api:twitter', { singleton: false }); + let twitter = container.lookup('api:twitter', { singleton: false }); + let twitter2 = container.lookup('api:twitter', { singleton: false }); twitter === twitter2; //=> false ``` @public @method lookup @param {String} fullName @@ -33632,10 +33308,24 @@ _lookupFactory: function (fullName, options) { return this.__container__.lookupFactory(fullName, options); }, /** + Given a name and a source path, resolve the fullName + @private + @method _resolveLocalLookupName + @param {String} fullName + @param {String} source + @return {String} + */ + _resolveLocalLookupName: function (name, source) { + return this.__container__.registry.expandLocalLookup('component:' + name, { + source: source + }); + }, + + /** @private */ willDestroy: function () { this._super.apply(this, arguments); @@ -33691,12 +33381,10 @@ @default null @public */ target: null, - parentController: null, - store: null, /** The controller's current model. When retrieving or modifying a controller's model, this property should be used instead of the `content` property. @@ -33929,13 +33617,13 @@ If you override this method, you should implement it so that it will always return the same value each time it is called. If your enumerable contains only one object, this method should always return that object. If your enumerable is empty, this method should return `undefined`. ```javascript - var arr = ['a', 'b', 'c']; + let arr = ['a', 'b', 'c']; arr.get('firstObject'); // 'a' - var arr = []; + let arr = []; arr.get('firstObject'); // undefined ``` @property firstObject @return {Object} the object or undefined @readOnly @@ -33958,13 +33646,13 @@ /** Helper method returns the last object from a collection. If your enumerable contains only one object, this method should always return that object. If your enumerable is empty, this method should return `undefined`. ```javascript - var arr = ['a', 'b', 'c']; + let arr = ['a', 'b', 'c']; arr.get('lastObject'); // 'c' - var arr = []; + let arr = []; arr.get('lastObject'); // undefined ``` @property lastObject @return {Object} the last object or undefined @readOnly @@ -33978,11 +33666,11 @@ } var context = popCtx(); var idx = 0; var last = null; - var cur; + var cur = undefined; do { last = cur; cur = this.nextObject(idx++, last, context); } while (cur !== undefined); @@ -33995,21 +33683,22 @@ /** Returns `true` if the passed object can be found in the receiver. The default version will iterate through the enumerable until the object is found. You may want to override this with a more efficient version. ```javascript - var arr = ['a', 'b', 'c']; + let arr = ['a', 'b', 'c']; arr.contains('a'); // true arr.contains('z'); // false ``` @method contains + @deprecated Use `Enumerable#includes` instead. See http://emberjs.com/deprecations/v2.x#toc_enumerable-contains @param {Object} obj The object to search for. @return {Boolean} `true` if object is found in enumerable. @public */ contains: function (obj) { - if (false) {} + if (true) {} var found = this.find(function (item) { return item === obj; }); @@ -34071,22 +33760,22 @@ */ getEach: _emberMetalMixin.aliasMethod('mapBy'), /** Sets the value on the named property for each member. This is more - ergonomic than using other methods defined on this helper. If the object + efficient than using other methods defined on this helper. If the object implements Ember.Observable, the value will be changed to `set(),` otherwise it will be set directly. `null` objects are skipped. @method setEach @param {String} key The key to set @param {Object} value The object to set @return {Object} receiver @public */ setEach: function (key, value) { return this.forEach(function (item) { - _emberMetalProperty_set.set(item, key, value); + return _emberMetalProperty_set.set(item, key, value); }); }, /** Maps all of the items in the enumeration to another value, returning @@ -34111,11 +33800,11 @@ */ map: function (callback, target) { var ret = emberA(); this.forEach(function (x, idx, i) { - ret[idx] = callback.call(target, x, idx, i); + return ret[idx] = callback.call(target, x, idx, i); }); return ret; }, @@ -34221,15 +33910,13 @@ */ rejectBy: function (key, value) { var exactValue = function (item) { return _emberMetalProperty_get.get(item, key) === value; }; - var hasValue = function (item) { return !!_emberMetalProperty_get.get(item, key); }; - var use = arguments.length === 2 ? exactValue : hasValue; return this.reject(use); }, @@ -34264,11 +33951,12 @@ } var context = popCtx(); var found = false; var last = null; - var next, ret; + var next = undefined, + ret = undefined; for (var idx = 0; idx < len && !found; idx++) { next = this.nextObject(idx, last, context); if (found = callback.call(target, next, idx, this)) { @@ -34378,17 +34066,17 @@ any: function (callback, target) { var len = _emberMetalProperty_get.get(this, 'length'); var context = popCtx(); var found = false; var last = null; - var next, idx; + var next = undefined; if (target === undefined) { target = null; } - for (idx = 0; idx < len && !found; idx++) { + for (var idx = 0; idx < len && !found; idx++) { next = this.nextObject(idx, last, context); found = callback.call(target, next, idx, this); last = next; } @@ -34490,20 +34178,20 @@ */ toArray: function () { var ret = emberA(); this.forEach(function (o, idx) { - ret[idx] = o; + return ret[idx] = o; }); return ret; }, /** Returns a copy of the array with all `null` and `undefined` elements removed. ```javascript - var arr = ['a', null, 'c', undefined]; + let arr = ['a', null, 'c', undefined]; arr.compact(); // ['a', 'c'] ``` @method compact @return {Array} the array without null and undefined elements. @public @@ -34517,11 +34205,11 @@ /** Returns a new enumerable that excludes the passed value. The default implementation returns an array regardless of the receiver type. If the receiver does not contain the value it returns the original enumerable. ```javascript - var arr = ['a', 'b', 'a', 'c']; + let arr = ['a', 'b', 'a', 'c']; arr.without('a'); // ['b', 'c'] ``` @method without @param {Object} value @return {Ember.Enumerable} @@ -34545,11 +34233,11 @@ /** Returns a new enumerable that contains only unique values. The default implementation returns an array regardless of the receiver type. ```javascript - var arr = ['a', 'a', 'b', 'b']; + let 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} @@ -34665,11 +34353,13 @@ added or the number of items to be added. @chainable @private */ enumerableContentWillChange: function (removing, adding) { - var removeCnt, addCnt, hasDelta; + var removeCnt = undefined, + addCnt = undefined, + hasDelta = undefined; if ('number' === typeof removing) { removeCnt = removing; } else if (removing) { removeCnt = _emberMetalProperty_get.get(removing, 'length'); @@ -34719,11 +34409,13 @@ be added or the number of items to be added. @chainable @private */ enumerableContentDidChange: function (removing, adding) { - var removeCnt, addCnt, hasDelta; + var removeCnt = undefined, + addCnt = undefined, + hasDelta = undefined; if ('number' === typeof removing) { removeCnt = removing; } else if (removing) { removeCnt = _emberMetalProperty_get.get(removing, 'length'); @@ -34794,11 +34486,11 @@ Enumerable.reopen({ /** Returns a new enumerable that contains only items containing a unique property value. The default implementation returns an array regardless of the receiver type. ```javascript - var arr = [{ value: 'a' }, { value: 'a' }, { value: 'b' }, { value: 'b' }]; + let arr = [{ value: 'a' }, { value: 'a' }, { value: 'b' }, { value: 'b' }]; arr.uniqBy('value'); // [{ value: 'a' }, { value: 'b' }] ``` @method uniqBy @return {Ember.Enumerable} @public @@ -34819,11 +34511,11 @@ return ret; } }); } - if (false) { + if (true) { Enumerable.reopen({ /** Returns `true` if the passed object can be found in the enumerable. ```javascript [1, 2, 3].includes(2); // true @@ -34838,11 +34530,12 @@ @public */ includes: function (obj) { var len = _emberMetalProperty_get.get(this, 'length'); - var idx, next; + var idx = undefined, + next = undefined; var last = null; var found = false; var context = popCtx(); @@ -35140,17 +34833,35 @@ // CONSTANTS // 'use strict'; + exports.removeAt = removeAt; var OUT_OF_RANGE_EXCEPTION = 'Index out of range'; var EMPTY = []; // .......................................................... // HELPERS // + function removeAt(array, start, len) { + if ('number' === typeof start) { + if (start < 0 || start >= _emberMetalProperty_get.get(array, 'length')) { + throw new _emberMetalError.default(OUT_OF_RANGE_EXCEPTION); + } + + // fast case + if (len === undefined) { + len = 1; + } + + array.replace(start, len, EMPTY); + } + + return array; + } + /** 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. It builds upon the Array mixin and adds methods to modify the array. One concrete implementations of this class include ArrayProxy. @@ -35190,11 +34901,11 @@ /** Remove all elements from the array. This is useful if you want to reuse an existing array without having to recreate it. ```javascript - var colors = ['red', 'green', 'blue']; + let colors = ['red', 'green', 'blue']; color.length(); // 3 colors.clear(); // [] colors.length(); // 0 ``` @method clear @@ -35213,11 +34924,11 @@ /** This will use the primitive `replace()` method to insert an object at the specified index. ```javascript - var colors = ['red', 'green', 'blue']; + let colors = ['red', 'green', 'blue']; colors.insertAt(2, 'yellow'); // ['red', 'green', 'yellow', 'blue'] colors.insertAt(5, 'orange'); // Error: Index out of range ``` @method insertAt @param {Number} idx index of insert the object at. @@ -35238,11 +34949,11 @@ Remove an object at the specified index using the `replace()` primitive method. You can pass either a single index, or a start and a length. If you pass a start and length that is beyond the length this method will throw an `OUT_OF_RANGE_EXCEPTION`. ```javascript - var colors = ['red', 'green', 'blue', 'yellow', 'orange']; + let colors = ['red', 'green', 'blue', 'yellow', 'orange']; colors.removeAt(0); // ['green', 'blue', 'yellow', 'orange'] colors.removeAt(2, 2); // ['green', 'blue'] colors.removeAt(4, 2); // Error: Index out of range ``` @method removeAt @@ -35250,31 +34961,18 @@ @param {Number} len length of passing range @return {Ember.Array} receiver @public */ removeAt: function (start, len) { - if ('number' === typeof start) { - if (start < 0 || start >= _emberMetalProperty_get.get(this, 'length')) { - throw new _emberMetalError.default(OUT_OF_RANGE_EXCEPTION); - } - - // fast case - if (len === undefined) { - len = 1; - } - - this.replace(start, len, EMPTY); - } - - return this; + return removeAt(this, start, len); }, /** Push the object onto the end of the array. Works just like `push()` but it is KVO-compliant. ```javascript - var colors = ['red', 'green']; + let colors = ['red', 'green']; colors.pushObject('black'); // ['red', 'green', 'black'] colors.pushObject(['yellow']); // ['red', 'green', ['yellow']] ``` @method pushObject @param {*} obj object to push @@ -35288,11 +34986,11 @@ /** Add the objects in the passed numerable to the end of the array. Defers notifying observers of the change until all objects are added. ```javascript - var colors = ['red']; + let colors = ['red']; colors.pushObjects(['yellow', 'orange']); // ['red', 'yellow', 'orange'] ``` @method pushObjects @param {Ember.Enumerable} objects the objects to add @return {Ember.Array} receiver @@ -35308,11 +35006,11 @@ /** Pop object from array or nil if none are left. Works just like `pop()` but it is KVO-compliant. ```javascript - var colors = ['red', 'green', 'blue']; + let colors = ['red', 'green', 'blue']; colors.popObject(); // 'blue' console.log(colors); // ['red', 'green'] ``` @method popObject @return object @@ -35331,11 +35029,11 @@ /** Shift an object from start of array or nil if none are left. Works just like `shift()` but it is KVO-compliant. ```javascript - var colors = ['red', 'green', 'blue']; + let colors = ['red', 'green', 'blue']; colors.shiftObject(); // 'red' console.log(colors); // ['green', 'blue'] ``` @method shiftObject @return object @@ -35353,11 +35051,11 @@ /** Unshift an object to start of array. Works just like `unshift()` but it is KVO-compliant. ```javascript - var colors = ['red']; + let colors = ['red']; colors.unshiftObject('yellow'); // ['yellow', 'red'] colors.unshiftObject(['black']); // [['black'], 'yellow', 'red'] ``` @method unshiftObject @param {*} obj object to unshift @@ -35371,11 +35069,11 @@ /** Adds the named objects to the beginning of the array. Defers notifying observers until all objects have been added. ```javascript - var colors = ['red']; + let colors = ['red']; colors.unshiftObjects(['black', 'white']); // ['black', 'white', 'red'] colors.unshiftObjects('yellow'); // Type Error: 'undefined' is not a function ``` @method unshiftObjects @param {Ember.Enumerable} objects the objects to add @@ -35407,11 +35105,11 @@ /** Replace all the receiver's content with content of the argument. If argument is an empty array receiver will be cleared. ```javascript - var colors = ['red', 'green', 'blue']; + let colors = ['red', 'green', 'blue']; colors.setObjects(['black', 'white']); // ['black', 'white'] colors.setObjects([]); // [] ``` @method setObjects @param {Ember.Array} objects array whose content will be used for replacing @@ -35434,11 +35132,11 @@ // /** Remove all occurrences of an object in the array. ```javascript - var cities = ['Chicago', 'Berlin', 'Lima', 'Chicago']; + let cities = ['Chicago', 'Berlin', 'Lima', 'Chicago']; cities.removeObject('Chicago'); // ['Berlin', 'Lima'] cities.removeObject('Lima'); // ['Berlin'] cities.removeObject('Tokyo') // ['Berlin'] ``` @method removeObject @@ -35460,23 +35158,23 @@ /** Push the object onto the end of the array if it is not already present in the array. ```javascript - var cities = ['Chicago', 'Berlin']; + let cities = ['Chicago', 'Berlin']; cities.addObject('Lima'); // ['Chicago', 'Berlin', 'Lima'] cities.addObject('Berlin'); // ['Chicago', 'Berlin', 'Lima'] ``` @method addObject @param {*} obj object to add, if not already present @return {Ember.Array} receiver @public */ addObject: function (obj) { - var included; + var included = undefined; - if (false) { + if (true) { included = this.includes(obj); } else { included = this.contains(obj); } @@ -36072,14 +35770,14 @@ /** A low level mixin making ObjectProxy promise-aware. ```javascript - var ObjectPromiseProxy = Ember.ObjectProxy.extend(Ember.PromiseProxyMixin); + let ObjectPromiseProxy = Ember.ObjectProxy.extend(Ember.PromiseProxyMixin); - var proxy = ObjectPromiseProxy.create({ - promise: $.getJSON('/some/remote/data.json') + let proxy = ObjectPromiseProxy.create({ + promise: Ember.RSVP.cast($.getJSON('/some/remote/data.json')) }); proxy.then(function(json){ // the json }, function(reason) { @@ -36097,10 +35795,13 @@ proxy.get('isFulfilled') //=> false ``` When the $.getJSON completes, and the promise is fulfilled with json, the life cycle attributes will update accordingly. + Note that $.getJSON doesn't return an ECMA specified promise, + it is useful to wrap this with an `RSVP.cast` so that it behaves + as a spec compliant promise. ```javascript proxy.get('isPending') //=> false proxy.get('isSettled') //=> true proxy.get('isRejected') //=> false @@ -36263,21 +35964,21 @@ Registers a factory that can be used for dependency injection (with `inject`) or for service lookup. Each factory is registered with a full name including two parts: `type:name`. A simple example: ```javascript - var App = Ember.Application.create(); + let App = Ember.Application.create(); App.Orange = Ember.Object.extend(); App.register('fruit:favorite', App.Orange); ``` Ember will resolve factories from the `App` namespace automatically. For example `App.CarsController` will be discovered and returned if an application requests `controller:cars`. An example of registering a controller with a non-standard name: ```javascript - var App = Ember.Application.create(); - var Session = Ember.Controller.extend(); + let App = Ember.Application.create(); + let Session = Ember.Controller.extend(); App.register('controller:session', Session); // The Session controller can now be treated like a normal controller, // despite its non-standard name. App.ApplicationController = Ember.Controller.extend({ needs: ['session'] @@ -36286,11 +35987,11 @@ Registered factories are **instantiated** by having `create` called on them. Additionally they are **singletons**, each time they are looked up they return the same instance. Some examples modifying that default behavior: ```javascript - var App = Ember.Application.create(); + let App = Ember.Application.create(); App.Person = Ember.Object.extend(); App.Orange = Ember.Object.extend(); App.Email = Ember.Object.extend(); App.session = Ember.Object.create(); App.register('model:user', App.Person, { singleton: false }); @@ -36307,12 +36008,12 @@ register: registryAlias('register'), /** Unregister a factory. ```javascript - var App = Ember.Application.create(); - var User = Ember.Object.extend(); + let App = Ember.Application.create(); + let User = Ember.Object.extend(); App.register('model:user', User); App.resolveRegistration('model:user').create() instanceof User //=> true App.unregister('model:user') App.resolveRegistration('model:user') === undefined //=> true ``` @@ -36370,21 +36071,21 @@ registeredOptions: registryAlias('getOptions'), /** Allow registering options for all factories of a type. ```javascript - var App = Ember.Application.create(); - var appInstance = App.buildInstance(); + let App = Ember.Application.create(); + let appInstance = App.buildInstance(); // if all of type `connection` must not be singletons appInstance.optionsForType('connection', { singleton: false }); appInstance.register('connection:twitter', TwitterConnection); appInstance.register('connection:facebook', FacebookConnection); - var twitter = appInstance.lookup('connection:twitter'); - var twitter2 = appInstance.lookup('connection:twitter'); + let twitter = appInstance.lookup('connection:twitter'); + let twitter2 = appInstance.lookup('connection:twitter'); twitter === twitter2; // => false - var facebook = appInstance.lookup('connection:facebook'); - var facebook2 = appInstance.lookup('connection:facebook'); + let facebook = appInstance.lookup('connection:facebook'); + let facebook2 = appInstance.lookup('connection:facebook'); facebook === facebook2; // => false ``` @public @method registerOptionsForType @param {String} type @@ -36407,12 +36108,12 @@ When Ember instantiates a controller, view, or other framework component it can attach a dependency to that component. This is often used to provide services to a set of framework components. An example of providing a session object to all controllers: ```javascript - var App = Ember.Application.create(); - var Session = Ember.Object.extend({ isAuthenticated: false }); + let App = Ember.Application.create(); + let Session = Ember.Object.extend({ isAuthenticated: false }); // A factory must be registered before it can be injected App.register('session:main', Session); // Inject 'session:main' onto all factories of the type 'controller' // with the name 'session' App.inject('controller', 'session', 'session:main'); @@ -36500,35 +36201,16 @@ @class TargetActionSupport @namespace Ember @extends Ember.Mixin @private */ - var TargetActionSupport = _emberMetalMixin.Mixin.create({ + exports.default = _emberMetalMixin.Mixin.create({ target: null, action: null, actionContext: null, - targetObject: _emberMetalComputed.computed('target', function () { - if (this._targetObject) { - return this._targetObject; - } - - var target = _emberMetalProperty_get.get(this, 'target'); - - if (typeof target === 'string') { - var value = _emberMetalProperty_get.get(this, target); - if (value === undefined) { - value = _emberMetalProperty_get.get(_emberEnvironment.context.lookup, target); - } - - return value; - } else { - return target; - } - }), - - actionContextObject: _emberMetalComputed.computed(function () { + actionContextObject: _emberMetalComputed.computed('actionContext', function () { var actionContext = _emberMetalProperty_get.get(this, 'actionContext'); if (typeof actionContext === 'string') { var value = _emberMetalProperty_get.get(this, actionContext); if (value === undefined) { @@ -36536,31 +36218,31 @@ } return value; } else { return actionContext; } - }).property('actionContext'), + }), /** Send an `action` with an `actionContext` to a `target`. The action, actionContext and target will be retrieved from properties of the object. For example: ```javascript App.SaveButtonView = Ember.View.extend(Ember.TargetActionSupport, { target: Ember.computed.alias('controller'), action: 'save', actionContext: Ember.computed.alias('context'), - click: function() { + click() { this.triggerAction(); // Sends the `save` action, along with the current context // to the current controller } }); ``` The `target`, `action`, and `actionContext` can be provided as properties of an optional object argument to `triggerAction` as well. ```javascript App.SaveButtonView = Ember.View.extend(Ember.TargetActionSupport, { - click: function() { + click() { this.triggerAction({ action: 'save', target: this.get('controller'), actionContext: this.get('context') }); // Sends the `save` action, along with the current context @@ -36572,11 +36254,11 @@ But `target` and `action` must be specified either as properties or with the argument to `triggerAction`, or a combination: ```javascript App.SaveButtonView = Ember.View.extend(Ember.TargetActionSupport, { target: Ember.computed.alias('controller'), - click: function() { + click() { this.triggerAction({ action: 'save' }); // Sends the `save` action, along with a reference to `this`, // to the current controller } @@ -36589,11 +36271,16 @@ */ triggerAction: function () { var opts = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; var action = opts.action || _emberMetalProperty_get.get(this, 'action'); - var target = opts.target || _emberMetalProperty_get.get(this, 'targetObject'); + var target = opts.target; + + if (!target) { + target = getTarget(this); + } + var actionContext = opts.actionContext; function args(options, actionName) { var ret = []; if (actionName) { @@ -36606,11 +36293,11 @@ if (typeof actionContext === 'undefined') { actionContext = _emberMetalProperty_get.get(this, 'actionContextObject') || this; } if (target && action) { - var ret; + var ret = undefined; if (target.send) { ret = target.send.apply(target, args(actionContext, action)); } else { ret = target[action].apply(target, args(actionContext)); @@ -36625,11 +36312,40 @@ return false; } } }); - exports.default = TargetActionSupport; + function getTarget(instance) { + // TODO: Deprecate specifying `targetObject` + var target = _emberMetalProperty_get.get(instance, 'targetObject'); + + // if a `targetObject` CP was provided, use it + if (target) { + return target; + } + + // if _targetObject use it + if (instance._targetObject) { + return instance._targetObject; + } + + target = _emberMetalProperty_get.get(instance, 'target'); + if (target) { + if (typeof target === 'string') { + var value = _emberMetalProperty_get.get(instance, target); + if (value === undefined) { + value = _emberMetalProperty_get.get(_emberEnvironment.context.lookup, target); + } + + return value; + } else { + return target; + } + } + + return null; + } }); enifed("ember-runtime/string_registry", ["exports"], function (exports) { // STATE within a module is frowned apon, this exists // to support Ember.STRINGS but shield ember internals from this legacy global // API. @@ -36679,12 +36395,12 @@ out the underlying array is useful. A simple example of usage: ```javascript - var pets = ['dog', 'cat', 'fish']; - var ap = Ember.ArrayProxy.create({ content: Ember.A(pets) }); + let pets = ['dog', 'cat', 'fish']; + let ap = Ember.ArrayProxy.create({ content: Ember.A(pets) }); ap.get('firstObject'); // 'dog' ap.set('content', ['amoeba', 'paramecium']); ap.get('firstObject'); // 'amoeba' ``` @@ -36692,12 +36408,12 @@ This class can also be useful as a layer to transform the contents of an array, as they are accessed. This can be done by overriding `objectAtContent`: ```javascript - var pets = ['dog', 'cat', 'fish']; - var ap = Ember.ArrayProxy.create({ + let pets = ['dog', 'cat', 'fish']; + let ap = Ember.ArrayProxy.create({ content: Ember.A(pets), objectAtContent: function(idx) { return this.get('content').objectAt(idx).toUpperCase(); } }); @@ -36709,11 +36425,11 @@ @namespace Ember @extends Ember.Object @uses Ember.MutableArray @public */ - var ArrayProxy = _emberRuntimeSystemObject.default.extend(_emberRuntimeMixinsMutable_array.default, { + exports.default = _emberRuntimeSystemObject.default.extend(_emberRuntimeMixinsMutable_array.default, { /** The content array. Must be an object that implements `Ember.Array` and/or `Ember.MutableArray.` @property content @@ -36922,33 +36638,32 @@ removeAt: function (start, len) { if ('number' === typeof start) { var content = _emberMetalProperty_get.get(this, 'content'); var arrangedContent = _emberMetalProperty_get.get(this, 'arrangedContent'); var indices = []; - var i; if (start < 0 || start >= _emberMetalProperty_get.get(this, 'length')) { throw new _emberMetalError.default(OUT_OF_RANGE_EXCEPTION); } if (len === undefined) { len = 1; } // Get a list of indices in original content to remove - for (i = start; i < start + len; i++) { + for (var i = start; i < start + len; i++) { // Use arrangedContent here so we avoid confusion with objects transformed by objectAtContent indices.push(content.indexOf(_emberRuntimeMixinsArray.objectAt(arrangedContent, i))); } // Replace in reverse order since indices will change indices.sort(function (a, b) { return b - a; }); _emberMetalProperty_events.beginPropertyChanges(); - for (i = 0; i < indices.length; i++) { + for (var i = 0; i < indices.length; i++) { this._replace(indices[i], 1, EMPTY); } _emberMetalProperty_events.endPropertyChanges(); } @@ -36992,15 +36707,15 @@ var arr = this.toArray(); return arr.slice.apply(arr, arguments); }, arrangedContentArrayWillChange: function (item, idx, removedCnt, addedCnt) { - this.arrayContentWillChange(idx, removedCnt, addedCnt); + _emberRuntimeMixinsArray.arrayContentWillChange(this, idx, removedCnt, addedCnt); }, arrangedContentArrayDidChange: function (item, idx, removedCnt, addedCnt) { - this.arrayContentDidChange(idx, removedCnt, addedCnt); + _emberRuntimeMixinsArray.arrayContentDidChange(this, idx, removedCnt, addedCnt); }, init: function () { this._super.apply(this, arguments); this._setupContent(); @@ -37010,12 +36725,10 @@ willDestroy: function () { this._teardownArrangedContent(); this._teardownContent(); } }); - - exports.default = ArrayProxy; }); enifed('ember-runtime/system/container', ['exports', 'ember-metal/property_set', 'container/registry', 'container/container', 'container/owner'], function (exports, _emberMetalProperty_set, _containerRegistry, _containerContainer, _containerOwner) { 'use strict'; _containerRegistry.default.set = _emberMetalProperty_set.set; @@ -37093,11 +36806,11 @@ for (var j = 0; j < keyNames.length; j++) { var keyName = keyNames[j]; var value = properties[keyName]; - if (_emberMetalMixin.IS_BINDING.test(keyName)) { + if (_emberMetalMixin.detectBinding(keyName)) { m.writeBindings(keyName, value); } var possibleDesc = this[keyName]; var desc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined; @@ -37834,17 +37547,20 @@ @method _onLookup */ enifed('ember-runtime/system/each_proxy', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/observer', 'ember-metal/property_events', 'ember-metal/empty_object', 'ember-runtime/mixins/array'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalObserver, _emberMetalProperty_events, _emberMetalEmpty_object, _emberRuntimeMixinsArray) { 'use strict'; + exports.default = EachProxy; + /** This is the object instance returned when you get the `@each` property on an array. It uses the unknownProperty handler to automatically create EachArray instances for property names. @class EachProxy @private */ + function EachProxy(content) { this._content = content; this._keys = undefined; this.__ember_meta__ = null; } @@ -37949,12 +37665,10 @@ _emberMetalObserver._removeBeforeObserver(item, keyName, proxy, 'contentKeyWillChange'); _emberMetalObserver.removeObserver(item, keyName, proxy, 'contentKeyDidChange'); } } } - - exports.default = EachProxy; }); enifed('ember-runtime/system/lazy_load', ['exports', 'ember-environment'], function (exports, _emberEnvironment) { /*globals CustomEvent */ 'use strict'; @@ -38017,12 +37731,12 @@ function runLoadHooks(name, object) { loaded[name] = object; var window = _emberEnvironment.environment.window; if (window && typeof CustomEvent === 'function') { - var event = new CustomEvent(name, { detail: object, name: name }); - window.dispatchEvent(event); + var _event = new CustomEvent(name, { detail: object, name: name }); + window.dispatchEvent(_event); } if (loadHooks[name]) { loadHooks[name].forEach(function (callback) { return callback(object); @@ -38210,11 +37924,11 @@ function classToString() { if (!searchDisabled && !this[_emberMetalMixin.NAME_KEY]) { processAllNamespaces(); } - var ret; + var ret = undefined; if (this[_emberMetalMixin.NAME_KEY]) { ret = this[_emberMetalMixin.NAME_KEY]; } else if (this._toString) { ret = this._toString; @@ -38240,11 +37954,11 @@ Namespace.PROCESSED = true; } if (unprocessedNamespaces || unprocessedMixins) { var namespaces = Namespace.NAMESPACES; - var namespace; + var namespace = undefined; for (var i = 0; i < namespaces.length; i++) { namespace = namespaces[i]; processNamespace([namespace.toString()], namespace, {}); } @@ -38313,26 +38027,26 @@ // if we replaced exactly the same number of items, then pass only the // replaced range. Otherwise, pass the full remaining array length // since everything has shifted var len = objects ? _emberMetalProperty_get.get(objects, 'length') : 0; - this.arrayContentWillChange(idx, amt, len); + _emberRuntimeMixinsArray.arrayContentWillChange(this, idx, amt, len); if (len === 0) { this.splice(idx, amt); } else { _emberMetalReplace.default(this, idx, amt, objects); } - this.arrayContentDidChange(idx, amt, len); + _emberRuntimeMixinsArray.arrayContentDidChange(this, idx, amt, len); return this; }, // If you ask for an unknown property, then try to collect the value // from member items. unknownProperty: function (key, value) { - var ret; // = this.reducedProperty(key, value); + var ret = undefined; // = this.reducedProperty(key, value); if (value !== undefined && ret === undefined) { ret = this[key] = value; } return ret; }, @@ -38390,11 +38104,11 @@ @method A @for Ember @return {Ember.NativeArray} @public */ - var A; + var A = undefined; if (_emberEnvironment.ENV.EXTEND_PROTOTYPES.Array) { NativeArray.apply(Array.prototype); exports. // ES6TODO: Setting A onto the object returned by ember-metal/core to avoid circles A = A = function (arr) { @@ -39016,734 +38730,34 @@ } return ret; } }); -enifed('ember-template-compiler/compat', ['exports', 'ember-metal/core', 'ember-template-compiler/compiler'], function (exports, _emberMetalCore, _emberTemplateCompilerCompiler) { +enifed('ember-templates/compat', ['exports', 'ember-metal/core', 'ember-templates/template', 'ember-templates/string', 'ember-runtime/system/string', 'ember-metal/features', 'ember-templates/make-bound-helper'], function (exports, _emberMetalCore, _emberTemplatesTemplate, _emberTemplatesString, _emberRuntimeSystemString, _emberMetalFeatures, _emberTemplatesMakeBoundHelper) { 'use strict'; var EmberHandlebars = _emberMetalCore.default.Handlebars = _emberMetalCore.default.Handlebars || {}; + exports.EmberHandlebars = EmberHandlebars; var EmberHTMLBars = _emberMetalCore.default.HTMLBars = _emberMetalCore.default.HTMLBars || {}; + exports.EmberHTMLBars = EmberHTMLBars; + var EmberHandleBarsUtils = EmberHandlebars.Utils = EmberHandlebars.Utils || {}; - var _compiler = _emberTemplateCompilerCompiler.default(); + exports.EmberHandleBarsUtils = EmberHandleBarsUtils; + Object.defineProperty(EmberHandlebars, 'SafeString', { + get: _emberTemplatesString.getSafeString + }); - var precompile = _compiler.precompile; - var compile = _compiler.compile; - var template = _compiler.template; - var registerPlugin = _compiler.registerPlugin; + EmberHTMLBars.template = EmberHandlebars.template = _emberTemplatesTemplate.default; + EmberHandleBarsUtils.escapeExpression = _emberTemplatesString.escapeExpression; + _emberRuntimeSystemString.default.htmlSafe = _emberTemplatesString.htmlSafe; - EmberHTMLBars.precompile = EmberHandlebars.precompile = precompile; - EmberHTMLBars.compile = EmberHandlebars.compile = compile; - EmberHTMLBars.template = EmberHandlebars.template = template; - EmberHTMLBars.registerPlugin = registerPlugin; -}); -// reexports -enifed('ember-template-compiler/compat/precompile', ['exports', 'require', 'ember-metal/features'], function (exports, _require, _emberMetalFeatures) { - /** - @module ember - @submodule ember-template-compiler - */ - 'use strict'; - - var compile, compileSpec, compileOptions; - - // Note we don't really want to expose this from main file - if (false) { - compileOptions = _require.default('ember-glimmer-template-compiler/system/compile-options').default; - } else { - compileOptions = _require.default('ember-htmlbars-template-compiler/system/compile-options').default; + if (true) { + _emberRuntimeSystemString.default.isHTMLSafe = _emberTemplatesString.isHTMLSafe; } - - exports.default = function (string) { - if ((!compile || !compileSpec) && _require.has('htmlbars-compiler/compiler')) { - var Compiler = _require.default('htmlbars-compiler/compiler'); - - compile = Compiler.compile; - compileSpec = Compiler.compileSpec; - } - - if (!compile || !compileSpec) { - throw new Error('Cannot call `precompile` without the template compiler loaded. Please load `ember-template-compiler.js` prior to calling `precompile`.'); - } - - var asObject = arguments[1] === undefined ? true : arguments[1]; - var compileFunc = asObject ? compile : compileSpec; - - return compileFunc(string, compileOptions()); - }; + EmberHTMLBars.makeBoundHelper = _emberTemplatesMakeBoundHelper.default; }); -enifed('ember-template-compiler/compiler', ['exports', 'ember-metal/features', 'require'], function (exports, _emberMetalFeatures, _require) { - 'use strict'; - - exports.default = pickCompiler; - - function pickCompiler() { - var compiler = undefined; - if (false) { - compiler = _require.default('ember-glimmer-template-compiler'); - } else { - compiler = _require.default('ember-htmlbars-template-compiler'); - } - - return compiler; - } -}); -enifed('ember-template-compiler/index', ['exports', 'ember-template-compiler/compat', 'ember-metal', 'ember-template-compiler/system/precompile', 'ember-template-compiler/system/compile', 'ember-template-compiler/system/register-plugin', 'ember-template-compiler/system/compile-options', 'ember-template-compiler/system/template'], function (exports, _emberTemplateCompilerCompat, _emberMetal, _emberTemplateCompilerSystemPrecompile, _emberTemplateCompilerSystemCompile, _emberTemplateCompilerSystemRegisterPlugin, _emberTemplateCompilerSystemCompileOptions, _emberTemplateCompilerSystemTemplate) { - 'use strict'; - - exports._Ember = _emberMetal.default; - // Is this still needed - exports.precompile = _emberTemplateCompilerSystemPrecompile.default; - exports.compile = _emberTemplateCompilerSystemCompile.default; - exports.registerPlugin = _emberTemplateCompilerSystemRegisterPlugin.default; - exports.defaultCompileOptions = _emberTemplateCompilerSystemCompileOptions.default; - exports.template = _emberTemplateCompilerSystemTemplate.default; - - // used for adding Ember.Handlebars.compile for backwards compat -}); -enifed('ember-template-compiler/plugins/deprecate-render-model', ['exports', 'ember-metal/debug', 'ember-template-compiler/system/calculate-location-display'], function (exports, _emberMetalDebug, _emberTemplateCompilerSystemCalculateLocationDisplay) { - 'use strict'; - - exports.default = DeprecateRenderModel; - - function DeprecateRenderModel(options) { - this.syntax = null; - this.options = options; - } - - DeprecateRenderModel.prototype.transform = function DeprecateRenderModel_transform(ast) { - var moduleName = this.options.moduleName; - var walker = new this.syntax.Walker(); - - walker.visit(ast, function (node) { - if (!validate(node)) { - return; - } - - each(node.params, function (param) { - if (param.type !== 'PathExpression') { - return; - } - }); - }); - - return ast; - }; - - function validate(node) { - return node.type === 'MustacheStatement' && node.path.original === 'render' && node.params.length > 1; - } - - function each(list, callback) { - for (var i = 0, l = list.length; i < l; i++) { - callback(list[i]); - } - } - - function deprecationMessage(moduleName, node, param) { - var sourceInformation = _emberTemplateCompilerSystemCalculateLocationDisplay.default(moduleName, node.loc); - var componentName = node.params[0].original; - var modelName = param.original; - var original = '{{render "' + componentName + '" ' + modelName + '}}'; - var preferred = '{{' + componentName + ' model=' + modelName + '}}'; - - return 'Please refactor `' + original + '` to a component and invoke via' + (' `' + preferred + '`. ' + sourceInformation); - } -}); -enifed('ember-template-compiler/plugins/index', ['exports', 'ember-template-compiler/plugins/transform-old-binding-syntax', 'ember-template-compiler/plugins/transform-item-class', 'ember-template-compiler/plugins/transform-angle-bracket-components', 'ember-template-compiler/plugins/transform-input-on-to-onEvent', 'ember-template-compiler/plugins/transform-top-level-components', 'ember-template-compiler/plugins/deprecate-render-model', 'ember-template-compiler/plugins/transform-inline-link-to'], function (exports, _emberTemplateCompilerPluginsTransformOldBindingSyntax, _emberTemplateCompilerPluginsTransformItemClass, _emberTemplateCompilerPluginsTransformAngleBracketComponents, _emberTemplateCompilerPluginsTransformInputOnToOnEvent, _emberTemplateCompilerPluginsTransformTopLevelComponents, _emberTemplateCompilerPluginsDeprecateRenderModel, _emberTemplateCompilerPluginsTransformInlineLinkTo) { - 'use strict'; - - exports.default = Object.freeze([_emberTemplateCompilerPluginsTransformOldBindingSyntax.default, _emberTemplateCompilerPluginsTransformItemClass.default, _emberTemplateCompilerPluginsTransformAngleBracketComponents.default, _emberTemplateCompilerPluginsTransformInputOnToOnEvent.default, _emberTemplateCompilerPluginsTransformTopLevelComponents.default, _emberTemplateCompilerPluginsDeprecateRenderModel.default, _emberTemplateCompilerPluginsTransformInlineLinkTo.default]); -}); -enifed('ember-template-compiler/plugins/transform-angle-bracket-components', ['exports'], function (exports) { - 'use strict'; - - function TransformAngleBracketComponents() { - // set later within HTMLBars to the syntax package - this.syntax = null; - } - - /** - @private - @method transform - @param {AST} ast The AST to be transformed. - */ - TransformAngleBracketComponents.prototype.transform = function TransformAngleBracketComponents_transform(ast) { - var walker = new this.syntax.Walker(); - - walker.visit(ast, function (node) { - if (!validate(node)) { - return; - } - - node.tag = '<' + node.tag + '>'; - }); - - return ast; - }; - - function validate(node) { - return node.type === 'ComponentNode'; - } - - exports.default = TransformAngleBracketComponents; -}); -enifed('ember-template-compiler/plugins/transform-inline-link-to', ['exports'], function (exports) { - 'use strict'; - - exports.default = TransformInlineLinkTo; - - function TransformInlineLinkTo(options) { - this.options = options; - this.syntax = null; - } - - TransformInlineLinkTo.prototype.transform = function TransformInlineLinkTo_transform(ast) { - var _syntax = this.syntax; - var traverse = _syntax.traverse; - var b = _syntax.builders; - - function buildProgram(content, loc) { - return b.program([buildStatement(content, loc)], null, loc); - } - - function buildStatement(content, loc) { - switch (content.type) { - case 'PathExpression': - return b.mustache(content, null, null, null, loc); - - case 'SubExpression': - return b.mustache(content.path, content.params, content.hash, null, loc); - - // The default case handles literals. - default: - return b.text('' + content.value, loc); - } - } - - function unsafeHtml(expr) { - return b.sexpr('-html-safe', [expr]); - } - - traverse(ast, { - MustacheStatement: function (node) { - if (node.path.original === 'link-to') { - var content = node.escaped ? node.params[0] : unsafeHtml(node.params[0]); - return b.block('link-to', node.params.slice(1), node.hash, buildProgram(content, node.loc), null, node.loc); - } - } - }); - - return ast; - }; -}); -enifed('ember-template-compiler/plugins/transform-input-on-to-onEvent', ['exports', 'ember-metal/debug', 'ember-template-compiler/system/calculate-location-display'], function (exports, _emberMetalDebug, _emberTemplateCompilerSystemCalculateLocationDisplay) { - 'use strict'; - - /** - @module ember - @submodule ember-htmlbars - */ - - /** - An HTMLBars AST transformation that replaces all instances of - - ```handlebars - {{input on="enter" action="doStuff"}} - {{input on="key-press" action="doStuff"}} - ``` - - with - - ```handlebars - {{input enter="doStuff"}} - {{input key-press="doStuff"}} - ``` - - @private - @class TransformInputOnToOnEvent - */ - function TransformInputOnToOnEvent() { - var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; - - // set later within HTMLBars to the syntax package - this.syntax = null; - this.options = options; - } - - /** - @private - @method transform - @param {AST} ast The AST to be transformed. - */ - TransformInputOnToOnEvent.prototype.transform = function TransformInputOnToOnEvent_transform(ast) { - var pluginContext = this; - var b = pluginContext.syntax.builders; - var walker = new pluginContext.syntax.Walker(); - var moduleName = pluginContext.options.moduleName; - - walker.visit(ast, function (node) { - if (pluginContext.validate(node)) { - var action = hashPairForKey(node.hash, 'action'); - var on = hashPairForKey(node.hash, 'on'); - var onEvent = hashPairForKey(node.hash, 'onEvent'); - var normalizedOn = on || onEvent; - var moduleInfo = _emberTemplateCompilerSystemCalculateLocationDisplay.default(moduleName, node.loc); - - if (normalizedOn && normalizedOn.value.type !== 'StringLiteral') { - - normalizedOn.key = 'onEvent'; - return; // exit early, as we cannot transform further - } - - removeFromHash(node.hash, normalizedOn); - removeFromHash(node.hash, action); - - if (!action) { - - return; // exit early, if no action was available there is nothing to do - } - - var specifiedOn = normalizedOn ? normalizedOn.key + '="' + normalizedOn.value.value + '" ' : ''; - if (normalizedOn && normalizedOn.value.value === 'keyPress') { - // using `keyPress` in the root of the component will - // clobber the keyPress event handler - normalizedOn.value.value = 'key-press'; - } - - var expected = (normalizedOn ? normalizedOn.value.value : 'enter') + '="' + action.value.original + '"'; - - if (!normalizedOn) { - normalizedOn = b.pair('onEvent', b.string('enter')); - } - - node.hash.pairs.push(b.pair(normalizedOn.value.value, action.value)); - } - }); - - return ast; - }; - - TransformInputOnToOnEvent.prototype.validate = function TransformWithAsToHash_validate(node) { - return node.type === 'MustacheStatement' && node.path.original === 'input' && (hashPairForKey(node.hash, 'action') || hashPairForKey(node.hash, 'on') || hashPairForKey(node.hash, 'onEvent')); - }; - - function hashPairForKey(hash, key) { - for (var i = 0; i < hash.pairs.length; i++) { - var pair = hash.pairs[i]; - if (pair.key === key) { - return pair; - } - } - - return false; - } - - function removeFromHash(hash, pairToRemove) { - var newPairs = []; - for (var i = 0; i < hash.pairs.length; i++) { - var pair = hash.pairs[i]; - - if (pair !== pairToRemove) { - newPairs.push(pair); - } - } - - hash.pairs = newPairs; - } - - exports.default = TransformInputOnToOnEvent; -}); -enifed('ember-template-compiler/plugins/transform-item-class', ['exports'], function (exports) { - 'use strict'; - - exports.default = TransformItemClass; - - function TransformItemClass() { - this.syntax = null; - } - - TransformItemClass.prototype.transform = function TransformItemClass_transform(ast) { - var b = this.syntax.builders; - var walker = new this.syntax.Walker(); - - walker.visit(ast, function (node) { - if (!validate(node)) { - return; - } - - each(node.hash.pairs, function (pair) { - var key = pair.key; - var value = pair.value; - - if (key !== 'itemClass') { - return; - } - if (value.type === 'StringLiteral') { - return; - } - - var propName = value.original; - var params = [value]; - var sexprParams = [b.string(propName), b.path(propName)]; - - params.push(b.sexpr(b.string('-normalize-class'), sexprParams)); - var sexpr = b.sexpr(b.string('if'), params); - - pair.value = sexpr; - }); - }); - - return ast; - }; - - function validate(node) { - return (node.type === 'BlockStatement' || node.type === 'MustacheStatement') && node.path.original === 'collection'; - } - - function each(list, callback) { - for (var i = 0; i < list.length; i++) { - callback(list[i]); - } - } -}); -enifed('ember-template-compiler/plugins/transform-old-binding-syntax', ['exports', 'ember-metal/debug', 'ember-template-compiler/system/calculate-location-display'], function (exports, _emberMetalDebug, _emberTemplateCompilerSystemCalculateLocationDisplay) { - 'use strict'; - - exports.default = TransformOldBindingSyntax; - - function TransformOldBindingSyntax(options) { - this.syntax = null; - this.options = options; - } - - TransformOldBindingSyntax.prototype.transform = function TransformOldBindingSyntax_transform(ast) { - var moduleName = this.options.moduleName; - var b = this.syntax.builders; - var walker = new this.syntax.Walker(); - - walker.visit(ast, function (node) { - if (!validate(node)) { - return; - } - - each(node.hash.pairs, function (pair) { - var key = pair.key; - var value = pair.value; - - var sourceInformation = _emberTemplateCompilerSystemCalculateLocationDisplay.default(moduleName, pair.loc); - - if (key === 'classBinding') { - return; - } - - if (key.substr(-7) === 'Binding') { - var newKey = key.slice(0, -7); - - pair.key = newKey; - if (value.type === 'StringLiteral') { - pair.value = b.path(value.original); - } - } - }); - }); - - return ast; - }; - - function validate(node) { - return node.type === 'BlockStatement' || node.type === 'MustacheStatement'; - } - - function each(list, callback) { - for (var i = 0; i < list.length; i++) { - callback(list[i]); - } - } - - function exprToString(expr) { - switch (expr.type) { - case 'StringLiteral': - return '"' + expr.original + '"'; - case 'PathExpression': - return expr.original; - } - } -}); -enifed('ember-template-compiler/plugins/transform-top-level-components', ['exports'], function (exports) { - 'use strict'; - - function TransformTopLevelComponents() { - // set later within HTMLBars to the syntax package - this.syntax = null; - } - - /** - @private - @method transform - @param {AST} The AST to be transformed. - */ - TransformTopLevelComponents.prototype.transform = function TransformTopLevelComponents_transform(ast) { - hasSingleComponentNode(ast, function (component) { - component.tag = '@' + component.tag; - component.isStatic = true; - }); - - return ast; - }; - - function hasSingleComponentNode(program, componentCallback) { - var loc = program.loc; - var body = program.body; - - if (!loc || loc.start.line !== 1 || loc.start.column !== 0) { - return; - } - - var lastComponentNode = undefined; - var lastIndex = undefined; - var nodeCount = 0; - - for (var i = 0; i < body.length; i++) { - var curr = body[i]; - - // text node with whitespace only - if (curr.type === 'TextNode' && /^[\s]*$/.test(curr.chars)) { - continue; - } - - // has multiple root elements if we've been here before - if (nodeCount++ > 0) { - return false; - } - - if (curr.type === 'ComponentNode' || curr.type === 'ElementNode') { - lastComponentNode = curr; - lastIndex = i; - } - } - - if (!lastComponentNode) { - return; - } - - if (lastComponentNode.type === 'ComponentNode') { - componentCallback(lastComponentNode); - } - } - - exports.default = TransformTopLevelComponents; -}); -enifed('ember-template-compiler/system/calculate-location-display', ['exports'], function (exports) { - 'use strict'; - - exports.default = calculateLocationDisplay; - - function calculateLocationDisplay(moduleName, _loc) { - var loc = _loc || {}; - - var _ref = loc.start || {}; - - var column = _ref.column; - var line = _ref.line; - - var moduleInfo = ''; - if (moduleName) { - moduleInfo += '\'' + moduleName + '\' '; - } - - if (line !== undefined && column !== undefined) { - if (moduleName) { - // only prepend @ if the moduleName was present - moduleInfo += '@ '; - } - moduleInfo += 'L' + line + ':C' + column; - } - - if (moduleInfo) { - moduleInfo = '(' + moduleInfo + ') '; - } - - return moduleInfo; - } -}); -enifed('ember-template-compiler/system/compile-options', ['exports', 'ember-template-compiler/compiler'], function (exports, _emberTemplateCompilerCompiler) { - 'use strict'; - - var _compiler = _emberTemplateCompilerCompiler.default(); - - var defaultCompileOptions = _compiler.defaultCompileOptions; - exports.default = defaultCompileOptions; -}); -enifed('ember-template-compiler/system/compile', ['exports', 'ember-template-compiler/compiler', 'ember-template-compiler/system/compile-options', 'ember-metal/assign'], function (exports, _emberTemplateCompilerCompiler, _emberTemplateCompilerSystemCompileOptions, _emberMetalAssign) { - /** - @module ember - @submodule ember-template-compiler - */ - 'use strict'; - - /** - Uses HTMLBars `compile` function to process a string into a compiled template. - - This is not present in production builds. - - @private - @method compile - @param {String} templateString This is the string to be compiled by HTMLBars. - @param {Object} options This is an options hash to augment the compiler options. - */ - - exports.default = function (templateString, options) { - var _compiler = _emberTemplateCompilerCompiler.default(); - - var compile = _compiler.compile; - - return compile(templateString, _emberMetalAssign.default({}, _emberTemplateCompilerSystemCompileOptions.default(), options)); - }; -}); -enifed('ember-template-compiler/system/precompile', ['exports', 'ember-metal/assign', 'ember-template-compiler/compiler', 'ember-template-compiler/system/compile-options'], function (exports, _emberMetalAssign, _emberTemplateCompilerCompiler, _emberTemplateCompilerSystemCompileOptions) { - /** - @module ember - @submodule ember-template-compiler - */ - - 'use strict'; - - /** - Uses HTMLBars `compile` function to process a string into a compiled template string. - The returned string must be passed through `Ember.HTMLBars.template`. - - This is not present in production builds. - - @private - @method precompile - @param {String} templateString This is the string to be compiled by HTMLBars. - */ - - exports.default = function (templateString, options) { - var _compiler = _emberTemplateCompilerCompiler.default(); - - var precompile = _compiler.precompile; - - return precompile(templateString, _emberMetalAssign.default({}, _emberTemplateCompilerSystemCompileOptions.default(), options)); - }; -}); -enifed('ember-template-compiler/system/register-plugin', ['exports', 'ember-template-compiler/compiler'], function (exports, _emberTemplateCompilerCompiler) { - 'use strict'; - - var _compiler = _emberTemplateCompilerCompiler.default(); - - var registerPlugin = _compiler.registerPlugin; - exports.default = registerPlugin; -}); -enifed('ember-template-compiler/system/template', ['exports', 'ember-template-compiler/compiler'], function (exports, _emberTemplateCompilerCompiler) { - 'use strict'; - - var _compiler = _emberTemplateCompilerCompiler.default(); - - var template = _compiler.template; - exports.default = template; -}); -enifed('ember-templates/bootstrap', ['exports', 'ember-views/component_lookup', 'ember-views/system/jquery', 'ember-metal/error', 'ember-runtime/system/lazy_load', 'ember-template-compiler', 'ember-environment', 'ember-templates/template_registry'], function (exports, _emberViewsComponent_lookup, _emberViewsSystemJquery, _emberMetalError, _emberRuntimeSystemLazy_load, _emberTemplateCompiler, _emberEnvironment, _emberTemplatesTemplate_registry) { - /*globals Handlebars */ - - /** - @module ember - @submodule ember-htmlbars - */ - - 'use strict'; - - /** - @module ember - @submodule ember-htmlbars - */ - - /** - Find templates stored in the head tag as script tags and make them available - to `Ember.CoreView` in the global `Ember.TEMPLATES` object. This will be run - as a jQuery DOM-ready callback. - - Script tags with `text/x-handlebars` will be compiled - with Ember's template compiler and are suitable for use as a view's template. - Those with type `text/x-raw-handlebars` will be compiled with regular - Handlebars and are suitable for use in views' computed properties. - - @private - @method bootstrap - @for Ember.HTMLBars - @static - @param ctx - */ - function bootstrap(ctx) { - var selectors = 'script[type="text/x-handlebars"], script[type="text/x-raw-handlebars"]'; - - _emberViewsSystemJquery.default(selectors, ctx).each(function () { - // Get a reference to the script tag. - var script = _emberViewsSystemJquery.default(this); - - // Get the name of the script, used by Ember.View's templateName property. - // First look for data-template-name attribute, then fall back to its - // id if no name is found. - var templateName = script.attr('data-template-name') || script.attr('id') || 'application'; - var template, compile; - - if (script.attr('type') === 'text/x-raw-handlebars') { - compile = _emberViewsSystemJquery.default.proxy(Handlebars.compile, Handlebars); - template = compile(script.html()); - } else { - template = _emberTemplateCompiler.compile(script.html(), { - moduleName: templateName - }); - } - - // Check if template of same name already exists. - if (_emberTemplatesTemplate_registry.has(templateName)) { - throw new _emberMetalError.default('Template named "' + templateName + '" already exists.'); - } - - // For templates which have a name, we save them and then remove them from the DOM. - _emberTemplatesTemplate_registry.set(templateName, template); - - // Remove script tag from DOM. - script.remove(); - }); - } - - function _bootstrap() { - bootstrap(_emberViewsSystemJquery.default(document)); - } - - function registerComponentLookup(app) { - app.register('component-lookup:main', _emberViewsComponent_lookup.default); - } - - /* - We tie this to application.load to ensure that we've at least - attempted to bootstrap at the point that the application is loaded. - - We also tie this to document ready since we're guaranteed that all - the inline templates are present at this point. - - There's no harm to running this twice, since we remove the templates - from the DOM after processing. - */ - - _emberRuntimeSystemLazy_load.onLoad('Ember.Application', function (Application) { - Application.initializer({ - name: 'domTemplates', - initialize: _emberEnvironment.environment.hasDOM ? _bootstrap : function () {} - }); - - Application.instanceInitializer({ - name: 'registerComponentLookup', - initialize: registerComponentLookup - }); - }); - - exports.default = bootstrap; -}); +// reexports enifed('ember-templates/component', ['exports', 'ember-metal/features', 'require'], function (exports, _emberMetalFeatures, _require) { 'use strict'; exports.default = (function () { if (false) { @@ -39815,11 +38829,11 @@ return _require.default('ember-htmlbars/helper').helper; } })(); exports.helper = helper; }); -enifed('ember-templates/index', ['exports', 'ember-metal/core', 'ember-templates/template_registry', 'ember-templates/bootstrap', 'ember-templates/renderer', 'ember-templates/component', 'ember-templates/helper', 'ember-templates/components/checkbox', 'ember-templates/components/text_field', 'ember-templates/components/text_area', 'ember-templates/components/link-to'], function (exports, _emberMetalCore, _emberTemplatesTemplate_registry, _emberTemplatesBootstrap, _emberTemplatesRenderer, _emberTemplatesComponent, _emberTemplatesHelper, _emberTemplatesComponentsCheckbox, _emberTemplatesComponentsText_field, _emberTemplatesComponentsText_area, _emberTemplatesComponentsLinkTo) { +enifed('ember-templates/index', ['exports', 'ember-metal/core', 'ember-templates/template_registry', 'ember-templates/renderer', 'ember-templates/component', 'ember-templates/helper', 'ember-templates/components/checkbox', 'ember-templates/components/text_field', 'ember-templates/components/text_area', 'ember-templates/components/link-to', 'ember-templates/string', 'ember-environment', 'ember-templates/compat'], function (exports, _emberMetalCore, _emberTemplatesTemplate_registry, _emberTemplatesRenderer, _emberTemplatesComponent, _emberTemplatesHelper, _emberTemplatesComponentsCheckbox, _emberTemplatesComponentsText_field, _emberTemplatesComponentsText_area, _emberTemplatesComponentsLinkTo, _emberTemplatesString, _emberEnvironment, _emberTemplatesCompat) { 'use strict'; _emberMetalCore.default._Renderer = _emberTemplatesRenderer.Renderer; _emberMetalCore.default.Component = _emberTemplatesComponent.default; _emberTemplatesHelper.default.helper = _emberTemplatesHelper.helper; @@ -39827,10 +38841,16 @@ _emberMetalCore.default.Checkbox = _emberTemplatesComponentsCheckbox.default; _emberMetalCore.default.TextField = _emberTemplatesComponentsText_field.default; _emberMetalCore.default.TextArea = _emberTemplatesComponentsText_area.default; _emberMetalCore.default.LinkComponent = _emberTemplatesComponentsLinkTo.default; + if (_emberEnvironment.ENV.EXTEND_PROTOTYPES.String) { + String.prototype.htmlSafe = function () { + return _emberTemplatesString.htmlSafe(this); + }; + } + /** Global hash of shared templates. This will automatically be populated by the build tools so that you can store your Handlebars templates in separate files that get loaded into JavaScript at buildtime. @@ -39847,10 +38867,21 @@ }); exports.default = _emberMetalCore.default; }); // reexports +enifed('ember-templates/make-bound-helper', ['exports', 'ember-metal/features', 'require'], function (exports, _emberMetalFeatures, _require) { + 'use strict'; + + exports.default = (function () { + if (false) { + return _require.default('ember-glimmer/make-bound-helper').default; + } else { + return _require.default('ember-htmlbars/make-bound-helper').default; + } + })(); +}); enifed('ember-templates/renderer', ['exports', 'ember-metal/features', 'require'], function (exports, _emberMetalFeatures, _require) { 'use strict'; var InteractiveRenderer = (function () { if (false) { @@ -39877,10 +38908,49 @@ return _require.default('ember-htmlbars/renderer').Renderer; } })(); exports.Renderer = Renderer; }); +enifed('ember-templates/string', ['exports', 'ember-metal/features', 'require'], function (exports, _emberMetalFeatures, _require) { + 'use strict'; + + var strings = (function () { + if (false) { + return _require.default('ember-glimmer/utils/string'); + } else { + return _require.default('ember-htmlbars/utils/string'); + } + })(); + + var SafeString = strings.SafeString; + exports.SafeString = SafeString; + var escapeExpression = strings.escapeExpression; + exports.escapeExpression = escapeExpression; + var htmlSafe = strings.htmlSafe; + exports.htmlSafe = htmlSafe; + var isHTMLSafe = strings.isHTMLSafe; + exports.isHTMLSafe = isHTMLSafe; + var getSafeString = strings.getSafeString; + exports.getSafeString = getSafeString; +}); +enifed('ember-templates/template', ['exports', 'ember-metal/features', 'require'], function (exports, _emberMetalFeatures, _require) { + 'use strict'; + + var htmlbarsTemplate = undefined, + glimmerTemplate = undefined; + if (_require.has('ember-htmlbars')) { + htmlbarsTemplate = _require.default('ember-htmlbars').template; + } + + if (_require.has('ember-glimmer')) { + glimmerTemplate = _require.default('ember-glimmer').template; + } + + var template = false ? glimmerTemplate : htmlbarsTemplate; + + exports.default = template; +}); enifed("ember-templates/template_registry", ["exports"], function (exports) { // STATE within a module is frowned apon, this exists // to support Ember.TEMPLATES but shield ember internals from this legacy // global API. "use strict"; @@ -39916,10 +38986,11 @@ }); enifed('ember-views/compat/attrs-proxy', ['exports', 'ember-metal/mixin', 'ember-metal/symbol', 'ember-metal/property_events'], function (exports, _emberMetalMixin, _emberMetalSymbol, _emberMetalProperty_events) { 'use strict'; exports.deprecation = deprecation; + exports.getAttrFor = getAttrFor; function deprecation(key) { return 'You tried to look up an attribute directly on the component. This is deprecated. Use attrs.' + key + ' instead.'; } @@ -39928,26 +38999,26 @@ exports.MUTABLE_CELL = MUTABLE_CELL; function isCell(val) { return val && val[MUTABLE_CELL]; } + function getAttrFor(attrs, key) { + var val = attrs[key]; + return isCell(val) ? val.value : val; + } + var AttrsProxyMixin = { attrs: null, getAttr: function (key) { var attrs = this.attrs; if (!attrs) { return; } - return this.getAttrFor(attrs, key); + return getAttrFor(attrs, key); }, - getAttrFor: function (attrs, key) { - var val = attrs[key]; - return isCell(val) ? val.value : val; - }, - setAttr: function (key, value) { var attrs = this.attrs; var val = attrs[key]; if (!isCell(val)) { @@ -39974,10 +39045,15 @@ } }; exports.default = _emberMetalMixin.Mixin.create(AttrsProxyMixin); }); +enifed('ember-views/compat/fallback-view-registry', ['exports', 'ember-metal/dictionary'], function (exports, _emberMetalDictionary) { + 'use strict'; + + exports.default = _emberMetalDictionary.default(null); +}); enifed('ember-views/component_lookup', ['exports', 'ember-metal/debug', 'ember-runtime/system/object'], function (exports, _emberMetalDebug, _emberRuntimeSystemObject) { 'use strict'; exports.default = _emberRuntimeSystemObject.default.extend({ componentFor: function (name, owner, options) { @@ -39991,11 +39067,11 @@ var templateFullName = 'template:components/' + name; return owner.lookup(templateFullName, options); } }); }); -enifed('ember-views/index', ['exports', 'ember-runtime', 'ember-views/system/jquery', 'ember-views/system/utils', 'ember-views/system/ext', 'ember-htmlbars/renderer', 'ember-htmlbars/component', 'ember-views/system/event_dispatcher', 'ember-views/mixins/view_target_action_support', 'ember-views/component_lookup', 'ember-htmlbars/components/checkbox', 'ember-views/mixins/text_support', 'ember-htmlbars/components/text_field', 'ember-htmlbars/components/text_area'], function (exports, _emberRuntime, _emberViewsSystemJquery, _emberViewsSystemUtils, _emberViewsSystemExt, _emberHtmlbarsRenderer, _emberHtmlbarsComponent, _emberViewsSystemEvent_dispatcher, _emberViewsMixinsView_target_action_support, _emberViewsComponent_lookup, _emberHtmlbarsComponentsCheckbox, _emberViewsMixinsText_support, _emberHtmlbarsComponentsText_field, _emberHtmlbarsComponentsText_area) { +enifed('ember-views/index', ['exports', 'ember-runtime', 'ember-views/system/jquery', 'ember-views/system/utils', 'ember-views/system/ext', 'ember-views/system/event_dispatcher', 'ember-views/mixins/view_target_action_support', 'ember-views/component_lookup', 'ember-views/mixins/text_support'], function (exports, _emberRuntime, _emberViewsSystemJquery, _emberViewsSystemUtils, _emberViewsSystemExt, _emberViewsSystemEvent_dispatcher, _emberViewsMixinsView_target_action_support, _emberViewsComponent_lookup, _emberViewsMixinsText_support) { /** @module ember @submodule ember-views */ @@ -40020,26 +39096,154 @@ var ViewUtils = _emberRuntime.default.ViewUtils = {}; ViewUtils.isSimpleClick = _emberViewsSystemUtils.isSimpleClick; ViewUtils.getViewClientRects = _emberViewsSystemUtils.getViewClientRects; ViewUtils.getViewBoundingClientRect = _emberViewsSystemUtils.getViewBoundingClientRect; - _emberRuntime.default._Renderer = _emberHtmlbarsRenderer.Renderer; - - _emberRuntime.default.Checkbox = _emberHtmlbarsComponentsCheckbox.default; - _emberRuntime.default.TextField = _emberHtmlbarsComponentsText_field.default; - _emberRuntime.default.TextArea = _emberHtmlbarsComponentsText_area.default; - _emberRuntime.default.TextSupport = _emberViewsMixinsText_support.default; _emberRuntime.default.ComponentLookup = _emberViewsComponent_lookup.default; - _emberRuntime.default.Component = _emberHtmlbarsComponent.default; _emberRuntime.default.EventDispatcher = _emberViewsSystemEvent_dispatcher.default; // END EXPORTS exports.default = _emberRuntime.default; }); // for the side effect of extending Ember.run.queues +enifed('ember-views/mixins/action_support', ['exports', 'ember-metal/mixin', 'ember-metal/property_get', 'ember-metal/is_none', 'ember-metal/debug', 'ember-views/compat/attrs-proxy', 'ember-metal/utils'], function (exports, _emberMetalMixin, _emberMetalProperty_get, _emberMetalIs_none, _emberMetalDebug, _emberViewsCompatAttrsProxy, _emberMetalUtils) { + 'use strict'; + + function validateAction(component, actionName) { + if (actionName && actionName[_emberViewsCompatAttrsProxy.MUTABLE_CELL]) { + actionName = actionName.value; + } + + return actionName; + } + + exports.default = _emberMetalMixin.Mixin.create({ + /** + Calls an action passed to a component. + For example a component for playing or pausing music may translate click events + into action notifications of "play" or "stop" depending on some internal state + of the component: + ```javascript + // app/components/play-button.js + export default Ember.Component.extend({ + click() { + if (this.get('isPlaying')) { + this.sendAction('play'); + } else { + this.sendAction('stop'); + } + } + }); + ``` + The actions "play" and "stop" must be passed to this `play-button` component: + ```handlebars + {{! app/templates/application.hbs }} + {{play-button play=(action "musicStarted") stop=(action "musicStopped")}} + ``` + When the component receives a browser `click` event it translate this + interaction into application-specific semantics ("play" or "stop") and + calls the specified action. + ```javascript + // app/controller/application.js + export default Ember.Controller.extend({ + actions: { + musicStarted() { + // called when the play button is clicked + // and the music started playing + }, + musicStopped() { + // called when the play button is clicked + // and the music stopped playing + } + } + }); + ``` + If no action is passed to `sendAction` a default name of "action" + is assumed. + ```javascript + // app/components/next-button.js + export default Ember.Component.extend({ + click() { + this.sendAction(); + } + }); + ``` + ```handlebars + {{! app/templates/application.hbs }} + {{next-button action=(action "playNextSongInAlbum")}} + ``` + ```javascript + // app/controllers/application.js + App.ApplicationController = Ember.Controller.extend({ + actions: { + playNextSongInAlbum() { + ... + } + } + }); + ``` + @method sendAction + @param [action] {String} the action to call + @param [params] {*} arguments for the action + @public + */ + sendAction: function (action) { + for (var _len = arguments.length, contexts = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + contexts[_key - 1] = arguments[_key]; + } + + var actionName = undefined; + + // Send the default action + if (action === undefined) { + action = 'action'; + } + actionName = _emberMetalProperty_get.get(this, 'attrs.' + action) || _emberMetalProperty_get.get(this, action); + actionName = validateAction(this, actionName); + + // If no action name for that action could be found, just abort. + if (actionName === undefined) { + return; + } + + if (typeof actionName === 'function') { + actionName.apply(undefined, contexts); + } else { + this.triggerAction({ + action: actionName, + actionContext: contexts + }); + } + }, + + send: function (actionName) { + for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + args[_key2 - 1] = arguments[_key2]; + } + + var target = undefined; + var action = this.actions && this.actions[actionName]; + + if (action) { + var shouldBubble = action.apply(this, args) === true; + if (!shouldBubble) { + return; + } + } + + target = _emberMetalProperty_get.get(this, 'target') || _emberMetalProperty_get.get(this, '_targetObject'); + + if (target) { + var _target; + + (_target = target).send.apply(_target, arguments); + } else {} + } + }); +}); enifed('ember-views/mixins/aria_role_support', ['exports', 'ember-metal/mixin'], function (exports, _emberMetalMixin) { /** @module ember @submodule ember-views */ @@ -40050,12 +39254,10 @@ @class AriaRoleSupport @namespace Ember @private */ exports.default = _emberMetalMixin.Mixin.create({ - attributeBindings: ['ariaRole:role'], - /** The WAI-ARIA role of the control represented by this view. For example, a button may have a role of type 'button', or a pane may have a role of type 'alertdialog'. This property is used by assistive software to help visually challenged users navigate rich web applications. @@ -40067,10 +39269,84 @@ @public */ ariaRole: null }); }); +enifed('ember-views/mixins/child_views_support', ['exports', 'ember-metal/mixin', 'container/owner'], function (exports, _emberMetalMixin, _containerOwner) { + /** + @module ember + @submodule ember-views + */ + 'use strict'; + + exports.default = _emberMetalMixin.Mixin.create({ + init: function () { + this._super.apply(this, arguments); + + /** + Array of child views. You should never edit this array directly. + @property childViews + @type Array + @default [] + @private + */ + this.childViews = []; + this.ownerView = this.ownerView || this; + }, + + appendChild: function (view) { + this.linkChild(view); + this.childViews.push(view); + }, + + destroyChild: function (view) { + view.destroy(); + }, + + /** + Removes the child view from the parent view. + @method removeChild + @param {Ember.View} view + @return {Ember.View} receiver + @private + */ + removeChild: function (view) { + // If we're destroying, the entire subtree will be + // freed, and the DOM will be handled separately, + // so no need to mess with childViews. + if (this.isDestroying) { + return; + } + + // update parent node + this.unlinkChild(view); + + // remove view from childViews array. + var childViews = this.childViews; + + var index = childViews.indexOf(view); + if (index !== -1) { + childViews.splice(index, 1); + } + + return this; + }, + + linkChild: function (instance) { + if (!instance[_containerOwner.OWNER]) { + _containerOwner.setOwner(instance, _containerOwner.getOwner(this)); + } + + instance.parentView = this; + instance.ownerView = this.ownerView; + }, + + unlinkChild: function (instance) { + instance.parentView = null; + } + }); +}); enifed('ember-views/mixins/class_names_support', ['exports', 'ember-metal/debug', 'ember-metal/mixin', 'ember-runtime/system/native_array'], function (exports, _emberMetalDebug, _emberMetalMixin, _emberRuntimeSystemNative_array) { /** @module ember @submodule ember-views */ @@ -40153,11 +39429,11 @@ /** @class InstrumentationSupport @namespace Ember @public */ - var InstrumentationSupport = _emberMetalMixin.Mixin.create({ + exports.default = _emberMetalMixin.Mixin.create({ /** Used to identify this view during debugging @property instrumentDisplay @type String @public @@ -40169,93 +39445,115 @@ instrumentDetails: function (hash) { hash.template = _emberMetalProperty_get.get(this, 'templateName'); this._super(hash); } }); - - exports.default = InstrumentationSupport; }); -enifed('ember-views/mixins/legacy_child_views_support', ['exports', 'ember-metal/mixin', 'ember-metal/property_get', 'ember-metal/property_set', 'container/owner'], function (exports, _emberMetalMixin, _emberMetalProperty_get, _emberMetalProperty_set, _containerOwner) { +enifed('ember-views/mixins/template_support', ['exports', 'ember-metal/error', 'ember-metal/computed', 'container/owner', 'ember-metal/mixin', 'ember-metal/property_get', 'ember-metal/debug'], function (exports, _emberMetalError, _emberMetalComputed, _containerOwner, _emberMetalMixin, _emberMetalProperty_get, _emberMetalDebug) { 'use strict'; exports.default = _emberMetalMixin.Mixin.create({ - linkChild: function (instance) { - if (!instance[_containerOwner.OWNER]) { - _containerOwner.setOwner(instance, _containerOwner.getOwner(this)); - } + /** + @property isView + @type Boolean + @default true + @static + @private + */ + isView: true, - if (_emberMetalProperty_get.get(instance, 'parentView') !== this) { - // linkChild should be idempotent - _emberMetalProperty_set.set(instance, 'parentView', this); - instance.trigger('parentViewDidChange'); - } - instance.ownerView = this.ownerView; - }, + // .......................................................... + // TEMPLATE SUPPORT + // - unlinkChild: function (instance) { - _emberMetalProperty_set.set(instance, 'parentView', null); - instance.trigger('parentViewDidChange'); - } - }); -}); -enifed('ember-views/mixins/legacy_view_support', ['exports', 'ember-metal/debug', 'ember-metal/mixin', 'ember-metal/property_get'], function (exports, _emberMetalDebug, _emberMetalMixin, _emberMetalProperty_get) { - /** - @module ember - @submodule ember-views - */ - 'use strict'; + /** + The name of the template to lookup if no template is provided. + By default `Ember.View` will lookup a template with this name in + `Ember.TEMPLATES` (a shared global object). + @property templateName + @type String + @default null + @private + */ + templateName: null, - /** - @class LegacyViewSupport - @namespace Ember - @private - */ - var LegacyViewSupport = _emberMetalMixin.Mixin.create({ /** - Return the nearest ancestor whose parent is an instance of - `klass`. - @method nearestChildOf - @param {Class} klass Subclass of Ember.View (or Ember.View itself) - @return Ember.View - @deprecated + The name of the layout to lookup if no layout is provided. + By default `Ember.View` will lookup a template with this name in + `Ember.TEMPLATES` (a shared global object). + @property layoutName + @type String + @default null @private */ - nearestChildOf: function (klass) { + layoutName: null, - var view = _emberMetalProperty_get.get(this, 'parentView'); + /** + The template used to render the view. This should be a function that + accepts an optional context parameter and returns a string of HTML that + will be inserted into the DOM relative to its parent view. + In general, you should set the `templateName` property instead of setting + the template yourself. + @property template + @type Function + @private + */ + template: _emberMetalComputed.computed({ + get: function () { + var templateName = _emberMetalProperty_get.get(this, 'templateName'); + var template = this.templateForName(templateName, 'template'); - while (view) { - if (_emberMetalProperty_get.get(view, 'parentView') instanceof klass) { - return view; + return template || _emberMetalProperty_get.get(this, 'defaultTemplate'); + }, + set: function (key, value) { + if (value !== undefined) { + return value; } - view = _emberMetalProperty_get.get(view, 'parentView'); + return _emberMetalProperty_get.get(this, key); } - }, + }), /** - Return the nearest ancestor that is an instance of the provided - class. - @method nearestInstanceOf - @param {Class} klass Subclass of Ember.View (or Ember.View itself) - @return Ember.View - @deprecated + A view may contain a layout. A layout is a regular template but + supersedes the `template` property during rendering. It is the + responsibility of the layout template to retrieve the `template` + property from the view (or alternatively, call `Handlebars.helpers.yield`, + `{{yield}}`) to render it in the correct location. + This is useful for a view that has a shared wrapper, but which delegates + the rendering of the contents of the wrapper to the `template` property + on a subclass. + @property layout + @type Function @private */ - nearestInstanceOf: function (klass) { + layout: _emberMetalComputed.computed({ + get: function (key) { + var layoutName = _emberMetalProperty_get.get(this, 'layoutName'); + var layout = this.templateForName(layoutName, 'layout'); - var view = _emberMetalProperty_get.get(this, 'parentView'); + return layout || _emberMetalProperty_get.get(this, 'defaultLayout'); + }, - while (view) { - if (view instanceof klass) { - return view; - } - view = _emberMetalProperty_get.get(view, 'parentView'); + set: function (key, value) { + return value; } + }), + + templateForName: function (name, type) { + if (!name) { + return; + } + + var owner = _containerOwner.getOwner(this); + + if (!owner) { + throw new _emberMetalError.default('Container was not found when looking up a views template. ' + 'This is most likely due to manually instantiating an Ember.View. ' + 'See: http://git.io/EKPpnA'); + } + + return owner.lookup('template:' + name); } }); - - exports.default = LegacyViewSupport; }); enifed('ember-views/mixins/text_support', ['exports', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/mixin', 'ember-runtime/mixins/target_action_support'], function (exports, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalMixin, _emberRuntimeMixinsTarget_action_support) { /** @module ember @submodule ember-views @@ -40364,11 +39662,11 @@ @namespace Ember @uses Ember.TargetActionSupport @extends Ember.Mixin @private */ - var TextSupport = _emberMetalMixin.Mixin.create(_emberRuntimeMixinsTarget_action_support.default, { + exports.default = _emberMetalMixin.Mixin.create(_emberRuntimeMixinsTarget_action_support.default, { value: '', attributeBindings: ['autocapitalize', 'autocorrect', 'autofocus', 'disabled', 'form', 'maxlength', 'placeholder', 'readonly', 'required', 'selectionDirection', 'spellcheck', 'tabindex', 'title'], placeholder: null, disabled: false, @@ -40429,13 +39727,11 @@ return this[method](event); } }, _elementValueDidChange: function () { - // Using readDOMAttr will ensure that HTMLBars knows the last - // value. - _emberMetalProperty_set.set(this, 'value', this.readDOMAttr('value')); + _emberMetalProperty_set.set(this, 'value', this.element.value); }, change: function (event) { this._elementValueDidChange(event); }, @@ -40572,250 +39868,15 @@ if (!_emberMetalProperty_get.get(view, 'bubbles')) { event.stopPropagation(); } } } - - exports.default = TextSupport; }); -enifed('ember-views/mixins/view_child_views_support', ['exports', 'ember-metal/debug', 'ember-metal/mixin', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/set_properties', 'ember-runtime/system/native_array', 'container/owner'], function (exports, _emberMetalDebug, _emberMetalMixin, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalSet_properties, _emberRuntimeSystemNative_array, _containerOwner) { - /** - @module ember - @submodule ember-views - */ - 'use strict'; - - var EMPTY_ARRAY = []; - - exports.default = _emberMetalMixin.Mixin.create({ - /** - Array of child views. You should never edit this array directly. - @property childViews - @type Array - @default [] - @private - */ - childViews: EMPTY_ARRAY, - - init: function () { - this._super.apply(this, arguments); - - // setup child views. be sure to clone the child views array first - // 2.0TODO: Remove Ember.A() here - this.childViews = _emberRuntimeSystemNative_array.A(this.childViews.slice()); - this.ownerView = this.ownerView || this; - }, - - appendChild: function (view) { - this.linkChild(view); - this.childViews.push(view); - }, - - destroyChild: function (view) { - view.destroy(); - }, - - /** - Removes the child view from the parent view. - @method removeChild - @param {Ember.View} view - @return {Ember.View} receiver - @private - */ - removeChild: function (view) { - // If we're destroying, the entire subtree will be - // freed, and the DOM will be handled separately, - // so no need to mess with childViews. - if (this.isDestroying) { - return; - } - - // update parent node - this.unlinkChild(view); - - // remove view from childViews array. - var childViews = _emberMetalProperty_get.get(this, 'childViews'); - - var index = childViews.indexOf(view); - if (index !== -1) { - childViews.splice(index, 1); - } - - return this; - }, - - /** - Instantiates a view to be added to the childViews array during view - initialization. You generally will not call this method directly unless - you are overriding `createChildViews()`. Note that this method will - automatically configure the correct settings on the new view instance to - act as a child of the parent. - @method createChildView - @param {Class|String} viewClass - @param {Object} [attrs] Attributes to add - @return {Ember.View} new instance - @private - */ - createChildView: function (maybeViewClass) { - var attrs = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; - - if (!maybeViewClass) { - throw new TypeError('createChildViews first argument must exist'); - } - - var owner = _containerOwner.getOwner(this); - - if (maybeViewClass.isView && maybeViewClass.parentView === this && _containerOwner.getOwner(maybeViewClass) === owner) { - return maybeViewClass; - } - - var view; - - attrs.parentView = this; - attrs.renderer = this.renderer; - attrs._viewRegistry = this._viewRegistry; - - if (maybeViewClass.isViewFactory) { - _containerOwner.setOwner(attrs, owner); - - view = maybeViewClass.create(attrs); - - if (view.viewName) { - _emberMetalProperty_set.set(this, view.viewName, view); - } - } else if ('string' === typeof maybeViewClass) { - var fullName = 'view:' + maybeViewClass; - var ViewKlass = owner._lookupFactory(fullName); - - view = ViewKlass.create(attrs); - } else { - view = maybeViewClass; - - _containerOwner.setOwner(attrs, owner); - _emberMetalSet_properties.default(view, attrs); - } - - this.linkChild(view); - - return view; - }, - - linkChild: function (instance) { - if (!instance[_containerOwner.OWNER]) { - _containerOwner.setOwner(instance, _containerOwner.getOwner(this)); - } - - instance.parentView = this; - instance.ownerView = this.ownerView; - }, - - unlinkChild: function (instance) { - instance.parentView = null; - } - }); -}); -enifed('ember-views/mixins/view_context_support', ['exports', 'ember-metal/mixin', 'ember-metal/computed', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-views/mixins/legacy_view_support', 'ember-metal/events'], function (exports, _emberMetalMixin, _emberMetalComputed, _emberMetalProperty_get, _emberMetalProperty_set, _emberViewsMixinsLegacy_view_support, _emberMetalEvents) { - /** - @module ember - @submodule ember-views - */ - 'use strict'; - - var ViewContextSupport = _emberMetalMixin.Mixin.create(_emberViewsMixinsLegacy_view_support.default, { - /** - The object from which templates should access properties. - This object will be passed to the template function each time the render - method is called, but it is up to the individual function to decide what - to do with it. - By default, this will be the view's controller. - @property context - @type Object - @private - */ - context: _emberMetalComputed.computed({ - get: function () { - return _emberMetalProperty_get.get(this, '_context'); - }, - set: function (key, value) { - _emberMetalProperty_set.set(this, '_context', value); - return value; - } - }), - - /** - Private copy of the view's template context. This can be set directly - by Handlebars without triggering the observer that causes the view - to be re-rendered. - The context of a view is looked up as follows: - 1. Supplied context (usually by Handlebars) - 2. Specified controller - 3. `parentView`'s context - The code in Handlebars that overrides the `_context` property first - checks to see whether the view has a specified controller. This is - something of a hack and should be revisited. - @property _context - @private - */ - _context: _emberMetalComputed.computed({ - get: function () { - var parentView, controller; - - if (controller = _emberMetalProperty_get.get(this, 'controller')) { - return controller; - } - - parentView = this.parentView; - if (parentView) { - return _emberMetalProperty_get.get(parentView, '_context'); - } - return null; - }, - set: function (key, value) { - return value; - } - }), - - _controller: null, - - /** - The controller managing this view. If this property is set, it will be - made available for use by the template. - @property controller - @type Object - @private - */ - controller: _emberMetalComputed.computed({ - get: function () { - if (this._controller) { - return this._controller; - } - - return this.parentView ? _emberMetalProperty_get.get(this.parentView, 'controller') : null; - }, - set: function (_, value) { - this._controller = value; - return value; - } - }), - - _legacyControllerDidChange: _emberMetalMixin.observer('controller', function () { - this.childViews.forEach(function (view) { - return view.notifyPropertyChange('controller'); - }); - }), - - _notifyControllerChange: _emberMetalEvents.on('parentViewDidChange', function () { - this.notifyPropertyChange('controller'); - }) - }); - - exports.default = ViewContextSupport; -}); enifed('ember-views/mixins/view_state_support', ['exports', 'ember-metal/mixin'], function (exports, _emberMetalMixin) { 'use strict'; - var ViewStateSupport = _emberMetalMixin.Mixin.create({ + exports.default = _emberMetalMixin.Mixin.create({ _transitionTo: function (state) { var priorState = this._currentState; var currentState = this._currentState = this._states[state]; this._state = state; @@ -40825,14 +39886,12 @@ if (currentState.enter) { currentState.enter(this); } } }); - - exports.default = ViewStateSupport; }); -enifed('ember-views/mixins/view_support', ['exports', 'ember-metal/debug', 'ember-metal/error', 'ember-metal/property_get', 'ember-metal/run_loop', 'ember-metal/utils', 'ember-metal/computed', 'ember-metal/mixin', 'ember-runtime/system/core_object', 'ember-metal/symbol', 'container/owner', 'ember-views/system/jquery'], function (exports, _emberMetalDebug, _emberMetalError, _emberMetalProperty_get, _emberMetalRun_loop, _emberMetalUtils, _emberMetalComputed, _emberMetalMixin, _emberRuntimeSystemCore_object, _emberMetalSymbol, _containerOwner, _emberViewsSystemJquery) { +enifed('ember-views/mixins/view_support', ['exports', 'ember-metal/debug', 'ember-metal/run_loop', 'ember-metal/utils', 'ember-metal/mixin', 'ember-runtime/system/core_object', 'ember-metal/symbol', 'ember-views/system/jquery'], function (exports, _emberMetalDebug, _emberMetalRun_loop, _emberMetalUtils, _emberMetalMixin, _emberRuntimeSystemCore_object, _emberMetalSymbol, _emberViewsSystemJquery) { 'use strict'; var _Mixin$create; var INIT_WAS_CALLED = _emberMetalSymbol.default('INIT_WAS_CALLED'); @@ -40842,150 +39901,56 @@ } exports.default = _emberMetalMixin.Mixin.create((_Mixin$create = { concatenatedProperties: ['attributeBindings'], - /** - @property isView - @type Boolean - @default true - @static - @private - */ - isView: true, - // .......................................................... // TEMPLATE SUPPORT // /** - The name of the template to lookup if no template is provided. - By default `Ember.View` will lookup a template with this name in - `Ember.TEMPLATES` (a shared global object). - @property templateName - @type String - @default null - @private - */ - templateName: null, - - /** - The name of the layout to lookup if no layout is provided. - By default `Ember.View` will lookup a template with this name in - `Ember.TEMPLATES` (a shared global object). - @property layoutName - @type String - @default null - @private - */ - layoutName: null, - - /** - The template used to render the view. This should be a function that - accepts an optional context parameter and returns a string of HTML that - will be inserted into the DOM relative to its parent view. - In general, you should set the `templateName` property instead of setting - the template yourself. - @property template - @type Function - @private - */ - template: _emberMetalComputed.computed({ - get: function () { - var templateName = _emberMetalProperty_get.get(this, 'templateName'); - var template = this.templateForName(templateName, 'template'); - - return template || _emberMetalProperty_get.get(this, 'defaultTemplate'); - }, - set: function (key, value) { - if (value !== undefined) { - return value; - } - return _emberMetalProperty_get.get(this, key); - } - }), - - /** - A view may contain a layout. A layout is a regular template but - supersedes the `template` property during rendering. It is the - responsibility of the layout template to retrieve the `template` - property from the view (or alternatively, call `Handlebars.helpers.yield`, - `{{yield}}`) to render it in the correct location. - This is useful for a view that has a shared wrapper, but which delegates - the rendering of the contents of the wrapper to the `template` property - on a subclass. - @property layout - @type Function - @private - */ - layout: _emberMetalComputed.computed({ - get: function (key) { - var layoutName = _emberMetalProperty_get.get(this, 'layoutName'); - var layout = this.templateForName(layoutName, 'layout'); - - return layout || _emberMetalProperty_get.get(this, 'defaultLayout'); - }, - - set: function (key, value) { - return value; - } - }), - - templateForName: function (name, type) { - if (!name) { - return; - } - - var owner = _containerOwner.getOwner(this); - - if (!owner) { - throw new _emberMetalError.default('Container was not found when looking up a views template. ' + 'This is most likely due to manually instantiating an Ember.View. ' + 'See: http://git.io/EKPpnA'); - } - - return owner.lookup('template:' + name); - }, - - /** Return the nearest ancestor that is an instance of the provided class or mixin. @method nearestOfType @param {Class,Mixin} klass Subclass of Ember.View (or Ember.View itself), or an instance of Ember.Mixin. @return Ember.View + @deprecated use `yield` and contextual components for composition instead. @private */ nearestOfType: function (klass) { - var view = _emberMetalProperty_get.get(this, 'parentView'); + var view = this.parentView; var isOfType = klass instanceof _emberMetalMixin.Mixin ? function (view) { return klass.detect(view); } : function (view) { return klass.detect(view.constructor); }; while (view) { if (isOfType(view)) { return view; } - view = _emberMetalProperty_get.get(view, 'parentView'); + view = view.parentView; } }, /** Return the nearest ancestor that has a given property. @method nearestWithProperty @param {String} property A property name @return Ember.View + @deprecated use `yield` and contextual components for composition instead. @private */ nearestWithProperty: function (property) { - var view = _emberMetalProperty_get.get(this, 'parentView'); + var view = this.parentView; while (view) { if (property in view) { return view; } - view = _emberMetalProperty_get.get(view, 'parentView'); + view = view.parentView; } }, /** Renders the view again. This will work regardless of whether the @@ -41030,27 +39995,10 @@ */ $: function (sel) { return this._currentState.$(this, sel); }, - forEachChildView: function (callback) { - var childViews = this.childViews; - - if (!childViews) { - return this; - } - - var view, idx; - - for (idx = 0; idx < childViews.length; idx++) { - view = childViews[idx]; - callback(view); - } - - return this; - }, - /** Appends the view's element to the specified parent element. If the view does not have an HTML representation yet, `createElement()` will be called automatically. Note that this method just schedules the view to be appended; the DOM @@ -41086,26 +40034,26 @@ element. By default, the element created and rendered into will be a `BODY` element, since this is the default context that views are rendered into when being inserted directly into the DOM. ```js - var element = view.renderToElement(); + let element = view.renderToElement(); element.tagName; // => "BODY" ``` You can override the kind of element rendered into and returned by specifying an optional tag name as the first argument. ```js - var element = view.renderToElement('table'); + let element = view.renderToElement('table'); element.tagName; // => "TABLE" ``` This method is useful if you want to render the view into an element that is not in the document's body. Instead, a new `body` element, detached from the DOM is returned. FastBoot uses this to serialize the rendered view into a string for transmission over the network. ```js app.visit('/').then(function(instance) { - var element; + let element; Ember.run(function() { element = renderToElement(instance); }); res.send(serialize(element)); }); @@ -41161,30 +40109,10 @@ append: function () { return this.appendTo(document.body); }, /** - Removes the view's element from the element to which it is attached. - @method remove - @return {Ember.View} receiver - @private - */ - remove: function () { - // What we should really do here is wait until the end of the run loop - // to determine if the element has been re-appended to a different - // element. - // In the interim, we will just re-render if that happens. It is more - // important than elements get garbage collected. - if (!this.removedFromDOM) { - this.destroyElement(); - } - - // Set flag to avoid future renders - this._willInsert = false; - }, - - /** The HTML `id` of the view's element in the DOM. You can provide this value yourself but it must be unique (just as in HTML): ```handlebars {{my-component elementId="a-really-cool-id"}} ``` @@ -41194,11 +40122,11 @@ `elementId`, you should do this when the component or element is being instantiated: ```javascript export default Ember.Component.extend({ setElementId: Ember.on('init', function() { - var index = this.get('index'); + let index = this.get('index'); this.set('elementId', 'component-id' + index); }) }); ``` @property elementId @@ -41284,14 +40212,28 @@ @method destroyElement @return {Ember.View} receiver @private */ destroyElement: function () { - return this._currentState.destroyElement(this); + this._currentState.destroyElement(this); + return this; }, /** + You must call `destroy` on a view to destroy the view (and all of its + child views). This will remove the view from any parent node, then make + sure that the DOM element managed by the view can be released by the + memory manager. + @method destroy + @private + */ + destroy: function () { + this._super.apply(this, arguments); + this._currentState.destroy(this); + }, + + /** Called when the element of the view is going to be destroyed. Override this function to do any teardown that requires an element, like removing event listeners. Please note: any property changes made during this event will have no effect on object observers. @@ -41331,46 +40273,10 @@ or invoking from a template. @property _defaultTagName @private */ - /** - Normally, Ember's component model is "write-only". The component takes a - bunch of attributes that it got passed in, and uses them to render its - template. - One nice thing about this model is that if you try to set a value to the - same thing as last time, Ember (through HTMLBars) will avoid doing any - work on the DOM. - This is not just a performance optimization. If an attribute has not - changed, it is important not to clobber the element's "hidden state". - For example, if you set an input's `value` to the same value as before, - it will clobber selection state and cursor position. In other words, - setting an attribute is not **always** idempotent. - This method provides a way to read an element's attribute and also - update the last value Ember knows about at the same time. This makes - setting an attribute idempotent. - In particular, what this means is that if you get an `<input>` element's - `value` attribute and then re-render the template with the same value, - it will avoid clobbering the cursor and selection position. - Since most attribute sets are idempotent in the browser, you typically - can get away with reading attributes using jQuery, but the most reliable - way to do so is through this method. - @method readDOMAttr - @param {String} name the name of the attribute - @return String - @public - */ - readDOMAttr: function (name) { - var attr = this._renderNode.childNodes.filter(function (node) { - return node.attrName === name; - })[0]; - if (!attr) { - return null; - } - return attr.getContent(); - }, - // ....................................................... // CORE DISPLAY METHODS // /** @@ -41413,46 +40319,12 @@ if (!this.scheduledRevalidation || this._dispatching) { this.scheduledRevalidation = true; _emberMetalRun_loop.default.scheduleOnce('render', this, this.revalidate); } - }, _Mixin$create.removeFromParent = function () { - var parent = this.parentView; - - // Remove DOM element from parent - this.remove(); - - if (parent) { - parent.removeChild(this); - } - return this; - }, _Mixin$create.destroy = function () { - // get parentView before calling super because it'll be destroyed - var parentView = this.parentView; - var viewName = this.viewName; - - if (!this._super.apply(this, arguments)) { - return; - } - - // remove from non-virtual parent view if viewName was specified - if (viewName && parentView) { - parentView.set(viewName, null); - } - - // Destroy HTMLbars template - if (this.lastResult) { - this.lastResult.destroy(); - } - - return this; }, _Mixin$create.handleEvent = function (eventName, evt) { return this._currentState.handleEvent(this, eventName, evt); - }, _Mixin$create._register = function () { - this._viewRegistry[this.elementId] = this; - }, _Mixin$create._unregister = function () { - delete this._viewRegistry[this.elementId]; }, _Mixin$create)); }); /* This is a special hook implemented in CoreObject, that allows Views/Components to have a way to ensure that `init` fires before `didInitAttrs` / `didReceiveAttrs` @@ -41460,27 +40332,10 @@ own `init` is finished). @method __postInitInitialization @private */ -/** - Removes the view from its `parentView`, if one is found. Otherwise - does nothing. - @method removeFromParent - @return {Ember.View} receiver - @private -*/ - -/** - You must call `destroy` on a view to destroy the view (and all of its - child views). This will remove the view from any parent node, then make - sure that the DOM element managed by the view can be released by the - memory manager. - @method destroy - @private -*/ - // ....................................................... // EVENT HANDLING // /** @@ -41488,27 +40343,10 @@ @method handleEvent @param eventName {String} @param evt {Event} @private */ - -/** - Registers the view in the view registry, keyed on the view's `elementId`. - This is used by the EventDispatcher to locate the view in response to - events. - This method should only be called once the view has been inserted into the - DOM. - @method _register - @private -*/ - -/** - Removes the view from the view registry. This should be called when the - view is removed from DOM. - @method _unregister - @private -*/ enifed('ember-views/mixins/view_target_action_support', ['exports', 'ember-metal/mixin', 'ember-runtime/mixins/target_action_support', 'ember-metal/alias'], function (exports, _emberMetalMixin, _emberRuntimeMixinsTarget_action_support, _emberMetalAlias) { 'use strict'; /** `Ember.ViewTargetActionSupport` is a mixin that can be included in a @@ -41579,11 +40417,11 @@ /** @class VisibilitySupport @namespace Ember @public */ - var VisibilitySupport = _emberMetalMixin.Mixin.create({ + exports.default = _emberMetalMixin.Mixin.create({ /** If `false`, the view will appear hidden in DOM. @property isVisible @type Boolean @default null @@ -41636,70 +40474,66 @@ } }, _notifyBecameVisible: function () { this.trigger('becameVisible'); - - this.forEachChildView(function (view) { + var childViews = this.childViews; + for (var i = 0; i < childViews.length; i++) { + var view = childViews[i]; var isVisible = _emberMetalProperty_get.get(view, 'isVisible'); - if (isVisible || isVisible === null) { view._notifyBecameVisible(); } - }); + } }, _notifyBecameHidden: function () { this.trigger('becameHidden'); - this.forEachChildView(function (view) { + var childViews = this.childViews; + for (var i = 0; i < childViews.length; i++) { + var view = childViews[i]; var isVisible = _emberMetalProperty_get.get(view, 'isVisible'); - if (isVisible || isVisible === null) { view._notifyBecameHidden(); } - }); + } }, _isAncestorHidden: function () { - var parent = _emberMetalProperty_get.get(this, 'parentView'); - + var parent = this.parentView; while (parent) { if (_emberMetalProperty_get.get(parent, 'isVisible') === false) { return true; } - - parent = _emberMetalProperty_get.get(parent, 'parentView'); + parent = parent.parentView; } - return false; } }); - - exports.default = VisibilitySupport; }); enifed("ember-views/system/action_manager", ["exports"], function (exports) { /** @module ember @submodule ember-views */ "use strict"; + exports.default = ActionManager; + function ActionManager() {} /** Global action id hash. @private @property registeredActions @type Object */ ActionManager.registeredActions = {}; - - exports.default = ActionManager; }); -enifed('ember-views/system/event_dispatcher', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/is_none', 'ember-metal/run_loop', 'ember-runtime/system/object', 'ember-views/system/jquery', 'ember-views/system/action_manager', 'ember-views/views/view', 'ember-metal/assign', 'container/owner', 'ember-environment'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalIs_none, _emberMetalRun_loop, _emberRuntimeSystemObject, _emberViewsSystemJquery, _emberViewsSystemAction_manager, _emberViewsViewsView, _emberMetalAssign, _containerOwner, _emberEnvironment) { +enifed('ember-views/system/event_dispatcher', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/is_none', 'ember-metal/run_loop', 'ember-runtime/system/object', 'ember-views/system/jquery', 'ember-views/system/action_manager', 'ember-metal/assign', 'container/owner', 'ember-environment', 'ember-views/compat/fallback-view-registry'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberMetalProperty_set, _emberMetalIs_none, _emberMetalRun_loop, _emberRuntimeSystemObject, _emberViewsSystemJquery, _emberViewsSystemAction_manager, _emberMetalAssign, _containerOwner, _emberEnvironment, _emberViewsCompatFallbackViewRegistry) { /** @module ember @submodule ember-views */ @@ -41725,19 +40559,19 @@ The set of events names (and associated handler function names) to be setup and dispatched by the `EventDispatcher`. Modifications to this list can be done at setup time, generally via the `Ember.Application.customEvents` hash. To add new events to be listened to: ```javascript - var App = Ember.Application.create({ + let App = Ember.Application.create({ customEvents: { paste: 'paste' } }); ``` To prevent default events from being listened to: ```javascript - var App = Ember.Application.create({ + let App = Ember.Application.create({ customEvents: { mouseenter: null, mouseleave: null } }); @@ -41795,11 +40629,11 @@ Note that most Ember applications do not use this feature. If your app also does not use it, consider setting this property to false to gain some performance improvement by allowing the EventDispatcher to skip the search for the `eventManager` on the view tree. ```javascript - var EventDispatcher = Em.EventDispatcher.extend({ + let EventDispatcher = Em.EventDispatcher.extend({ events: { click : 'click', focusin : 'focusIn', focusout : 'focusOut', change : 'change' @@ -41829,21 +40663,25 @@ @private @method setup @param addedEvents {Object} */ setup: function (addedEvents, rootElement) { - var event; + var event = undefined; var events = this._finalEvents = _emberMetalAssign.default({}, _emberMetalProperty_get.get(this, 'events'), addedEvents); if (!_emberMetalIs_none.default(rootElement)) { _emberMetalProperty_set.set(this, 'rootElement', rootElement); } rootElement = _emberViewsSystemJquery.default(_emberMetalProperty_get.get(this, 'rootElement')); rootElement.addClass(ROOT_ELEMENT_CLASS); + if (!rootElement.is(ROOT_ELEMENT_SELECTOR)) { + throw new TypeError('Unable to add \'' + ROOT_ELEMENT_CLASS + '\' class to root element (' + (rootElement.selector || rootElement[0].tagName) + '). Make sure you set rootElement to the body or an element in the body.'); + } + for (event in events) { if (events.hasOwnProperty(event)) { this.setupHandler(rootElement, event, events[event]); } } @@ -41863,11 +40701,11 @@ */ setupHandler: function (rootElement, event, eventName) { var self = this; var owner = _containerOwner.getOwner(this); - var viewRegistry = owner && owner.lookup('-view-registry:main') || _emberViewsViewsView.default.views; + var viewRegistry = owner && owner.lookup('-view-registry:main') || _emberViewsCompatFallbackViewRegistry.default; if (eventName === null) { return; } @@ -41984,28 +40822,29 @@ // after bindings have synced, and a queue for scheduling actions // that should occur after view rendering. _emberMetalRun_loop.default._addQueue('render', 'actions'); _emberMetalRun_loop.default._addQueue('afterRender', 'render'); }); -enifed('ember-views/system/jquery', ['exports', 'ember-environment', 'require'], function (exports, _emberEnvironment, _require) { +enifed('ember-views/system/jquery', ['exports', 'ember-environment'], function (exports, _emberEnvironment) { 'use strict'; var jQuery = undefined; if (_emberEnvironment.environment.hasDOM) { jQuery = _emberEnvironment.context.imports.jQuery; - if (!jQuery && typeof _require.default === 'function') { - jQuery = _require.default('jquery'); - } if (jQuery) { - // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dndevents - ['dragstart', 'drag', 'dragenter', 'dragleave', 'dragover', 'drop', 'dragend'].forEach(function (eventName) { - jQuery.event.fixHooks[eventName] = { - props: ['dataTransfer'] - }; - }); + if (jQuery.event.addProp) { + jQuery.event.addProp('dataTransfer'); + } else { + // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dndevents + ['dragstart', 'drag', 'dragenter', 'dragleave', 'dragover', 'drop', 'dragend'].forEach(function (eventName) { + jQuery.event.fixHooks[eventName] = { + props: ['dataTransfer'] + }; + }); + } } } exports.default = jQuery; }); @@ -42069,17 +40908,17 @@ return !!div.innerHTML.match('foo'); })(); exports.canSetNameOnInputs = canSetNameOnInputs; }); -enifed("ember-views/system/utils", ["exports"], function (exports) { +enifed('ember-views/system/utils', ['exports'], function (exports) { /** @module ember @submodule ember-views */ - "use strict"; + 'use strict'; exports.isSimpleClick = isSimpleClick; exports.getViewClientRects = getViewClientRects; exports.getViewBoundingClientRect = getViewBoundingClientRect; @@ -42088,10 +40927,13 @@ var secondaryClick = event.which > 1; // IE9 may return undefined return !modifier && !secondaryClick; } + var STYLE_WARNING = '' + 'Binding style attributes may introduce cross-site scripting vulnerabilities; ' + 'please ensure that values being bound are properly escaped. For more information, ' + 'including how to disable this warning, see ' + 'http://emberjs.com/deprecations/v1.x/#toc_binding-style-attributes.'; + + exports.STYLE_WARNING = STYLE_WARNING; /** @private @method getViewRange @param {Ember.View} view */ @@ -42134,19 +40976,48 @@ function getViewBoundingClientRect(view) { var range = getViewRange(view); return range.getBoundingClientRect(); } }); -enifed('ember-views/views/core_view', ['exports', 'ember-metal/debug', 'ember-metal/property_get', 'ember-runtime/system/object', 'ember-runtime/mixins/evented', 'ember-runtime/mixins/action_handler', 'ember-runtime/utils', 'ember-htmlbars/renderer', 'ember-views/views/states', 'htmlbars-runtime', 'require'], function (exports, _emberMetalDebug, _emberMetalProperty_get, _emberRuntimeSystemObject, _emberRuntimeMixinsEvented, _emberRuntimeMixinsAction_handler, _emberRuntimeUtils, _emberHtmlbarsRenderer, _emberViewsViewsStates, _htmlbarsRuntime, _require) { +enifed('ember-views/utils/lookup-component', ['exports'], function (exports) { 'use strict'; + exports.default = lookupComponent; + function lookupComponentPair(componentLookup, owner, name, options) { + var component = componentLookup.componentFor(name, owner, options); + var layout = componentLookup.layoutFor(name, owner, options); + return { + component: component, + layout: layout + }; + } + + function lookupComponent(owner, name, options) { + var componentLookup = owner.lookup('component-lookup:main'); + + var source = options && options.source; + + if (source) { + var localResult = lookupComponentPair(componentLookup, owner, name, options); + + if (localResult.component || localResult.layout) { + return localResult; + } + } + + return lookupComponentPair(componentLookup, owner, name); + } +}); +enifed('ember-views/views/core_view', ['exports', 'ember-metal/property_get', 'ember-runtime/system/object', 'ember-runtime/mixins/evented', 'ember-runtime/mixins/action_handler', 'ember-runtime/utils', 'ember-views/views/states', 'require'], function (exports, _emberMetalProperty_get, _emberRuntimeSystemObject, _emberRuntimeMixinsEvented, _emberRuntimeMixinsAction_handler, _emberRuntimeUtils, _emberViewsViewsStates, _require) { + 'use strict'; + // Normally, the renderer is injected by the container when the view is looked // up. However, if someone creates a view without looking it up via the // container (e.g. `Ember.View.create().append()`) then we create a fallback // DOM renderer that is shared. In general, this path should be avoided since // views created this way cannot run in a node environment. - var renderer; + var renderer = undefined; /** `Ember.CoreView` is an abstract class that exists to give view-like behavior to both Ember's main view class `Ember.View` and other classes that don't need the fully functionaltiy of `Ember.View`. @@ -42169,22 +41040,27 @@ init: function () { this._super.apply(this, arguments); this._state = 'preRender'; this._currentState = this._states.preRender; + this._willInsert = false; + this._renderNode = null; + this.lastResult = null; + this._dispatching = null; + this._destroyingSubtreeForView = null; + this._isDispatchingAttrs = false; + this._isVisible = false; + this.element = null; + this.env = null; this._isVisible = _emberMetalProperty_get.get(this, 'isVisible'); // Fallback for legacy cases where the view was created directly // via `create()` instead of going through the container. if (!this.renderer) { - var DOMHelper = domHelper(); - renderer = renderer || _emberHtmlbarsRenderer.InteractiveRenderer.create({ dom: new DOMHelper() }); + renderer = renderer || htmlbarsRenderer(); this.renderer = renderer; } - - this._destroyingSubtreeForView = null; - this._dispatching = null; }, /** If the view is currently inserted into the DOM of a parent view, this property will point to the parent of the view. @@ -42223,42 +41099,26 @@ } }, has: function (name) { return _emberRuntimeUtils.typeOf(this[name]) === 'function' || this._super(name); - }, - - destroy: function () { - if (!this._super.apply(this, arguments)) { - return; - } - - this._currentState.cleanup(this); - - // If the destroyingSubtreeForView property is not set but we have an - // associated render node, it means this view is being destroyed from user - // code and not via a change in the templating layer (like an {{if}} - // becoming falsy, for example). In this case, it is our responsibility to - // make sure that any render nodes created as part of the rendering process - // are cleaned up. - if (!this.ownerView._destroyingSubtreeForView && this._renderNode) { - _htmlbarsRuntime.internal.clearMorph(this._renderNode, this.ownerView.env, true); - } - - return this; } }); _emberRuntimeMixinsAction_handler.deprecateUnderscoreActions(CoreView); CoreView.reopenClass({ isViewFactory: true }); - var _domHelper; - function domHelper() { - return _domHelper = _domHelper || _require.default('ember-htmlbars/system/dom-helper').default; + var InteractiveRenderer = undefined, + DOMHelper = undefined; + function htmlbarsRenderer() { + DOMHelper = DOMHelper || _require.default('ember-htmlbars/system/dom-helper').default; + InteractiveRenderer = InteractiveRenderer || _require.default('ember-htmlbars/renderer').InteractiveRenderer; + + return InteractiveRenderer.create({ dom: new DOMHelper() }); } exports.default = CoreView; }); enifed('ember-views/views/states', ['exports', 'ember-metal/assign', 'ember-views/views/states/default', 'ember-views/views/states/pre_render', 'ember-views/views/states/has_element', 'ember-views/views/states/in_dom', 'ember-views/views/states/destroying'], function (exports, _emberMetalAssign, _emberViewsViewsStatesDefault, _emberViewsViewsStatesPre_render, _emberViewsViewsStatesHas_element, _emberViewsViewsStatesIn_dom, _emberViewsViewsStatesDestroying) { @@ -42333,13 +41193,14 @@ // Handle events from `Ember.EventDispatcher` handleEvent: function () { return true; // continue event propagation }, - cleanup: function () {}, destroyElement: function () {}, + destroy: function () {}, + rerender: function (view) { view.renderer.ensureViewNotRendering(view); } }; }); @@ -42394,23 +41255,18 @@ rerender: function (view) { view.renderer.ensureViewNotRendering(view); view.renderer.rerender(view); }, - cleanup: function (view) { - view._currentState.destroyElement(view); - }, - - // once the view is already in the DOM, destroying it removes it - // from the DOM, nukes its element, and puts it back into the - // preRender state if inDOM. - destroyElement: function (view) { view.renderer.remove(view, false); - return view; }, + destroy: function (view) { + view.renderer.remove(view, true); + }, + // Handle events from `Ember.EventDispatcher` handleEvent: function (view, eventName, event) { if (view.has(eventName)) { // Handler should be able to re-dispatch events, so we don't // preventDefault or stopPropagation. @@ -42443,16 +41299,18 @@ _emberMetalAssign.default(inDOM, { enter: function (view) { // Register the view for event handling. This hash is used by // Ember.EventDispatcher to dispatch incoming events. if (view.tagName !== '') { - view._register(); + view.renderer._register(view); } }, exit: function (view) { - view._unregister(); + if (view.tagName !== '') { + view.renderer._unregister(view); + } } }); exports.default = inDOM; }); @@ -42470,11 +41328,11 @@ legacyPropertyDidChange: function (view, key) {} }); exports.default = preRender; }); -enifed('ember-views/views/view', ['exports', 'ember-views/system/ext', 'ember-views/views/core_view', 'ember-views/mixins/view_context_support', 'ember-views/mixins/view_child_views_support', 'ember-views/mixins/legacy_child_views_support', 'ember-views/mixins/view_state_support', 'ember-views/mixins/class_names_support', 'ember-views/mixins/legacy_view_support', 'ember-views/mixins/instrumentation_support', 'ember-views/mixins/aria_role_support', 'ember-views/mixins/visibility_support', 'ember-views/compat/attrs-proxy', 'ember-views/mixins/view_support'], function (exports, _emberViewsSystemExt, _emberViewsViewsCore_view, _emberViewsMixinsView_context_support, _emberViewsMixinsView_child_views_support, _emberViewsMixinsLegacy_child_views_support, _emberViewsMixinsView_state_support, _emberViewsMixinsClass_names_support, _emberViewsMixinsLegacy_view_support, _emberViewsMixinsInstrumentation_support, _emberViewsMixinsAria_role_support, _emberViewsMixinsVisibility_support, _emberViewsCompatAttrsProxy, _emberViewsMixinsView_support) { +enifed('ember-views/views/view', ['exports', 'ember-views/system/ext', 'ember-views/views/core_view', 'ember-views/mixins/child_views_support', 'ember-views/mixins/view_state_support', 'ember-views/mixins/class_names_support', 'ember-views/mixins/instrumentation_support', 'ember-views/mixins/aria_role_support', 'ember-views/mixins/visibility_support', 'ember-views/compat/attrs-proxy', 'ember-views/mixins/view_support'], function (exports, _emberViewsSystemExt, _emberViewsViewsCore_view, _emberViewsMixinsChild_views_support, _emberViewsMixinsView_state_support, _emberViewsMixinsClass_names_support, _emberViewsMixinsInstrumentation_support, _emberViewsMixinsAria_role_support, _emberViewsMixinsVisibility_support, _emberViewsCompatAttrsProxy, _emberViewsMixinsView_support) { 'use strict'; /** @module ember @submodule ember-views @@ -42719,11 +41577,11 @@ ```html <use xlink:href="#triangle"></use> ``` If the return value of an `attributeBindings` monitored property is a boolean - the attribute will be present or absent depending on the value: + the property's value will be set as a coerced string: ```javascript MyTextInput = Ember.View.extend({ tagName: 'input', attributeBindings: ['disabled'], @@ -42732,11 +41590,11 @@ ``` Will result in a view instance with an HTML representation of: ```html - <input id="ember1" class="ember-view" /> + <input id="ember1" class="ember-view" disabled="false" /> ``` `attributeBindings` can refer to computed properties: ```javascript @@ -42768,136 +41626,10 @@ update of the HTML attribute in the view's rendered HTML representation. `attributeBindings` is a concatenated property. See [Ember.Object](/api/classes/Ember.Object.html) documentation for more information about concatenated properties. - ## Templates - - The HTML contents of a view's rendered representation are determined by its - template. Templates can be any function that accepts an optional context - parameter and returns a string of HTML that will be inserted within the - view's tag. Most typically in Ember this function will be a compiled - template. - - ```javascript - AView = Ember.View.extend({ - template: Ember.HTMLBars.compile('I am the template') - }); - ``` - - Will result in view instances with an HTML representation of: - - ```html - <div id="ember1" class="ember-view">I am the template</div> - ``` - - Within an Ember application is more common to define a Handlebars templates as - part of a page: - - ```html - <script type='text/x-handlebars' data-template-name='some-template'> - Hello - </script> - ``` - - And associate it by name using a view's `templateName` property: - - ```javascript - AView = Ember.View.extend({ - templateName: 'some-template' - }); - ``` - - If you have nested routes, your Handlebars template will look like this: - - ```html - <script type='text/x-handlebars' data-template-name='posts/new'> - <h1>New Post</h1> - </script> - ``` - - And `templateName` property: - - ```javascript - AView = Ember.View.extend({ - templateName: 'posts/new' - }); - ``` - - Using a value for `templateName` that does not have a template - with a matching `data-template-name` attribute will throw an error. - - For views classes that may have a template later defined (e.g. as the block - portion of a `{{view}}` helper call in another template or in - a subclass), you can provide a `defaultTemplate` property set to compiled - template function. If a template is not later provided for the view instance - the `defaultTemplate` value will be used: - - ```javascript - AView = Ember.View.extend({ - defaultTemplate: Ember.HTMLBars.compile('I was the default'), - template: null, - templateName: null - }); - ``` - - Will result in instances with an HTML representation of: - - ```html - <div id="ember1" class="ember-view">I was the default</div> - ``` - - If a `template` or `templateName` is provided it will take precedence over - `defaultTemplate`: - - ```javascript - AView = Ember.View.extend({ - defaultTemplate: Ember.HTMLBars.compile('I was the default') - }); - - aView = AView.create({ - template: Ember.HTMLBars.compile('I was the template, not default') - }); - ``` - - Will result in the following HTML representation when rendered: - - ```html - <div id="ember1" class="ember-view">I was the template, not default</div> - ``` - - ## View Context - - The default context of the compiled template is the view's controller: - - ```javascript - AView = Ember.View.extend({ - template: Ember.HTMLBars.compile('Hello {{excitedGreeting}}') - }); - - aController = Ember.Object.create({ - firstName: 'Barry', - excitedGreeting: Ember.computed('content.firstName', function() { - return this.get('content.firstName') + '!!!'; - }) - }); - - aView = AView.create({ - controller: aController - }); - ``` - - Will result in an HTML representation of: - - ```html - <div id="ember1" class="ember-view">Hello Barry!!!</div> - ``` - - A context can also be explicitly supplied through the view's `context` - property. If the view has neither `context` nor `controller` properties, the - `parentView`'s context will be used. - ## Layouts Views can have a secondary template that wraps their main template. Like primary templates, layouts can be any function that accepts an optional context parameter and returns a string of HTML that will be inserted inside @@ -43080,41 +41812,27 @@ * `dragLeave` * `dragOver` * `dragEnd` * `drop` - ## `{{view}}` Helper - - Other `Ember.View` instances can be included as part of a view's template by - using the `{{view}}` helper. See [Ember.Templates.helpers.view](/api/classes/Ember.Templates.helpers.html#method_view) - for additional information. - @class View @namespace Ember @extends Ember.CoreView @deprecated See http://emberjs.com/deprecations/v1.x/#toc_ember-view @uses Ember.ViewSupport - @uses Ember.ViewContextSupport @uses Ember.ViewChildViewsSupport @uses Ember.ClassNamesSupport @uses Ember.AttributeBindingsSupport - @uses Ember.LegacyViewSupport @uses Ember.InstrumentationSupport @uses Ember.VisibilitySupport @uses Ember.AriaRoleSupport @public */ // jscs:disable validateIndentation - var View = _emberViewsViewsCore_view.default.extend(_emberViewsMixinsView_context_support.default, _emberViewsMixinsView_child_views_support.default, _emberViewsMixinsLegacy_child_views_support.default, _emberViewsMixinsView_state_support.default, _emberViewsMixinsClass_names_support.default, _emberViewsMixinsLegacy_view_support.default, _emberViewsMixinsInstrumentation_support.default, _emberViewsMixinsVisibility_support.default, _emberViewsCompatAttrsProxy.default, _emberViewsMixinsAria_role_support.default, _emberViewsMixinsView_support.default, { - init: function () { - this._super.apply(this, arguments); + var View = _emberViewsViewsCore_view.default.extend(_emberViewsMixinsChild_views_support.default, _emberViewsMixinsView_state_support.default, _emberViewsMixinsClass_names_support.default, _emberViewsMixinsInstrumentation_support.default, _emberViewsMixinsVisibility_support.default, _emberViewsCompatAttrsProxy.default, _emberViewsMixinsAria_role_support.default, _emberViewsMixinsView_support.default, { + attributeBindings: ['ariaRole:role'], - if (!this._viewRegistry) { - this._viewRegistry = View.views; - } - }, - /** Given a property name, returns a dasherized version of that property name if the property evaluates to a non-falsy value. For example, if the view has property `isUrgent` that evaluates to true, passing `isUrgent` to this method will return `"is-urgent"`. @@ -43154,38 +41872,33 @@ // inside the buffer, legal manipulations are done on the buffer // once the view has been inserted into the DOM, legal manipulations // are done on the DOM element. - View.reopenClass({ - /** - Global views hash - @property views - @static - @type Object - @private - */ - views: {} - }); - exports.default = View; - exports.ViewContextSupport = _emberViewsMixinsView_context_support.default; - exports.ViewChildViewsSupport = _emberViewsMixinsView_child_views_support.default; + exports.ViewChildViewsSupport = _emberViewsMixinsChild_views_support.default; exports.ViewStateSupport = _emberViewsMixinsView_state_support.default; exports.ClassNamesSupport = _emberViewsMixinsClass_names_support.default; }); // for the side effect of extending Ember.run.queues enifed("ember/features", ["exports"], function (exports) { "use strict"; exports.default = {}; }); -enifed('ember/index', ['exports', 'ember-metal', 'ember-runtime', 'ember-views', 'ember-routing', 'ember-application', 'ember-extension-support', 'ember-htmlbars', 'ember-templates', 'require', 'ember-runtime/system/lazy_load'], function (exports, _emberMetal, _emberRuntime, _emberViews, _emberRouting, _emberApplication, _emberExtensionSupport, _emberHtmlbars, _emberTemplates, _require, _emberRuntimeSystemLazy_load) { +enifed('ember/index', ['exports', 'require', 'ember-metal', 'ember-runtime', 'ember-views', 'ember-routing', 'ember-application', 'ember-extension-support', 'ember-templates', 'ember-runtime/system/lazy_load'], function (exports, _require, _emberMetal, _emberRuntime, _emberViews, _emberRouting, _emberApplication, _emberExtensionSupport, _emberTemplates, _emberRuntimeSystemLazy_load) { // require the main entry points for each of these packages // this is so that the global exports occur properly 'use strict'; + if (_require.has('ember-htmlbars')) { + _require.default('ember-htmlbars'); + } + if (_require.has('ember-glimmer')) { + _require.default('ember-glimmer'); + } + if (_require.has('ember-template-compiler')) { _require.default('ember-template-compiler'); } // do this to ensure that Ember.Test is defined properly on the global @@ -43201,11 +41914,11 @@ */ }); enifed("ember/version", ["exports"], function (exports) { "use strict"; - exports.default = "2.7.2"; + exports.default = "2.8.0-beta.1"; }); enifed('htmlbars-runtime', ['exports', 'htmlbars-runtime/hooks', 'htmlbars-runtime/render', 'htmlbars-util/morph-utils', 'htmlbars-util/template-utils'], function (exports, _htmlbarsRuntimeHooks, _htmlbarsRuntimeRender, _htmlbarsUtilMorphUtils, _htmlbarsUtilTemplateUtils) { 'use strict'; var internal = { @@ -46410,13 +45123,16 @@ } node = nextNode; } while (node); } }); -enifed('route-recognizer', ['exports', 'route-recognizer/dsl'], function (exports, _routeRecognizerDsl) { +enifed('route-recognizer', ['exports', 'route-recognizer/dsl', 'route-recognizer/normalizer'], function (exports, _routeRecognizerDsl, _routeRecognizerNormalizer) { 'use strict'; + var normalizePath = _routeRecognizerNormalizer.default.normalizePath; + var normalizeSegment = _routeRecognizerNormalizer.default.normalizeSegment; + var specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\']; var escapeRegex = new RegExp('(\\' + specials.join('|\\') + ')', 'g'); function isArray(test) { @@ -46439,21 +45155,23 @@ // * `validChars`: a String with a list of all valid characters, or // * `invalidChars`: a String with a list of all invalid characters // * `repeat`: true if the character specification can repeat function StaticSegment(string) { - this.string = string; + this.string = normalizeSegment(string); } StaticSegment.prototype = { - eachChar: function (callback) { + eachChar: function (currentState) { var string = this.string, ch; - for (var i = 0, l = string.length; i < l; i++) { + for (var i = 0; i < string.length; i++) { ch = string.charAt(i); - callback({ validChars: ch }); + currentState = currentState.put({ invalidChars: undefined, repeat: false, validChars: ch }); } + + return currentState; }, regex: function () { return this.string.replace(escapeRegex, '\\$1'); }, @@ -46462,32 +45180,36 @@ return this.string; } }; function DynamicSegment(name) { - this.name = name; + this.name = normalizeSegment(name); } DynamicSegment.prototype = { - eachChar: function (callback) { - callback({ invalidChars: "/", repeat: true }); + eachChar: function (currentState) { + return currentState.put({ invalidChars: "/", repeat: true, validChars: undefined }); }, regex: function () { return "([^/]+)"; }, generate: function (params) { - return params[this.name]; + if (RouteRecognizer.ENCODE_AND_DECODE_PATH_SEGMENTS) { + return encodeURIComponent(params[this.name]); + } else { + return params[this.name]; + } } }; function StarSegment(name) { this.name = name; } StarSegment.prototype = { - eachChar: function (callback) { - callback({ invalidChars: "", repeat: true }); + eachChar: function (currentState) { + return currentState.put({ invalidChars: "", repeat: true, validChars: undefined }); }, regex: function () { return "(.+)"; }, @@ -46497,49 +45219,80 @@ } }; function EpsilonSegment() {} EpsilonSegment.prototype = { - eachChar: function () {}, + eachChar: function (currentState) { + return currentState; + }, regex: function () { return ""; }, generate: function () { return ""; } }; - function parse(route, names, types) { + // The `names` will be populated with the paramter name for each dynamic/star + // segment. `shouldDecodes` will be populated with a boolean for each dyanamic/star + // segment, indicating whether it should be decoded during recognition. + function parse(route, names, specificity, shouldDecodes) { // normalize route as not starting with a "/". Recognition will // also normalize. if (route.charAt(0) === "/") { route = route.substr(1); } - var segments = route.split("/"), - results = []; + var segments = route.split("/"); + var results = new Array(segments.length); - for (var i = 0, l = segments.length; i < l; i++) { + // A routes has specificity determined by the order that its different segments + // appear in. This system mirrors how the magnitude of numbers written as strings + // works. + // Consider a number written as: "abc". An example would be "200". Any other number written + // "xyz" will be smaller than "abc" so long as `a > x`. For instance, "199" is smaller + // then "200", even though "y" and "z" (which are both 9) are larger than "0" (the value + // of (`b` and `c`). This is because the leading symbol, "2", is larger than the other + // leading symbol, "1". + // The rule is that symbols to the left carry more weight than symbols to the right + // when a number is written out as a string. In the above strings, the leading digit + // represents how many 100's are in the number, and it carries more weight than the middle + // number which represents how many 10's are in the number. + // This system of number magnitude works well for route specificity, too. A route written as + // `a/b/c` will be more specific than `x/y/z` as long as `a` is more specific than + // `x`, irrespective of the other parts. + // Because of this similarity, we assign each type of segment a number value written as a + // string. We can find the specificity of compound routes by concatenating these strings + // together, from left to right. After we have looped through all of the segments, + // we convert the string to a number. + specificity.val = ''; + + for (var i = 0; i < segments.length; i++) { var segment = segments[i], match; if (match = segment.match(/^:([^\/]+)$/)) { - results.push(new DynamicSegment(match[1])); + results[i] = new DynamicSegment(match[1]); names.push(match[1]); - types.dynamics++; + shouldDecodes.push(true); + specificity.val += '3'; } else if (match = segment.match(/^\*([^\/]+)$/)) { - results.push(new StarSegment(match[1])); + results[i] = new StarSegment(match[1]); names.push(match[1]); - types.stars++; + shouldDecodes.push(false); + specificity.val += '1'; } else if (segment === "") { - results.push(new EpsilonSegment()); + results[i] = new EpsilonSegment(); + specificity.val += '2'; } else { - results.push(new StaticSegment(segment)); - types.statics++; + results[i] = new StaticSegment(segment); + specificity.val += '4'; } } + specificity.val = +specificity.val; + return results; } // A State has a character specification and (`charSpec`) and a list of possible // subsequent states (`nextStates`). @@ -46559,23 +45312,32 @@ // implementation would use a hash of keys pointing at one or more next states. function State(charSpec) { this.charSpec = charSpec; this.nextStates = []; + this.charSpecs = {}; + this.regex = undefined; + this.handlers = undefined; + this.specificity = undefined; } State.prototype = { get: function (charSpec) { + if (this.charSpecs[charSpec.validChars]) { + return this.charSpecs[charSpec.validChars]; + } + var nextStates = this.nextStates; - for (var i = 0, l = nextStates.length; i < l; i++) { + for (var i = 0; i < nextStates.length; i++) { var child = nextStates[i]; var isEqual = child.charSpec.validChars === charSpec.validChars; isEqual = isEqual && child.charSpec.invalidChars === charSpec.invalidChars; if (isEqual) { + this.charSpecs[charSpec.validChars] = child; return child; } } }, @@ -46605,20 +45367,18 @@ return state; }, // Find a list of child states matching the next character match: function (ch) { - // DEBUG "Processing `" + ch + "`:" var nextStates = this.nextStates, child, charSpec, chars; - // DEBUG " " + debugState(this) var returned = []; - for (var i = 0, l = nextStates.length; i < l; i++) { + for (var i = 0; i < nextStates.length; i++) { child = nextStates[i]; charSpec = child.charSpec; if (typeof (chars = charSpec.validChars) !== 'undefined') { @@ -46632,71 +45392,16 @@ } } return returned; } - - /** IF DEBUG - , debug: function() { - var charSpec = this.charSpec, - debug = "[", - chars = charSpec.validChars || charSpec.invalidChars; - if (charSpec.invalidChars) { debug += "^"; } - debug += chars; - debug += "]"; - if (charSpec.repeat) { debug += "+"; } - return debug; - } - END IF **/ }; - /** IF DEBUG - function debug(log) { - console.log(log); - } - - function debugState(state) { - return state.nextStates.map(function(n) { - if (n.nextStates.length === 0) { return "( " + n.debug() + " [accepting] )"; } - return "( " + n.debug() + " <then> " + n.nextStates.map(function(s) { return s.debug() }).join(" or ") + " )"; - }).join(", ") - } - END IF **/ - - // This is a somewhat naive strategy, but should work in a lot of cases - // A better strategy would properly resolve /posts/:id/new and /posts/edit/:id. - // - // This strategy generally prefers more static and less dynamic matching. - // Specifically, it - // - // * prefers fewer stars to more, then - // * prefers using stars for less of the match to more, then - // * prefers fewer dynamic segments to more, then - // * prefers more static segments to more + // Sort the routes by specificity function sortSolutions(states) { return states.sort(function (a, b) { - if (a.types.stars !== b.types.stars) { - return a.types.stars - b.types.stars; - } - - if (a.types.stars) { - if (a.types.statics !== b.types.statics) { - return b.types.statics - a.types.statics; - } - if (a.types.dynamics !== b.types.dynamics) { - return b.types.dynamics - a.types.dynamics; - } - } - - if (a.types.dynamics !== b.types.dynamics) { - return a.types.dynamics - b.types.dynamics; - } - if (a.types.statics !== b.types.statics) { - return b.types.statics - a.types.statics; - } - - return 0; + return b.specificity.val - a.specificity.val; }); } function recognizeChar(states, ch) { var nextStates = []; @@ -46725,46 +45430,58 @@ push: Array.prototype.push, length: 0, queryParams: null }); - function findHandler(state, path, queryParams) { + function findHandler(state, originalPath, queryParams) { var handlers = state.handlers, regex = state.regex; - var captures = path.match(regex), + var captures = originalPath.match(regex), currentCapture = 1; var result = new RecognizeResults(queryParams); - for (var i = 0, l = handlers.length; i < l; i++) { + result.length = handlers.length; + + for (var i = 0; i < handlers.length; i++) { var handler = handlers[i], names = handler.names, + shouldDecodes = handler.shouldDecodes, params = {}; + var name, shouldDecode, capture; - for (var j = 0, m = names.length; j < m; j++) { - params[names[j]] = captures[currentCapture++]; + for (var j = 0; j < names.length; j++) { + name = names[j]; + shouldDecode = shouldDecodes[j]; + capture = captures[currentCapture++]; + + if (RouteRecognizer.ENCODE_AND_DECODE_PATH_SEGMENTS) { + if (shouldDecode) { + params[name] = decodeURIComponent(capture); + } else { + params[name] = capture; + } + } else { + params[name] = capture; + } } - result.push({ handler: handler.handler, params: params, isDynamic: !!names.length }); + result[i] = { handler: handler.handler, params: params, isDynamic: !!names.length }; } return result; } - function addSegment(currentState, segment) { - segment.eachChar(function (ch) { - var state; - - currentState = currentState.put(ch); - }); - - return currentState; - } - function decodeQueryParamPart(part) { // http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1 part = part.replace(/\+/gm, '%20'); - return decodeURIComponent(part); + var result; + try { + result = decodeURIComponent(part); + } catch (error) { + result = ''; + } + return result; } // The main interface var RouteRecognizer = function () { @@ -46774,73 +45491,75 @@ RouteRecognizer.prototype = { add: function (routes, options) { var currentState = this.rootState, regex = "^", - types = { statics: 0, dynamics: 0, stars: 0 }, - handlers = [], + specificity = {}, + handlers = new Array(routes.length), allSegments = [], name; var isEmpty = true; - for (var i = 0, l = routes.length; i < l; i++) { + for (var i = 0; i < routes.length; i++) { var route = routes[i], - names = []; + names = [], + shouldDecodes = []; - var segments = parse(route.path, names, types); + var segments = parse(route.path, names, specificity, shouldDecodes); allSegments = allSegments.concat(segments); - for (var j = 0, m = segments.length; j < m; j++) { + for (var j = 0; j < segments.length; j++) { var segment = segments[j]; if (segment instanceof EpsilonSegment) { continue; } isEmpty = false; // Add a "/" for the new segment - currentState = currentState.put({ validChars: "/" }); + currentState = currentState.put({ invalidChars: undefined, repeat: false, validChars: "/" }); regex += "/"; // Add a representation of the segment to the NFA and regex - currentState = addSegment(currentState, segment); + currentState = segment.eachChar(currentState); regex += segment.regex(); } - - var handler = { handler: route.handler, names: names }; - handlers.push(handler); + var handler = { handler: route.handler, names: names, shouldDecodes: shouldDecodes }; + handlers[i] = handler; } if (isEmpty) { - currentState = currentState.put({ validChars: "/" }); + currentState = currentState.put({ invalidChars: undefined, repeat: false, validChars: "/" }); regex += "/"; } currentState.handlers = handlers; currentState.regex = new RegExp(regex + "$"); - currentState.types = types; + currentState.specificity = specificity; if (name = options && options.as) { this.names[name] = { segments: allSegments, handlers: handlers }; } }, handlersFor: function (name) { - var route = this.names[name], - result = []; + var route = this.names[name]; + if (!route) { throw new Error("There is no route named " + name); } - for (var i = 0, l = route.handlers.length; i < l; i++) { - result.push(route.handlers[i]); + var result = new Array(route.handlers.length); + + for (var i = 0; i < route.handlers.length; i++) { + result[i] = route.handlers[i]; } return result; }, @@ -46855,11 +45574,11 @@ throw new Error("There is no route named " + name); } var segments = route.segments; - for (var i = 0, l = segments.length; i < l; i++) { + for (var i = 0; i < segments.length; i++) { var segment = segments[i]; if (segment instanceof EpsilonSegment) { continue; } @@ -46886,19 +45605,19 @@ if (params.hasOwnProperty(key)) { keys.push(key); } } keys.sort(); - for (var i = 0, len = keys.length; i < len; i++) { + for (var i = 0; i < keys.length; i++) { key = keys[i]; var value = params[key]; if (value == null) { continue; } var pair = encodeURIComponent(key); if (isArray(value)) { - for (var j = 0, l = value.length; j < l; j++) { + for (var j = 0; j < value.length; j++) { var arrayPair = key + '[]' + '=' + encodeURIComponent(value[j]); pairs.push(arrayPair); } } else { pair += "=" + encodeURIComponent(value); @@ -46949,44 +45668,53 @@ pathLen, i, l, queryStart, queryParams = {}, + hashStart, isSlashDropped = false; + hashStart = path.indexOf('#'); + if (hashStart !== -1) { + path = path.substr(0, hashStart); + } + queryStart = path.indexOf('?'); if (queryStart !== -1) { var queryString = path.substr(queryStart + 1, path.length); path = path.substr(0, queryStart); queryParams = this.parseQueryString(queryString); } - path = decodeURI(path); - - // DEBUG GROUP path - if (path.charAt(0) !== "/") { path = "/" + path; } + var originalPath = path; + if (RouteRecognizer.ENCODE_AND_DECODE_PATH_SEGMENTS) { + path = normalizePath(path); + } else { + path = decodeURI(path); + originalPath = decodeURI(originalPath); + } + pathLen = path.length; if (pathLen > 1 && path.charAt(pathLen - 1) === "/") { path = path.substr(0, pathLen - 1); + originalPath = originalPath.substr(0, pathLen - 1); isSlashDropped = true; } - for (i = 0, l = path.length; i < l; i++) { + for (i = 0; i < path.length; i++) { states = recognizeChar(states, path.charAt(i)); if (!states.length) { break; } } - // END DEBUG GROUP - var solutions = []; - for (i = 0, l = states.length; i < l; i++) { + for (i = 0; i < states.length; i++) { if (states[i].handlers) { solutions.push(states[i]); } } @@ -46996,21 +45724,27 @@ if (state && state.handlers) { // if a trailing slash was dropped and a star segment is the last segment // specified, put the trailing slash back if (isSlashDropped && state.regex.source.slice(-5) === "(.+)$") { - path = path + "/"; + originalPath = originalPath + "/"; } - return findHandler(state, path, queryParams); + return findHandler(state, originalPath, queryParams); } } }; RouteRecognizer.prototype.map = _routeRecognizerDsl.default; - RouteRecognizer.VERSION = '0.1.5'; + RouteRecognizer.VERSION = '0.2.0'; + // Set to false to opt-out of encoding and decoding path segments. + // See https://github.com/tildeio/route-recognizer/pull/55 + RouteRecognizer.ENCODE_AND_DECODE_PATH_SEGMENTS = true; + + RouteRecognizer.Normalizer = _routeRecognizerNormalizer.default; + exports.default = RouteRecognizer; }); enifed("route-recognizer/dsl", ["exports"], function (exports) { "use strict"; @@ -47077,11 +45811,11 @@ }; } function addRoute(routeArray, path, handler) { var len = 0; - for (var i = 0, l = routeArray.length; i < l; i++) { + for (var i = 0; i < routeArray.length; i++) { len += routeArray[i].path.length; } path = path.substr(len); var route = { path: path, handler: handler }; @@ -47117,20 +45851,123 @@ this.add(route); } }, this); }; }); +enifed('route-recognizer/normalizer', ['exports'], function (exports) { + // Match percent-encoded values (e.g. %3a, %3A, %25) + 'use strict'; + + var PERCENT_ENCODED_VALUES = /%[a-fA-F0-9]{2}/g; + + function toUpper(str) { + return str.toUpperCase(); + } + + // Turn percent-encoded values to upper case ("%3a" -> "%3A") + function percentEncodedValuesToUpper(string) { + return string.replace(PERCENT_ENCODED_VALUES, toUpper); + } + + // Normalizes percent-encoded values to upper-case and decodes percent-encoded + // values that are not reserved (like unicode characters). + // Safe to call multiple times on the same path. + function normalizePath(path) { + return path.split('/').map(normalizeSegment).join('/'); + } + + function percentEncode(char) { + return '%' + charToHex(char); + } + + function charToHex(char) { + return char.charCodeAt(0).toString(16).toUpperCase(); + } + + // Decodes percent-encoded values in the string except those + // characters in `reservedHex`, where `reservedHex` is an array of 2-character + // percent-encodings + function decodeURIComponentExcept(string, reservedHex) { + if (string.indexOf('%') === -1) { + // If there is no percent char, there is no decoding that needs to + // be done and we exit early + return string; + } + string = percentEncodedValuesToUpper(string); + + var result = ''; + var buffer = ''; + var idx = 0; + while (idx < string.length) { + var pIdx = string.indexOf('%', idx); + + if (pIdx === -1) { + // no percent char + buffer += string.slice(idx); + break; + } else { + // found percent char + buffer += string.slice(idx, pIdx); + idx = pIdx + 3; + + var hex = string.slice(pIdx + 1, pIdx + 3); + var encoded = '%' + hex; + + if (reservedHex.indexOf(hex) === -1) { + // encoded is not in reserved set, add to buffer + buffer += encoded; + } else { + result += decodeURIComponent(buffer); + buffer = ''; + result += encoded; + } + } + } + result += decodeURIComponent(buffer); + return result; + } + + // Leave these characters in encoded state in segments + var reservedSegmentChars = ['%', '/']; + var reservedHex = reservedSegmentChars.map(charToHex); + + function normalizeSegment(segment) { + return decodeURIComponentExcept(segment, reservedHex); + } + + var Normalizer = { + normalizeSegment: normalizeSegment, + normalizePath: normalizePath + }; + + exports.default = Normalizer; +}); enifed('router', ['exports', 'router/router'], function (exports, _routerRouter) { 'use strict'; exports.default = _routerRouter.default; }); enifed('router/handler-info', ['exports', 'router/utils', 'rsvp/promise'], function (exports, _routerUtils, _rsvpPromise) { 'use strict'; function HandlerInfo(_props) { var props = _props || {}; + var name = props.name; + + // Setup a handlerPromise so that we can wait for asynchronously loaded handlers + this.handlerPromise = _rsvpPromise.default.resolve(props.handler); + + // Wait until the 'handler' property has been updated when chaining to a handler + // that is a promise + if (_routerUtils.isPromise(props.handler)) { + this.handlerPromise = this.handlerPromise.then(_routerUtils.bind(this, this.updateHandler)); + props.handler = undefined; + } else if (props.handler) { + // Store the name of the handler on the handler for easy checks later + props.handler._handlerName = name; + } + _routerUtils.merge(this, props); this.initialize(props); } HandlerInfo.prototype = { @@ -47160,18 +45997,31 @@ serialize: function () { return this.params || {}; }, + updateHandler: function (handler) { + // Store the name of the handler on the handler for easy checks later + handler._handlerName = this.name; + return this.handler = handler; + }, + resolve: function (shouldContinue, payload) { var checkForAbort = _routerUtils.bind(this, this.checkForAbort, shouldContinue), beforeModel = _routerUtils.bind(this, this.runBeforeModelHook, payload), model = _routerUtils.bind(this, this.getModel, payload), afterModel = _routerUtils.bind(this, this.runAfterModelHook, payload), - becomeResolved = _routerUtils.bind(this, this.becomeResolved, payload); + becomeResolved = _routerUtils.bind(this, this.becomeResolved, payload), + self = this; - return _rsvpPromise.default.resolve(undefined, this.promiseLabel("Start handler")).then(checkForAbort, null, this.promiseLabel("Check for abort")).then(beforeModel, null, this.promiseLabel("Before model")).then(checkForAbort, null, this.promiseLabel("Check if aborted during 'beforeModel' hook")).then(model, null, this.promiseLabel("Model")).then(checkForAbort, null, this.promiseLabel("Check if aborted in 'model' hook")).then(afterModel, null, this.promiseLabel("After model")).then(checkForAbort, null, this.promiseLabel("Check if aborted in 'afterModel' hook")).then(becomeResolved, null, this.promiseLabel("Become resolved")); + return _rsvpPromise.default.resolve(this.handlerPromise, this.promiseLabel("Start handler")).then(function (handler) { + // We nest this chain in case the handlerPromise has an error so that + // we don't have to bubble it through every step + return _rsvpPromise.default.resolve(handler).then(checkForAbort, null, self.promiseLabel("Check for abort")).then(beforeModel, null, self.promiseLabel("Before model")).then(checkForAbort, null, self.promiseLabel("Check if aborted during 'beforeModel' hook")).then(model, null, self.promiseLabel("Model")).then(checkForAbort, null, self.promiseLabel("Check if aborted in 'model' hook")).then(afterModel, null, self.promiseLabel("After model")).then(checkForAbort, null, self.promiseLabel("Check if aborted in 'afterModel' hook")).then(becomeResolved, null, self.promiseLabel("Become resolved")); + }, function (error) { + throw error; + }); }, runBeforeModelHook: function (payload) { if (payload.trigger) { payload.trigger(true, 'willResolveModel', payload, this.handler); @@ -47406,11 +46256,11 @@ } }); exports.default = UnresolvedHandlerInfoByParam; }); -enifed('router/router', ['exports', 'route-recognizer', 'rsvp/promise', 'router/utils', 'router/transition-state', 'router/transition', 'router/transition-intent/named-transition-intent', 'router/transition-intent/url-transition-intent', 'router/handler-info'], function (exports, _routeRecognizer, _rsvpPromise, _routerUtils, _routerTransitionState, _routerTransition, _routerTransitionIntentNamedTransitionIntent, _routerTransitionIntentUrlTransitionIntent, _routerHandlerInfo) { +enifed('router/router', ['exports', 'route-recognizer', 'rsvp/promise', 'router/utils', 'router/transition-state', 'router/transition', 'router/transition-intent/named-transition-intent', 'router/transition-intent/url-transition-intent'], function (exports, _routeRecognizer, _rsvpPromise, _routerUtils, _routerTransitionState, _routerTransition, _routerTransitionIntentNamedTransitionIntent, _routerTransitionIntentUrlTransitionIntent) { 'use strict'; var pop = Array.prototype.pop; function Router(_options) { @@ -47875,30 +46725,39 @@ Helper method used by setupContexts. Handles errors or redirects that may happen in enter/setup. */ function handlerEnteredOrUpdated(currentHandlerInfos, handlerInfo, enter, transition) { - var handler = handlerInfo.handler, context = handlerInfo.context; - if (enter) { - _routerUtils.callHook(handler, 'enter', transition); - } - if (transition && transition.isAborted) { - throw new _routerTransition.TransitionAborted(); - } + function _handlerEnteredOrUpdated(handler) { + if (enter) { + _routerUtils.callHook(handler, 'enter', transition); + } - handler.context = context; - _routerUtils.callHook(handler, 'contextDidChange'); + if (transition && transition.isAborted) { + throw new _routerTransition.TransitionAborted(); + } - _routerUtils.callHook(handler, 'setup', context, transition); - if (transition && transition.isAborted) { - throw new _routerTransition.TransitionAborted(); + handler.context = context; + _routerUtils.callHook(handler, 'contextDidChange'); + + _routerUtils.callHook(handler, 'setup', context, transition); + if (transition && transition.isAborted) { + throw new _routerTransition.TransitionAborted(); + } + + currentHandlerInfos.push(handlerInfo); } - currentHandlerInfos.push(handlerInfo); + // If the handler doesn't exist, it means we haven't resolved the handler promise yet + if (!handler) { + handlerInfo.handlerPromise = handlerInfo.handlerPromise.then(_handlerEnteredOrUpdated); + } else { + _handlerEnteredOrUpdated(handler); + } return true; } /** @@ -48271,11 +47130,11 @@ var invalidateIndex = handlers.length; // Pivot handlers are provided for refresh transitions if (this.pivotHandler) { for (i = 0, len = handlers.length; i < len; ++i) { - if (getHandler(handlers[i].handler) === this.pivotHandler) { + if (handlers[i].handler === this.pivotHandler._handlerName) { invalidateIndex = i; break; } } } @@ -48449,26 +47308,42 @@ if (!results) { throw new _routerUnrecognizedUrlError.default(this.url); } var statesDiffer = false; + var url = this.url; + // Checks if a handler is accessible by URL. If it is not, an error is thrown. + // For the case where the handler is loaded asynchronously, the error will be + // thrown once it is loaded. + function checkHandlerAccessibility(handler) { + if (handler.inaccessibleByURL) { + throw new _routerUnrecognizedUrlError.default(url); + } + + return handler; + } + for (i = 0, len = results.length; i < len; ++i) { var result = results[i]; var name = result.handler; var handler = getHandler(name); - if (handler.inaccessibleByURL) { - throw new _routerUnrecognizedUrlError.default(this.url); - } + checkHandlerAccessibility(handler); var newHandlerInfo = _routerHandlerInfoFactory.default('param', { name: name, handler: handler, params: result.params }); + // If the hanlder is being loaded asynchronously, check again if we can + // access it after it has resolved + if (_routerUtils.isPromise(handler)) { + newHandlerInfo.handlerPromise = newHandlerInfo.handlerPromise.then(checkHandlerAccessibility); + } + var oldHandlerInfo = oldState.handlerInfos[i]; if (statesDiffer || newHandlerInfo.shouldSupercede(oldHandlerInfo)) { statesDiffer = true; newState.handlerInfos[i] = newHandlerInfo; } else { @@ -48708,12 +47583,11 @@ Custom state can be stored on a Transition's `data` object. This can be useful for decorating a Transition within an earlier hook and shared with a later hook. Properties set on `data` will be copied to new transitions generated by calling `retry` on this transition. - - @property data + @property data @type {Object} @public */ data: null, @@ -48914,10 +47788,11 @@ exports.default = UnrecognizedURLError; }); enifed('router/utils', ['exports'], function (exports) { 'use strict'; + exports.isPromise = isPromise; exports.extractQueryParams = extractQueryParams; exports.log = log; exports.bind = bind; exports.forEach = forEach; exports.trigger = trigger; @@ -48936,10 +47811,18 @@ } var isArray = _isArray; exports.isArray = isArray; + /** + Determines if an object is Promise by checking if it is "thenable". + **/ + + function isPromise(obj) { + return (typeof obj === 'object' && obj !== null || typeof obj === 'function') && typeof obj.then === 'function'; + } + function merge(hash, other) { for (var prop in other) { if (other.hasOwnProperty(prop)) { hash[prop] = other[prop]; } @@ -49038,23 +47921,38 @@ throw new Error("Could not trigger event '" + name + "'. There are no active handlers"); } var eventWasHandled = false; + function delayedEvent(name, args, handler) { + handler.events[name].apply(handler, args); + } + for (var i = handlerInfos.length - 1; i >= 0; i--) { var handlerInfo = handlerInfos[i], handler = handlerInfo.handler; + // If there is no handler, it means the handler hasn't resolved yet which + // means that we should trigger the event later when the handler is available + if (!handler) { + handlerInfo.handlerPromise.then(bind(null, delayedEvent, name, args)); + continue; + } + if (handler.events && handler.events[name]) { if (handler.events[name].apply(handler, args) === true) { eventWasHandled = true; } else { return; } } } - if (!eventWasHandled && !ignoreFailure) { + // In the case that we got an UnrecognizedURLError as an event with no handler, + // let it bubble up + if (name === 'error' && args[0].name === 'UnrecognizedURLError') { + throw args[0]; + } else if (!eventWasHandled && !ignoreFailure) { throw new Error("Nothing handled the event '" + name + "'."); } } function getChangelist(oldObject, newObject) {