dist/ember.prod.js in ember-source-1.5.0.beta.3 vs dist/ember.prod.js in ember-source-1.5.0.beta.4

- old
+ new

@@ -3,11 +3,11 @@ * @copyright Copyright 2011-2014 Tilde Inc. and contributors * Portions Copyright 2006-2011 Strobe Inc. * Portions Copyright 2008-2011 Apple Inc. All rights reserved. * @license Licensed under MIT license * See https://raw.github.com/emberjs/ember.js/master/LICENSE - * @version 1.5.0-beta.3 + * @version 1.5.0-beta.4 */ (function() { var define, requireModule, require, requirejs; @@ -86,11 +86,11 @@ The core Runtime framework is based on the jQuery API with a number of performance optimizations. @class Ember @static - @version 1.5.0-beta.3+pre.f95d2018 + @version 1.5.0-beta.4 */ if ('undefined' === typeof Ember) { // Create core object. Make it act like an instance of Ember.Namespace so that // objects assigned to it are given a sane string representation. @@ -113,14 +113,14 @@ /** @property VERSION @type String - @default '1.5.0-beta.3+pre.f95d2018' + @default '1.5.0-beta.4' @static */ -Ember.VERSION = '1.5.0-beta.3+pre.f95d2018'; +Ember.VERSION = '1.5.0-beta.4'; /** Standard environmental variables. You can define these in a global `EmberENV` variable before loading Ember to control various configuration settings. @@ -5612,10 +5612,11 @@ return keyName+BEFORE_OBSERVERS; } /** @method addObserver + @for Ember @param obj @param {String} path @param {Object|Function} targetOrMethod @param {Function|String} [method] */ @@ -5630,10 +5631,11 @@ return Ember.listenersFor(obj, changeEvent(path)); }; /** @method removeObserver + @for Ember @param obj @param {String} path @param {Object|Function} targetOrMethod @param {Function|String} [method] */ @@ -5644,10 +5646,11 @@ return this; }; /** @method addBeforeObserver + @for Ember @param obj @param {String} path @param {Object|Function} targetOrMethod @param {Function|String} [method] */ @@ -5686,10 +5689,11 @@ return Ember.listenersFor(obj, beforeEvent(path)); }; /** @method removeBeforeObserver + @for Ember @param obj @param {String} path @param {Object|Function} targetOrMethod @param {Function|String} [method] */ @@ -16755,13 +16759,16 @@ ``` - `itemA` the first item to compare. - `itemB` the second item to compare. - This function should return `-1` when `itemA` should come before - `itemB`. It should return `1` when `itemA` should come after + This function should return negative number (e.g. `-1`) when `itemA` should come before + `itemB`. It should return positive number (e.g. `1`) when `itemA` should come after `itemB`. If the `itemA` and `itemB` are equal this function should return `0`. + + Therefore, if this function is comparing some numeric values, simple `itemA - itemB` or + `itemA.get( 'foo' ) - itemB.get( 'foo' )` can be used instead of series of `if`. Example ```javascript var ToDoList = Ember.Object.extend({ @@ -19297,10 +19304,11 @@ _setupContent: function() { var content = get(this, 'content'); if (content) { + content.addArrayObserver(this, { willChange: 'contentArrayWillChange', didChange: 'contentArrayDidChange' }); } @@ -19329,10 +19337,11 @@ _setupArrangedContent: function() { var arrangedContent = get(this, 'arrangedContent'); if (arrangedContent) { + arrangedContent.addArrayObserver(this, { willChange: 'arrangedContentArrayWillChange', didChange: 'arrangedContentArrayDidChange' }); } @@ -20350,10 +20359,12 @@ })(); (function() { +/*globals CustomEvent */ + var forEach = Ember.ArrayPolyfills.forEach; /** @module ember @submodule ember-runtime @@ -20401,10 +20412,15 @@ @param object {Object} object to pass to callbacks */ Ember.runLoadHooks = function(name, object) { loaded[name] = object; + if (typeof window === 'object' && typeof window.dispatchEvent === 'function' && typeof CustomEvent === "function") { + var event = new CustomEvent(name, {detail: object, name: name}); + window.dispatchEvent(event); + } + if (loadHooks[name]) { forEach.call(loadHooks[name], function(callback) { callback(object); }); } @@ -21057,11 +21073,11 @@ /** @module ember @submodule ember-views */ -var jQuery = (this && this.jQuery) || (Ember.imports && Ember.imports.jQuery); +var jQuery = (Ember.imports && Ember.imports.jQuery) || (this && this.jQuery); if (!jQuery && typeof require === 'function') { jQuery = require('jquery'); } @@ -25744,10 +25760,12 @@ })(); (function() { +var get = Ember.get; + /** The ComponentTemplateDeprecation mixin is used to provide a useful deprecation warning when using either `template` or `templateName` with a component. The `template` and `templateName` properties specified at extend time are moved to `layout` and `layoutName` respectively. @@ -25778,11 +25796,11 @@ // Calling super is only OK here since we KNOW that // there is another Mixin loaded first. this._super.apply(this, arguments); var deprecatedProperty, replacementProperty, - layoutSpecified = (props.layoutName || props.layout); + layoutSpecified = (props.layoutName || props.layout || get(this, 'layoutName')); if (props.templateName && !layoutSpecified) { deprecatedProperty = 'templateName'; replacementProperty = 'layoutName'; @@ -26853,11 +26871,11 @@ var helperInvocation = source[source.length - 1], helperName = (DOT_LOOKUP_REGEX.exec(helperInvocation) || BRACKET_STRING_LOOKUP_REGEX.exec(helperInvocation))[1], matches = INVOCATION_SPLITTING_REGEX.exec(helperInvocation); source[source.length - 1] = matches[1] + "'" + helperName + "'" + matches[3]; -} +}; var stringifyBlockHelperMissing = Ember.Handlebars.JavaScriptCompiler.stringifyLastBlockHelperMissingInvocation; var originalBlockValue = Ember.Handlebars.JavaScriptCompiler.prototype.blockValue; Ember.Handlebars.JavaScriptCompiler.prototype.blockValue = function() { originalBlockValue.apply(this, arguments); @@ -39569,20 +39587,50 @@ var get = Ember.get, classify = Ember.String.classify, capitalize = Ember.String.capitalize, decamelize = Ember.String.decamelize; +Ember.Resolver = Ember.Object.extend({ + /** + This will be set to the Application instance when it is + created. + + @property namespace + */ + namespace: null, + normalize: function(fullName) { + throw new Error("Invalid call to `resolver.normalize(fullName)`. Please override the 'normalize' method in subclass of `Ember.AbstractResolver` to prevent falling through to this error."); + }, + resolve: function(fullName) { + throw new Error("Invalid call to `resolver.resolve(parsedName)`. Please override the 'resolve' method in subclass of `Ember.AbstractResolver` to prevent falling through to this error."); + }, + parseName: function(parsedName) { + throw new Error("Invalid call to `resolver.resolveByType(parsedName)`. Please override the 'resolveByType' method in subclass of `Ember.AbstractResolver` to prevent falling through to this error."); + }, + lookupDescription: function(fullName) { + throw new Error("Invalid call to `resolver.lookupDescription(fullName)`. Please override the 'lookupDescription' method in subclass of `Ember.AbstractResolver` to prevent falling through to this error."); + }, + makeToString: function(factory, fullName) { + throw new Error("Invalid call to `resolver.makeToString(factory, fullName)`. Please override the 'makeToString' method in subclass of `Ember.AbstractResolver` to prevent falling through to this error."); + }, + resolveOther: function(parsedName) { + throw new Error("Invalid call to `resolver.resolveDefault(parsedName)`. Please override the 'resolveDefault' method in subclass of `Ember.AbstractResolver` to prevent falling through to this error."); + } +}); + + + /** The DefaultResolver defines the default lookup rules to resolve container lookups before consulting the container for registered items: -* templates are looked up on `Ember.TEMPLATES` -* other names are looked up on the application after converting - the name. For example, `controller:post` looks up - `App.PostController` by default. -* there are some nuances (see examples below) + * templates are looked up on `Ember.TEMPLATES` + * other names are looked up on the application after converting + the name. For example, `controller:post` looks up + `App.PostController` by default. + * there are some nuances (see examples below) ### How Resolving Works The container calls this object's `resolve` method with the `fullName` argument. @@ -39728,11 +39776,53 @@ name: name, root: root, resolveMethodName: "resolve" + classify(type) }; }, + /** + Returns a human-readable description for a fullName. Used by the + Application namespace in assertions to describe the + precise name of the class that Ember is looking for, rather than + container keys. + + @protected + @param {String} fullName the lookup string + @method lookupDescription + */ + lookupDescription: function(fullName) { + var parsedName = this.parseName(fullName); + + if (parsedName.type === 'template') { + return "template at " + parsedName.fullNameWithoutType.replace(/\./g, '/'); + } + + var description = parsedName.root + "." + classify(parsedName.name); + if (parsedName.type !== 'model') { description += classify(parsedName.type); } + + return description; + }, + + makeToString: function(factory, fullName) { + return factory.toString(); + }, + /** + Given a parseName object (output from `parseName`), apply + the conventions expected by `Ember.Router` + + @protected + @param {Object} parsedName a parseName object with the parsed + fullName lookup string + @method useRouterNaming + */ + useRouterNaming: function(parsedName) { + parsedName.name = parsedName.name.replace(/\./g, '_'); + if (parsedName.name === 'basic') { + parsedName.name = ''; + } + }, + /** Look up the template in Ember.TEMPLATES @protected @param {Object} parsedName a parseName object with the parsed fullName lookup string @@ -39749,23 +39839,20 @@ if (Ember.TEMPLATES[templateName]) { return Ember.TEMPLATES[templateName]; } }, /** - Given a parseName object (output from `parseName`), apply - the conventions expected by `Ember.Router` + Lookup the view using `resolveOther` @protected @param {Object} parsedName a parseName object with the parsed fullName lookup string - @method useRouterNaming + @method resolveView */ - useRouterNaming: function(parsedName) { - parsedName.name = parsedName.name.replace(/\./g, '_'); - if (parsedName.name === 'basic') { - parsedName.name = ''; - } + resolveView: function(parsedName) { + this.useRouterNaming(parsedName); + return this.resolveOther(parsedName); }, /** Lookup the controller using `resolveOther` @protected @@ -39787,27 +39874,11 @@ */ resolveRoute: function(parsedName) { this.useRouterNaming(parsedName); return this.resolveOther(parsedName); }, - /** - Lookup the view using `resolveOther` - @protected - @param {Object} parsedName a parseName object with the parsed - fullName lookup string - @method resolveView - */ - resolveView: function(parsedName) { - this.useRouterNaming(parsedName); - return this.resolveOther(parsedName); - }, - - resolveHelper: function(parsedName) { - return this.resolveOther(parsedName) || Ember.Handlebars.helpers[parsedName.fullNameWithoutType]; - }, - /** Lookup the model on the Application namespace @protected @param {Object} parsedName a parseName object with the parsed @@ -39825,43 +39896,28 @@ namespace (usually on the Application) @protected @param {Object} parsedName a parseName object with the parsed fullName lookup string - @method resolveOther + @method resolveHelper */ - resolveOther: function(parsedName) { - var className = classify(parsedName.name) + classify(parsedName.type), - factory = get(parsedName.root, className); - if (factory) { return factory; } + resolveHelper: function(parsedName) { + return this.resolveOther(parsedName) || Ember.Handlebars.helpers[parsedName.fullNameWithoutType]; }, - /** - Returns a human-readable description for a fullName. Used by the - Application namespace in assertions to describe the - precise name of the class that Ember is looking for, rather than - container keys. + Look up the specified object (from parsedName) on the appropriate + namespace (usually on the Application) @protected - @param {String} fullName the lookup string - @method lookupDescription + @param {Object} parsedName a parseName object with the parsed + fullName lookup string + @method resolveOther */ - lookupDescription: function(fullName) { - var parsedName = this.parseName(fullName); - - if (parsedName.type === 'template') { - return "template at " + parsedName.fullNameWithoutType.replace(/\./g, '/'); - } - - var description = parsedName.root + "." + classify(parsedName.name); - if (parsedName.type !== 'model') { description += classify(parsedName.type); } - - return description; - }, - - makeToString: function(factory, fullName) { - return factory.toString(); + resolveOther: function(parsedName) { + var className = classify(parsedName.name) + classify(parsedName.type), + factory = get(parsedName.root, className); + if (factory) { return factory; } } }); })(); @@ -40618,10 +40674,17 @@ container.injection('controller', 'target', 'router:main'); container.injection('controller', 'namespace', 'application:main'); container.injection('route', 'router', 'router:main'); + // DEBUGGING + container.register('resolver-for-debugging:main', container.resolver.__resolver__, { instantiate: false }); + container.injection('container-debug-adapter:main', 'resolver', 'resolver-for-debugging:main'); + container.injection('data-adapter:main', 'containerDebugAdapter', 'container-debug-adapter:main'); + // Custom resolver authors may want to register their own ContainerDebugAdapter with this key + container.register('container-debug-adapter:main', Ember.ContainerDebugAdapter); + return container; } }); /** @@ -40667,10 +40730,12 @@ } else { return fullName; } }; + resolve.__resolver__ = resolver; + return resolve; } Ember.runLoadHooks('Ember.Application', Ember.Application); @@ -40867,10 +40932,115 @@ /** @module ember @submodule ember-extension-support */ /** + The `ContainerDebugAdapter` helps the container and resolver interface + with tools that debug Ember such as the + [Ember Extension](https://github.com/tildeio/ember-extension) + for Chrome and Firefox. + + This class can be extended by a custom resolver implementer + to override some of the methods with library-specific code. + + The methods likely to be overridden are: + + * `canCatalogEntriesByType` + * `catalogEntriesByType` + + The adapter will need to be registered + in the application's container as `container-debug-adapter:main` + + Example: + + ```javascript + Application.initializer({ + name: "containerDebugAdapter", + + initialize: function(container, application) { + application.register('container-debug-adapter:main', require('app/container-debug-adapter')); + } + }); + ``` + + @class ContainerDebugAdapter + @namespace Ember + @extends Ember.Object +*/ +Ember.ContainerDebugAdapter = Ember.Object.extend({ + /** + The container of the application being debugged. + This property will be injected + on creation. + + @property container + @default null + */ + container: null, + + /** + The resolver instance of the application + being debugged. This property will be injected + on creation. + + @property resolver + @default null + */ + resolver: null, + + /** + Returns true if it is possible to catalog a list of available + classes in the resolver for a given type. + + @method canCatalogEntriesByType + @param {string} type The type. e.g. "model", "controller", "route" + @return {boolean} whether a list is available for this type. + */ + canCatalogEntriesByType: function(type) { + if (type === 'model' || type === 'template') return false; + return true; + }, + + /** + Returns the available classes a given type. + + @method catalogEntriesByType + @param {string} type The type. e.g. "model", "controller", "route" + @return {Array} An array of strings. + */ + catalogEntriesByType: function(type) { + var namespaces = Ember.A(Ember.Namespace.NAMESPACES), types = Ember.A(), self = this; + var typeSuffixRegex = new RegExp(Ember.String.classify(type) + "$"); + + namespaces.forEach(function(namespace) { + if (namespace !== Ember) { + for (var key in namespace) { + if (!namespace.hasOwnProperty(key)) { continue; } + if (typeSuffixRegex.test(key)) { + var klass = namespace[key]; + if (Ember.typeOf(klass) === 'class') { + types.push(Ember.String.dasherize(key.replace(typeSuffixRegex, ''))); + } + } + } + } + }); + return types; + } +}); + + +})(); + + + +(function() { +/** +@module ember +@submodule ember-extension-support +*/ +/** The `DataAdapter` helps a data persistence library interface with tools that debug Ember such as the [Ember Extension](https://github.com/tildeio/ember-extension) for Chrome and Firefox. @@ -40895,14 +41065,14 @@ Example: ```javascript Application.initializer({ - name: "dataAdapter", + name: "data-adapter", initialize: function(container, application) { - application.register('dataAdapter:main', DS.DataAdapter); + application.register('data-adapter:main', DS.DataAdapter); } }); ``` @class DataAdapter @@ -40923,11 +41093,21 @@ @property container @default null */ container: null, + /** + The container-debug-adapter which is used + to list all models. + + @property containerDebugAdapter + @default undefined + **/ + containerDebugAdapter: undefined, + + /** Number of attributes to send as columns. (Enough to make the record identifiable). @private @@ -40976,12 +41156,13 @@ watchModelTypes: function(typesAdded, typesUpdated) { var modelTypes = this.getModelTypes(), self = this, typesToSend, releaseMethods = Ember.A(); typesToSend = modelTypes.map(function(type) { - var wrapped = self.wrapModelType(type); - releaseMethods.push(self.observeModelType(type, typesUpdated)); + var klass = type.klass; + var wrapped = self.wrapModelType(klass, type.name); + releaseMethods.push(self.observeModelType(klass, typesUpdated)); return wrapped; }); typesAdded(typesToSend); @@ -40991,10 +41172,17 @@ }; this.releaseMethods.pushObject(release); return release; }, + _nameToClass: function(type) { + if (typeof type === 'string') { + type = this.container.lookupFactory('model:' + type); + } + return type; + }, + /** Fetch the records of a given type and observe them for changes. @public @method watchRecords @@ -41133,27 +41321,27 @@ Wraps a given model type and observes changes to it. @private @method wrapModelType @param {Class} type A model class - @param {Function} typesUpdated callback to call when the type changes + @param {String} Optional name of the class @return {Object} contains the wrapped type and the function to remove observers Format: type: {Object} the wrapped type The wrapped type has the following format: name: {String} name of the type count: {Integer} number of records available columns: {Columns} array of columns to describe the record object: {Class} the actual Model type class release: {Function} The function to remove observers */ - wrapModelType: function(type, typesUpdated) { + wrapModelType: function(type, name) { var release, records = this.getRecords(type), typeToSend, self = this; typeToSend = { - name: type.toString(), + name: name || type.toString(), count: Ember.get(records, 'length'), columns: this.columnsForType(type), object: type }; @@ -41167,21 +41355,48 @@ @private @method getModelTypes @return {Array} Array of model types */ - - // TODO: Use the resolver instead of looping over namespaces. getModelTypes: function() { - var namespaces = Ember.A(Ember.Namespace.NAMESPACES), types = Ember.A(), self = this; + var types, self = this, + containerDebugAdapter = this.get('containerDebugAdapter'); + if (containerDebugAdapter.canCatalogEntriesByType('model')) { + types = containerDebugAdapter.catalogEntriesByType('model'); + } else { + types = this._getObjectsOnNamespaces(); + } + // New adapters return strings instead of classes + return types.map(function(name) { + return { + klass: self._nameToClass(name), + name: name + }; + }).filter(function(type) { + return self.detect(type.klass); + }); + }, + + /** + Loops over all namespaces and all objects + attached to them + + @private + @method _getObjectsOnNamespaces + @return {Array} Array of model type strings + */ + _getObjectsOnNamespaces: function() { + var namespaces = Ember.A(Ember.Namespace.NAMESPACES), types = Ember.A(); + namespaces.forEach(function(namespace) { for (var key in namespace) { if (!namespace.hasOwnProperty(key)) { continue; } - var klass = namespace[key]; - if (self.detect(klass)) { - types.push(klass); + var name = Ember.String.dasherize(key); + if (!(namespace instanceof Ember.Application) && namespace.toString()) { + name = namespace + '/' + name; } + types.push(name); } }); return types; },