dist/ember.prod.js in ember-source-0.0.6 vs dist/ember.prod.js in ember-source-0.0.7

- old
+ new

@@ -10635,11 +10635,15 @@ return resolve(entity); } else { return resolve(fulfillment); } }, function(reason) { - return reject(reason); + if (reason === promise) { + return reject(entity); + } else { + return reject(reason); + } }); }, /** Resolve a Deferred object and call any `doneCallbacks` with the given args. @@ -10667,11 +10671,11 @@ reject: function(value) { get(this, '_deferred').reject(value); }, _deferred: Ember.computed(function() { - return new RSVP.defer(); + return RSVP.defer(); }) }); })(); @@ -14500,11 +14504,11 @@ // create a new buffer relative to the original using the // provided buffer operation (for example, `insertAfter` will // insert a new buffer after the "parent buffer"). var tagName = this.tagName; - if (Ember.isNone(tagName)) { + if (tagName === null || tagName === undefined) { tagName = 'div'; } var buffer = this.buffer = parentBuffer && parentBuffer.begin(tagName) || Ember.RenderBuffer(tagName); this.transitionTo('inBuffer', false); @@ -15290,11 +15294,11 @@ }).property('layoutName'), templateForName: function(name, type) { if (!name) { return; } - var container = this.container || (Ember.Container && Ember.Container.defaultContainer); + var container = this.container; return container && container.lookup('template:' + name); }, /** The object from which templates should access properties. @@ -17892,13 +17896,14 @@ `Ember.CollectionView`, ensuring that the view reflects the model. This array observer is added in `contentDidChange`. @method arrayDidChange - @param {Array} addedObjects the objects that were added to the content - @param {Array} removedObjects the objects that were removed from the content - @param {Number} changeIndex the index at which the changes occurred + @param {Array} content the managed collection of objects + @param {Number} start the index at which the changes occurred + @param {Number} removed number of object removed from content + @param {Number} added number of object added to content */ arrayDidChange: function(content, start, removed, added) { var itemViewClass = get(this, 'itemViewClass'), addedViews = [], view, item, idx, len; @@ -22436,13 +22441,13 @@ valuePath = get(this, 'optionValuePath').replace(/^content\.?/, ''), selectedValue = (valuePath ? get(this, 'selection.' + valuePath) : get(this, 'selection')), selection; if (value !== selectedValue) { - selection = content.find(function(obj) { + selection = content ? content.find(function(obj) { return value === (valuePath ? get(obj, valuePath) : obj); - }); + }) : null; this.set('selection', selection); } }, 'value'), @@ -22460,11 +22465,11 @@ _changeSingle: function() { var selectedIndex = this.$()[0].selectedIndex, content = get(this, 'content'), prompt = get(this, 'prompt'); - if (!get(content, 'length')) { return; } + if (!content || !get(content, 'length')) { return; } if (prompt && selectedIndex === 0) { set(this, 'selection', null); return; } if (prompt) { selectedIndex -= 1; } set(this, 'selection', content.objectAt(selectedIndex)); }, @@ -23053,18 +23058,18 @@ return output; }, recognize: function(path) { - var states = [ this.rootState ], i, l; + var states = [ this.rootState ], + pathLen, i, l; // DEBUG GROUP path - var pathLen = path.length; - if (path.charAt(0) !== "/") { path = "/" + path; } + pathLen = path.length; if (pathLen > 1 && path.charAt(pathLen - 1) === "/") { path = path.substr(0, pathLen - 1); } for (i=0, l=path.length; i<l; i++) { @@ -23436,15 +23441,15 @@ }, isActive: function(handlerName) { var contexts = [].slice.call(arguments, 1); - var currentHandlerInfos = this.currentHandlerInfos, - found = false, object, handlerInfo; + var targetHandlerInfos = this.targetHandlerInfos, + found = false, names, object, handlerInfo, handlerObj; - for (var i=currentHandlerInfos.length-1; i>=0; i--) { - handlerInfo = currentHandlerInfos[i]; + for (var i=targetHandlerInfos.length-1; i>=0; i--) { + handlerInfo = targetHandlerInfos[i]; if (handlerInfo.name === handlerName) { found = true; } if (found) { if (contexts.length === 0) { break; } @@ -23492,10 +23497,11 @@ var handler = router.getHandler('loading'); if (handler) { if (handler.enter) { handler.enter(); } if (handler.setup) { handler.setup(); } + if (handler.setupTemplate) { handler.setupTemplate(); } } } } /** @@ -23534,10 +23540,11 @@ loaded(router); var handler = router.getHandler('failure'); if (handler){ if (handler.enter) { handler.enter(); } if (handler.setup) { handler.setup(error); } + if (handler.setupTemplate) { handler.setupTemplate(error); } } } /** @private @@ -23661,32 +23668,44 @@ */ function setupContexts(router, handlerInfos) { var partition = partitionHandlers(router.currentHandlerInfos || [], handlerInfos); - router.currentHandlerInfos = handlerInfos; + router.targetHandlerInfos = handlerInfos; - eachHandler(partition.exited, function(handler, context) { + eachHandler(partition.exited, function(handler, context, handlerInfo) { delete handler.context; if (handler.exit) { handler.exit(); } }); - eachHandler(partition.updatedContext, function(handler, context) { + var currentHandlerInfos = partition.unchanged.slice(); + router.currentHandlerInfos = currentHandlerInfos; + + eachHandler(partition.updatedContext, function(handler, context, handlerInfo) { setContext(handler, context); if (handler.setup) { handler.setup(context); } + currentHandlerInfos.push(handlerInfo); }); var aborted = false; - eachHandler(partition.entered, function(handler, context) { + eachHandler(partition.entered, function(handler, context, handlerInfo) { if (aborted) { return; } if (handler.enter) { handler.enter(); } + setContext(handler, context); + if (handler.setup) { if (false === handler.setup(context)) { aborted = true; } } + if (!aborted) { + if (handler.setupTemplate) { + handler.setupTemplate(context); + } + currentHandlerInfos.push(handlerInfo); + } }); if (!aborted && router.didTransition) { router.didTransition(handlerInfos); } @@ -23705,11 +23724,11 @@ for (var i=0, l=handlerInfos.length; i<l; i++) { var handlerInfo = handlerInfos[i], handler = handlerInfo.handler, context = handlerInfo.context; - callback(handler, context); + callback(handler, context, handlerInfo); } } /** @private @@ -23731,19 +23750,20 @@ * exited: the handler was active in the old URL, but is no longer active. * entered: the handler was not active in the old URL, but is now active. - The PartitionedHandlers structure has three fields: + The PartitionedHandlers structure has four fields: * `updatedContext`: a list of `HandlerInfo` objects that represent handlers that remain active but have a changed context * `entered`: a list of `HandlerInfo` objects that represent handlers that are newly active * `exited`: a list of `HandlerInfo` objects that are no longer active. + * `unchanged`: a list of `HanderInfo` objects that remain active. @param {Array[HandlerInfo]} oldHandlers a list of the handler information for the previous URL (or `[]` if this is the first handled transition) @param {Array[HandlerInfo]} newHandlers a list of the handler @@ -23753,11 +23773,12 @@ */ function partitionHandlers(oldHandlers, newHandlers) { var handlers = { updatedContext: [], exited: [], - entered: [] + entered: [], + unchanged: [] }; var handlerChanged, contextChanged, i, l; for (i=0, l=newHandlers.length; i<l; i++) { @@ -23771,10 +23792,12 @@ handlers.entered.push(newHandler); if (oldHandler) { handlers.exited.unshift(oldHandler); } } else if (contextChanged || oldHandler.context !== newHandler.context) { contextChanged = true; handlers.updatedContext.push(newHandler); + } else { + handlers.unchanged.push(oldHandler); } } for (i=newHandlers.length, l=oldHandlers.length; i<l; i++) { handlers.exited.unshift(oldHandlers[i]); @@ -23810,11 +23833,10 @@ if (handler.contextDidChange) { handler.contextDidChange(); } } return Router; }); - })(); (function() { @@ -24033,10 +24055,26 @@ handleURL: function(url) { this.router.handleURL(url); this.notifyPropertyChange('url'); }, + /** + Transition to another route via the `routeTo` event which + will by default be handled by ApplicationRoute. + + @method routeTo + @param {TransitionEvent} transitionEvent + */ + routeTo: function(transitionEvent) { + var handlerInfos = this.router.currentHandlerInfos; + if (handlerInfos) { + transitionEvent.sourceRoute = handlerInfos[handlerInfos.length - 1].handler; + } + + this.send('routeTo', transitionEvent); + }, + transitionTo: function(name) { var args = [].slice.call(arguments); doTransition(this, 'transitionTo', args); }, @@ -24113,10 +24151,16 @@ container.register(routeName, DefaultRoute.extend()); handler = container.lookup(routeName); } + if (name === 'application') { + // Inject default `routeTo` handler. + handler.events = handler.events || {}; + handler.events.routeTo = handler.events.routeTo || Ember.TransitionEvent.defaultHandler; + } + handler.routeName = name; return handler; }; } @@ -24269,10 +24313,21 @@ @method activate */ activate: Ember.K, /** + Transition to another route via the `routeTo` event which + will by default be handled by ApplicationRoute. + + @method routeTo + @param {TransitionEvent} transitionEvent + */ + routeTo: function(transitionEvent) { + this.router.routeTo(transitionEvent); + }, + + /** Transition into another route. Optionally supply a model for the route in question. The model will be serialized into the URL using the `serialize` hook. @method transitionTo @@ -24395,19 +24450,30 @@ this.setupControllers(controller, context); } else { this.setupController(controller, context); } + }, + /** + @private + + This hook is an entry point for router.js. It is invoked when + we're entering a route, after the route's context has been setup. + + @method setupTemplate + */ + setupTemplate: function(context) { if (this.renderTemplates) { this.renderTemplates(context); } else { - this.renderTemplate(controller, context); + this.renderTemplate(this.controller, context); } }, + /** A hook you can implement to optionally redirect to another route. If you call `this.transitionTo` from inside of this hook, this route will not be entered in favor of the other hook. @@ -24716,11 +24782,11 @@ teardownView(this); } }); function parentRoute(route) { - var handlerInfos = route.router.router.currentHandlerInfos; + var handlerInfos = route.router.router.targetHandlerInfos; var parent, current; for (var i=0, l=handlerInfos.length; i<l; i++) { current = handlerInfos[i].handler; @@ -24821,16 +24887,75 @@ })(); (function() { +/** +@module ember +@submodule ember-routing +*/ + +/** + A TransitionEvent is passed as the argument for `transitionTo` + events and contains information about an attempted transition + that can be modified or decorated by leafier `transitionTo` event + handlers before the actual transition is committed by ApplicationRoute. + + @class TransitionEvent + @namespace Ember + @extends Ember.Deferred + */ +Ember.TransitionEvent = Ember.Object.extend({ + + /** + The Ember.Route method used to perform the transition. Presently, + the only valid values are 'transitionTo' and 'replaceWith'. + */ + transitionMethod: 'transitionTo', + destinationRouteName: null, + sourceRoute: null, + contexts: null, + + init: function() { + this._super(); + this.contexts = this.contexts || []; + }, + + /** + Convenience method that returns an array that can be used for + legacy `transitionTo` and `replaceWith`. + */ + transitionToArgs: function() { + return [this.destinationRouteName].concat(this.contexts); + } +}); + + +Ember.TransitionEvent.reopenClass({ + /** + This is the default transition event handler that will be injected + into ApplicationRoute. The context, like all route event handlers in + the events hash, will be an `Ember.Route`. + */ + defaultHandler: function(transitionEvent) { + var router = this.router; + router[transitionEvent.transitionMethod].apply(router, transitionEvent.transitionToArgs()); + } +}); + })(); (function() { + +})(); + + + +(function() { Ember.onLoad('Ember.Handlebars', function() { var handlebarsResolve = Ember.Handlebars.resolveParams, map = Ember.ArrayPolyfills.map, get = Ember.get; @@ -24934,14 +25059,25 @@ event.preventDefault(); if (this.bubbles === false) { event.stopPropagation(); } var router = this.get('router'); - if (this.get('replace')) { - router.replaceWith.apply(router, args(this, router)); + if (Ember.ENV.ENABLE_ROUTE_TO) { + + var routeArgs = args(this, router); + + router.routeTo(Ember.TransitionEvent.create({ + transitionMethod: this.get('replace') ? 'replaceWith' : 'transitionTo', + destinationRouteName: routeArgs[0], + contexts: routeArgs.slice(1) + })); } else { - router.transitionTo.apply(router, args(this, router)); + if (this.get('replace')) { + router.replaceWith.apply(router, args(this, router)); + } else { + router.transitionTo.apply(router, args(this, router)); + } } }, href: Ember.computed(function() { if (this.get('tagName') !== 'a') { return false; } @@ -27166,11 +27302,10 @@ container for. @return {Ember.Container} the built container */ buildContainer: function(namespace) { var container = new Ember.Container(); - Ember.Container.defaultContainer = Ember.Container.defaultContainer || container; container.set = Ember.set; container.normalize = normalize; container.resolver = resolverFor(namespace); container.optionsForType('view', { singleton: false }); @@ -28636,69 +28771,70 @@ (function() { /*globals EMBER_APP_BEING_TESTED */ var Promise = Ember.RSVP.Promise, pendingAjaxRequests = 0, - originalFind; + originalFind, + slice = [].slice, + get = Ember.get; -function visit(url) { - var promise = new Promise(); - Ember.run(EMBER_APP_BEING_TESTED, EMBER_APP_BEING_TESTED.handleURL, url); - wait(promise, promise.resolve); - return promise; +function visit(app, url) { + Ember.run(app, app.handleURL, url); + return wait(app); } -function click(selector) { - var promise = new Promise(); +function click(app, selector) { Ember.run(function() { - Ember.$(selector).click(); + app.$(selector).click(); }); - wait(promise, promise.resolve); - return promise; + return wait(app); } -function fillIn(selector, text) { - var promise = new Promise(); - var $el = find(selector); +function fillIn(app, selector, text) { + var $el = find(app, selector); Ember.run(function() { $el.val(text); }); + return wait(app); +} - wait(promise, promise.resolve); - return promise; +function find(app, selector) { + return app.$(get(app, 'rootElement')).find(selector); } -function find(selector) { - return Ember.$('.ember-application').find(selector); +function wait(app, value) { + return new Promise(function(resolve) { + stop(); + var watcher = setInterval(function() { + var routerIsLoading = app.__container__.lookup('router:main').router.isLoading; + if (routerIsLoading) { return; } + if (pendingAjaxRequests) { return; } + if (Ember.run.hasScheduledTimers() || Ember.run.currentRunLoop) { return; } + clearInterval(watcher); + start(); + Ember.run(function() { + resolve(value); + }); + }, 10); + }); } -function wait(target, method) { - if (!method) { - method = target; - target = null; - } - stop(); - var watcher = setInterval(function() { - var routerIsLoading = EMBER_APP_BEING_TESTED.__container__.lookup('router:main').router.isLoading; - if (routerIsLoading) { return; } - if (pendingAjaxRequests) { return; } - if (Ember.run.hasScheduledTimers() || Ember.run.currentRunLoop) { return; } - clearInterval(watcher); - start(); - Ember.run(target, method); - }, 200); +function curry(app, fn) { + return function() { + var args = slice.call(arguments); + args.unshift(app); + return fn.apply(app, args); + }; } Ember.Application.reopen({ setupForTesting: function() { this.deferReadiness(); this.Router.reopen({ location: 'none' }); - - window.EMBER_APP_BEING_TESTED = this; }, injectTestHelpers: function() { Ember.$(document).ajaxStart(function() { pendingAjaxRequests++; @@ -28706,23 +28842,27 @@ Ember.$(document).ajaxStop(function() { pendingAjaxRequests--; }); - window.visit = visit; - window.click = click; - window.fillIn = fillIn; + // todo do this safer. + window.visit = curry(this, visit); + window.click = curry(this, click); + window.fillIn = curry(this, fillIn); originalFind = window.find; - window.find = find; + window.find = curry(this, find); + window.wait = curry(this, wait); }, removeTestHelpers: function() { window.visit = null; window.click = null; window.fillIn = null; + window.wait = null; window.find = originalFind; } }); + })(); (function() {