dist/ember.js in ember-source-1.2.0.beta.4 vs dist/ember.js in ember-source-1.2.0

- old
+ new

@@ -6,11 +6,11 @@ // License: Licensed under MIT license // See https://raw.github.com/emberjs/ember.js/master/LICENSE // ========================================================================== - // Version: 1.2.0-beta.4 + // Version: 1.2.0 (function() { /*global __fail__*/ /** @@ -192,11 +192,11 @@ // License: Licensed under MIT license // See https://raw.github.com/emberjs/ember.js/master/LICENSE // ========================================================================== - // Version: 1.2.0-beta.4 + // Version: 1.2.0 (function() { var define, requireModule; (function() { @@ -257,11 +257,11 @@ The core Runtime framework is based on the jQuery API with a number of performance optimizations. @class Ember @static - @version 1.2.0-beta.4 + @version 1.2.0 */ 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. @@ -284,14 +284,14 @@ /** @property VERSION @type String - @default '1.2.0-beta.4' + @default '1.2.0' @final */ -Ember.VERSION = '1.2.0-beta.4'; +Ember.VERSION = '1.2.0'; /** Standard environmental variables. You can define these in a global `ENV` variable before loading Ember to control various configuration settings. @@ -1663,10 +1663,12 @@ @method subscribe @namespace Ember.Instrumentation @param {String} [pattern] Namespaced event name. @param {Object} [object] Before and After hooks. + + @return {Subscriber} */ Ember.Instrumentation.subscribe = function(pattern, object) { var paths = pattern.split("."), path, regex = []; for (var i=0, l=paths.length; i<l; i++) { @@ -2613,19 +2615,21 @@ }; /** @method beginPropertyChanges @chainable + @private */ function beginPropertyChanges() { deferred++; } Ember.beginPropertyChanges = beginPropertyChanges; /** @method endPropertyChanges + @private */ function endPropertyChanges() { deferred--; if (deferred<=0) { beforeObserverSet.clear(); @@ -4686,11 +4690,11 @@ @method cacheFor @for Ember @param {Object} obj the object whose property you want to check @param {String} key the name of the property whose cached value you want to return - @return {*} the cached value + @return {Object} the cached value */ Ember.cacheFor = function cacheFor(obj, key) { var cache = metaFor(obj, false).cache; if (cache && key in cache) { @@ -4892,11 +4896,11 @@ @return {Ember.ComputedProperty} computed property which match the original value for property against a given RegExp */ registerComputed('match', function(dependentKey, regexp) { var value = get(this, dependentKey); - return typeof value === 'string' ? !!value.match(regexp) : false; + return typeof value === 'string' ? regexp.test(value) : false; }); /** A computed property that returns true if the provided dependent property is equal to the given value. @@ -5044,11 +5048,10 @@ /** A computed property that performs a logical `and` on the original values for the provided dependent properties. - Example ```javascript var Hamster = Ember.Object.extend({ readyForCamp: Ember.computed.and('hasTent', 'hasBackpack') @@ -5061,11 +5064,11 @@ hamster.get('readyForCamp'); // true ``` @method computed.and @for Ember - @param {String} dependentKey, [dependentKey...] + @param {String} dependentKey* @return {Ember.ComputedProperty} computed property which performs a logical `and` on the values of all the original values for properties. */ registerComputedWithProperties('and', function(properties) { for (var key in properties) { @@ -5092,11 +5095,11 @@ hamster.get('readyForRain'); // true ``` @method computed.or @for Ember - @param {String} dependentKey, [dependentKey...] + @param {String} dependentKey* @return {Ember.ComputedProperty} computed property which performs a logical `or` on the values of all the original values for properties. */ registerComputedWithProperties('or', function(properties) { for (var key in properties) { @@ -5123,11 +5126,11 @@ hamster.get('hasClothes'); // 'Hawaiian Shirt' ``` @method computed.any @for Ember - @param {String} dependentKey, [dependentKey...] + @param {String} dependentKey* @return {Ember.ComputedProperty} computed property which returns the first truthy value of given list of properties. */ registerComputedWithProperties('any', function(properties) { for (var key in properties) { @@ -5155,11 +5158,11 @@ hamster.get('clothes'); // ['Camp Hat', 'Camp Shirt'] ``` @method computed.map @for Ember - @param {String} dependentKey, [dependentKey...] + @param {String} dependentKey* @return {Ember.ComputedProperty} computed property which maps values of all passed properties in to an array. */ registerComputedWithProperties('collect', function(properties) { var res = []; @@ -5286,11 +5289,10 @@ return newValue != null ? newValue : get(this, defaultPath); }); }; - })(); (function() { @@ -15182,11 +15184,11 @@ return this; } }); - c = Context.create({ firstName: "John", lastName: "Doe" }); + c = Contact.create({ firstName: "John", lastName: "Doe" }); c.swapNames(); // returns c c.freeze(); c.swapNames(); // EXCEPTION ``` @@ -23518,60 +23520,85 @@ var parentView = get(this, '_parentView'); return parentView ? get(parentView, 'controller') : null; }).property('_parentView'), /** - Sends an action to component's controller. A component inherits its - controller from the context in which it is used. + Triggers a named action on the controller context where the component is used if + this controller has registered for notifications of the action. - By default, calling `sendAction()` will send an action with the name - of the component's `action` property. + 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: - For example, if the component had a property `action` with the value - `"addItem"`, calling `sendAction()` would send the `addItem` action - to the component's controller. - If you provide the `action` argument to `sendAction()`, that key will - be used to look up the action name. + ```javascript + App.PlayButtonComponent = Ember.Component.extend({ + click: function(){ + if (this.get('isPlaying')) { + this.triggerAction('play'); + } else { + this.triggerAction('stop'); + } + } + }); + ``` - For example, if the component had a property `playing` with the value - `didStartPlaying`, calling `sendAction('playing')` would send the - `didStartPlaying` action to the component's controller. + When used inside a template these component actions are configured to + trigger actions in the outer application context: - Whether or not you are using the default action or a named action, if - the action name is not defined on the component, calling `sendAction()` - does not have any effect. + ```handlebars + {{! application.hbs }} + {{play-button play="musicStarted" stop="musicStopped"}} + ``` - For example, if you call `sendAction()` on a component that does not have - an `action` property defined, no action will be sent to the controller, - nor will an exception be raised. + When the component receives a browser `click` event it translate this + interaction into application-specific semantics ("play" or "stop") and + triggers the specified action name on the controller for the template + where the component is used: - You can send a context object with the action by supplying the `context` - argument. The context will be supplied as the first argument in the - target's action method. Example: ```javascript - App.MyTreeComponent = Ember.Component.extend({ - click: function() { - this.sendAction('didClickTreeNode', this.get('node')); + App.ApplicationController = Ember.Controller.extend({ + actions: { + musicStarted: function(){ + // called when the play button is clicked + // and the music started playing + }, + musicStopped: function(){ + // called when the play button is clicked + // and the music stopped playing + } } }); + ``` - App.CategoriesController = Ember.Controller.extend({ - actions: { - didClickCategory: function(category) { - //Do something with the node/category that was clicked - } + If no action name is passed to `sendAction` a default name of "action" + is assumed. + + ```javascript + App.NextButtonComponent = Ember.Component.extend({ + click: function(){ + this.sendAction(); } }); ``` ```handlebars - {{! categories.hbs}} - {{my-tree didClickTreeNode='didClickCategory'}} + {{! application.hbs }} + {{next-button action="playNextSongInAlbum"}} ``` + ```javascript + App.ApplicationController = Ember.Controller.extend({ + actions: { + playNextSongInAlbum: function(){ + ... + } + } + }); + ``` + @method sendAction @param [action] {String} the action to trigger @param [context] {*} a context to send with the action */ sendAction: function(action) { @@ -24630,10 +24657,12 @@ var options = arguments[arguments.length - 1]; + Ember.assert("`blockHelperMissing` was invoked without a helper name, which is most likely due to a mismatch between the version of Ember.js you're running now and the one used to precompile your templates. Please make sure the version of `ember-handlebars-compiler` you're using is up to date.", path); + var helper = Ember.Handlebars.resolveHelper(options.data.view.container, path); if (helper) { return helper.apply(this, slice.call(arguments, 1)); } @@ -25563,10 +25592,12 @@ // be done with it. data.buffer.push(handlebarsGet(currentContext, property, options)); } } +EmberHandlebars.bind = bind; + function simpleBind(currentContext, property, options) { var data = options.data, view = data.view, normalized, observer, pathRoot, output; @@ -27328,36 +27359,84 @@ @module ember @submodule ember-handlebars */ /** - `partial` renders a template directly using the current context. - If needed the context can be set using the `{{#with foo}}` helper. + The `partial` helper renders another template without + changing the template context: - ```html - <script type="text/x-handlebars" data-template-name="header_bar"> - {{#with currentUser}} - {{partial user_info}} - {{/with}} - </script> + ```handlebars + {{foo}} + {{partial "nav"}} ``` - The `data-template-name` attribute of a partial template - is prefixed with an underscore. + 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 + `{{foo}}`, it would print the same thing as the `{{foo}}` + in the above example. - ```html - <script type="text/x-handlebars" data-template-name="_user_info"> - <span>Hello {{username}}!</span> - </script> + 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 + to a property containing a template name, e.g.: + + ```handlebars + {{partial someTemplateName}} ``` + The above example will look up the value of `someTemplateName` + on the template context (e.g. a controller) and use that + value as the name of the template to render. If the resolved + value is falsy, nothing will be rendered. If `someTemplateName` + changes, the partial will be re-rendered using the new template + name. + + ## Setting the partial's context with `with` + + The `partial` helper can be used in conjunction with the `with` + helper to set a context that will be used by the partial: + + ```handlebars + {{#with currentUser}} + {{partial "user_info"}} + {{/with}} + ``` + @method partial @for Ember.Handlebars.helpers @param {String} partialName the name of the template to render minus the leading underscore */ Ember.Handlebars.registerHelper('partial', function(name, options) { + + var context = (options.contexts && options.contexts.length) ? options.contexts[0] : this; + + if (options.types[0] === "ID") { + // Helper was passed a property path; we need to + // create a binding that will re-render whenever + // this property changes. + options.fn = function(context, fnOptions) { + var partialName = Ember.Handlebars.get(context, name, fnOptions); + renderPartial(context, partialName, fnOptions); + }; + + return Ember.Handlebars.bind.call(context, name, options, true, exists); + } else { + // Render the partial right into parent template. + renderPartial(context, name, options); + } +}); + +function exists(value) { + return !Ember.isNone(value); +} + +function renderPartial(context, name, options) { var nameParts = name.split("/"), lastPart = nameParts[nameParts.length - 1]; nameParts[nameParts.length - 1] = "_" + lastPart; @@ -27368,12 +27447,12 @@ Ember.assert("Unable to find partial with name '"+name+"'.", template || deprecatedTemplate); template = template || deprecatedTemplate; - template(this, { data: options.data }); -}); + template(context, { data: options.data }); +} })(); @@ -32273,9 +32352,27 @@ this.transitionTo('fourOhFour'); } } }); ``` + + Transition to a nested route + + ```javascript + App.Router.map(function() { + this.resource('articles', { path: '/articles' }, function() { + this.route('new'); + }); + }); + + App.IndexRoute = Ember.Route.extend({ + actions: { + transitionToNewArticle: function() { + this.transitionTo('articles.new'); + } + } + }); + ``` Multiple Models Example ```javascript App.Router.map(function() {