dist/ember.js in ember-source-1.4.0.beta.3 vs dist/ember.js in ember-source-1.4.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.4.0-beta.3 + * @version 1.4.0-beta.4+pre.88c597fa */ (function() { /*global __fail__*/ @@ -196,11 +196,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.4.0-beta.3 + * @version 1.4.0-beta.4 */ (function() { var define, requireModule, require, requirejs; @@ -279,11 +279,11 @@ The core Runtime framework is based on the jQuery API with a number of performance optimizations. @class Ember @static - @version 1.4.0-beta.3 + @version 1.4.0-beta.4+pre.88c597fa */ 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. @@ -306,14 +306,14 @@ /** @property VERSION @type String - @default '1.4.0-beta.3' + @default '1.4.0-beta.4+pre.88c597fa' @static */ -Ember.VERSION = '1.4.0-beta.3'; +Ember.VERSION = '1.4.0-beta.4+pre.88c597fa'; /** Standard environmental variables. You can define these in a global `EmberENV` variable before loading Ember to control various configuration settings. @@ -2931,20 +2931,10 @@ Sets the value of a property on an object, respecting computed properties and notifying observers and other listeners of the change. If the property is not defined but the object implements the `setUnknownProperty` method then that will be invoked as well. - If you plan to run on IE8 and older browsers then you should use this - method anytime you want to set a property on an object that you don't - know for sure is private. (Properties beginning with an underscore '_' - are considered private.) - - On all newer browsers, you only need to use this method to set - properties if the property might not be defined on the object and you want - to respect the `setUnknownProperty` handler. Otherwise you can ignore this - method. - @method set @for Ember @param {Object} obj The object to modify. @param {String} keyName The property key to set @param {Object} value The value to set @@ -3697,16 +3687,11 @@ }); } else { obj[keyName] = undefined; // make enumerable } - - if (desc.func && desc._dependentCPs) { - addImplicitCPs(obj, desc._dependentCPs, meta); - } - - } else { + } else { descs[keyName] = undefined; // shadow descriptor in proto if (desc == null) { value = data; if (MANDATORY_SETTER && watching) { @@ -3738,26 +3723,10 @@ return this; }; - var addImplicitCPs = function defineImplicitCPs(obj, implicitCPs, meta) { - var cp, key, length = implicitCPs.length; - - for (var i=0; i<length; ++i) { - cp = implicitCPs[i]; - key = cp.implicitCPKey; - - Ember.defineProperty(obj, key, cp, undefined, meta); - - if (cp._dependentCPs) { - addImplicitCPs(obj, cp._dependentCPs, meta); - } - } - }; - - })(); (function() { @@ -4492,12 +4461,10 @@ unwatch = Ember.unwatch; - - var expandProperties = Ember.expandProperties; // .......................................................... // DEPENDENT KEYS @@ -4656,30 +4623,23 @@ @constructor */ function ComputedProperty(func, opts) { this.func = func; - setDependentKeys(this, opts && opts.dependentKeys); + this._dependentKeys = opts && opts.dependentKeys; + this._cacheable = (opts && opts.cacheable !== undefined) ? opts.cacheable : true; this._readOnly = opts && (opts.readOnly !== undefined || !!opts.readOnly); } Ember.ComputedProperty = ComputedProperty; ComputedProperty.prototype = new Ember.Descriptor(); var ComputedPropertyPrototype = ComputedProperty.prototype; - ComputedPropertyPrototype.toString = function() { - if (this.implicitCPKey) { - return this.implicitCPKey; - } - return Ember.Descriptor.prototype.toString.apply(this, arguments); - }; - - /** Properties are cacheable by default. Computed property will automatically cache the return value of your function until one of the dependent keys changes. Call `volatile()` to set it into non-cached mode. When in this mode @@ -4781,12 +4741,13 @@ for (var i = 0, l = arguments.length; i < l; i++) { expandProperties(arguments[i], addArg); } - setDependentKeys(this, args); + this._dependentKeys = args; + return this; }; /** In some cases, you may want to annotate computed properties with additional @@ -5044,89 +5005,35 @@ } var registerComputed, registerComputedWithProperties; - var guidFor = Ember.guidFor, - map = Ember.EnumerableUtils.map, - filter = Ember.EnumerableUtils.filter, - typeOf = Ember.typeOf; - var implicitKey = function (cp) { - return [guidFor(cp)].concat(cp._dependentKeys).join('_'); - }; - - var normalizeDependentKey = function (key) { - if (key instanceof Ember.ComputedProperty) { - return implicitKey(key); - } else if (typeof key === 'string' || key instanceof String || typeof key === 'object' || typeof key === 'number') { - return key; - } else { - Ember.assert('Unexpected dependent key ' + key + ' of type ' + typeof(key), false); - } - }; - - var normalizeDependentKeys = function (keys) { - return map(keys, function (key) { - return normalizeDependentKey(key); - }); - }; - - var selectDependentCPs = function (keys) { - return filter(keys, function (key) { - return key instanceof Ember.ComputedProperty; - }); - }; - - var setDependentKeys = function(cp, dependentKeys) { - if (dependentKeys) { - cp._dependentKeys = normalizeDependentKeys(dependentKeys); - cp._dependentCPs = selectDependentCPs(dependentKeys); - cp.implicitCPKey = implicitKey(cp); - } else { - cp._dependentKeys = cp._dependentCPs = []; - delete cp.implicitCPKey; - } - }; - // expose `normalizeDependentKey[s]` so user CP macros can easily support - // composition - Ember.computed.normalizeDependentKey = normalizeDependentKey; - Ember.computed.normalizeDependentKeys = normalizeDependentKeys; - registerComputed = function (name, macro) { Ember.computed[name] = function(dependentKey) { - var args = normalizeDependentKeys(a_slice.call(arguments)); + var args = a_slice.call(arguments); return Ember.computed(dependentKey, function() { return macro.apply(this, args); }); }; }; - - registerComputedWithProperties = function(name, macro) { Ember.computed[name] = function() { - var args = a_slice.call(arguments); - var properties = normalizeDependentKeys(args); + var properties = a_slice.call(arguments); var computed = Ember.computed(function() { return macro.apply(this, [getProperties(this, properties)]); }); - return computed.property.apply(computed, args); + return computed.property.apply(computed, properties); }; }; - Ember.computed.literal = function (value) { - return Ember.computed(function () { - return value; - }); - }; - /** A computed property that returns true if the value of the dependent property is null, an empty string, empty array, or empty function. Note: When using `Ember.computed.empty` to watch an array make sure to @@ -5652,56 +5559,11 @@ return Ember.computed(dependentKey, function() { return get(this, dependentKey); }); }; -if (Ember.FEATURES.isEnabled('computed-read-only')) { /** - Where `computed.oneWay` provides oneWay bindings, `computed.readOnly` provides - a readOnly one way binding. Very often when using `computed.oneWay` one does - not also want changes to propogate back up, as they will replace the value. - - This prevents the reverse flow, and also throws an exception when it occurs. - - Example - - ```javascript - User = Ember.Object.extend({ - firstName: null, - lastName: null, - nickName: Ember.computed.readOnly('firstName') - }); - - user = User.create({ - firstName: 'Teddy', - lastName: 'Zeenny' - }); - - user.get('nickName'); - # 'Teddy' - - user.set('nickName', 'TeddyBear'); - # throws Exception - # throw new Ember.Error('Cannot Set: nickName on: <User:ember27288>' );` - - user.get('firstName'); - # 'Teddy' - ``` - - @method computed.readOnly - @for Ember - @param {String} dependentKey - @return {Ember.ComputedProperty} computed property which creates a - one way computed property to the original value for property. -*/ -Ember.computed.readOnly = function(dependentKey) { - return Ember.computed(dependentKey, function() { - return get(this, dependentKey); - }).readOnly(); -}; -} -/** A computed property that acts like a standard getter and setter, but returns the value at the provided `defaultPath` if the property itself has not been set to a value Example @@ -6373,11 +6235,11 @@ if (timers[i + 1] === timer) { timers.splice(i, 2); // remove the two elements return true; } } - } else if (window.toString.call(timer) === "[object Array]"){ // we're cancelling a throttle or debounce + } else if (Object.prototype.toString.call(timer) === "[object Array]"){ // we're cancelling a throttle or debounce return this._cancelItem(findThrottler, throttlers, timer) || this._cancelItem(findDebouncee, debouncees, timer); } else { return; // timer was null or not a timer } @@ -6487,10 +6349,11 @@ } __exports__.Backburner = Backburner; }); + })(); (function() { @@ -7983,11 +7846,11 @@ Note that Mixins are created with `Ember.Mixin.create`, not `Ember.Mixin.extend`. Note that mixins extend a constructor's prototype so arrays and object literals defined as properties will be shared amongst objects that implement the mixin. - If you want to define an property in a mixin that is not shared, you can define + If you want to define a property in a mixin that is not shared, you can define it either as a computed property or have it be created on initialization of the object. ```javascript //filters array will be shared amongst any object implementing mixin App.Filterable = Ember.Mixin.create({ @@ -12048,60 +11911,13 @@ capitalize: function(str) { return str.charAt(0).toUpperCase() + str.substr(1); } }; -if (Ember.FEATURES.isEnabled("string-humanize")) { - /** - Returns the Humanized form of a string - Replaces underscores with spaces, and capitializes first character - of string. Also strips "_id" suffixes. - ```javascript - 'first_name'.humanize() // 'First name' - 'user_id'.humanize() // 'User' - ``` - @method humanize - @param {String} str The string to humanize. - @return {String} The humanized string. - */ - - Ember.String.humanize = function(str) { - return str.replace(/_id$/, ''). - replace(/_/g, ' '). - replace(/^\w/g, function(s){ - return s.toUpperCase(); - }); - }; -} - -if (Ember.FEATURES.isEnabled("string-parameterize")) { - /** - Transforms a string so that it may be used as part of a 'pretty' / SEO friendly URL. - - ```javascript - 'My favorite items.'.parameterize(); // 'my-favorite-items' - 'action_name'.parameterize(); // 'action-name' - '100 ways Ember.js is better than Angular.'.parameterize(); // '100-ways-emberjs-is-better-than-angular' - ``` - - @method parameterize - @param {String} str The string to parameterize. - @return {String} the parameterized string. - */ - Ember.String.parameterize = function(str) { - return str.replace(STRING_PARAMETERIZE_REGEXP_1, '-') // replace underscores, slashes and spaces with separator - .replace(STRING_PARAMETERIZE_REGEXP_2, '') // remove non-alphanumeric characters except the separator - .replace(STRING_PARAMETERIZE_REGEXP_3, '-') // replace multiple occurring separators - .replace(STRING_PARAMETERIZE_REGEXP_4, '') // trim leading and trailing separators - .toLowerCase(); - }; -} - - })(); (function() { @@ -12120,17 +11936,11 @@ dasherize = Ember.String.dasherize, underscore = Ember.String.underscore, capitalize = Ember.String.capitalize, classify = Ember.String.classify; -if (Ember.FEATURES.isEnabled("string-humanize")) { - var humanize = Ember.String.humanize; -} -if (Ember.FEATURES.isEnabled("string-parameterize")) { - var parameterize = Ember.String.parameterize; -} if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.String) { /** See [Ember.String.fmt](/api/classes/Ember.String.html#method_fmt). @@ -12220,34 +12030,12 @@ */ String.prototype.capitalize = function() { return capitalize(this); }; - if (Ember.FEATURES.isEnabled("string-humanize")) { - /** - See [Ember.String.humanize](/api/classes/Ember.String.html#method_humanize). - - @method humanize - @for String - */ - String.prototype.humanize = function() { - return humanize(this); - }; - } - - if (Ember.FEATURES.isEnabled("string-parameterize")) { - /** - See [Ember.String.parameterize](/api/classes/Ember.String.html#method_parameterize). - - @method parameterize - @for String - */ - String.prototype.parameterize = function() { - return parameterize(this); - }; - } - + + } })(); @@ -14506,15 +14294,27 @@ @param {Function} callback The callback to execute @param {Object} [target] The target object to use @return {Boolean} `true` if the passed function returns `true` for any item */ any: function(callback, target) { - var found = this.find(function(x, idx, i) { - return !!callback.call(target, x, idx, i); - }); + var len = get(this, 'length'), + context = popCtx(), + found = false, + last = null, + next, idx; - return typeof found !== 'undefined'; + if (target === undefined) { target = null; } + + for (idx = 0; idx < len && !found; idx++) { + next = this.nextObject(idx, last, context); + found = callback.call(target, next, idx, this); + last = next; + } + + next = last = null; + context = pushCtx(context); + return found; }, /** Returns `true` if the passed function returns true for any item in the enumeration. This corresponds with the `some()` method in JavaScript 1.6. @@ -15749,24 +15549,26 @@ }, setValue: function(newValue, triggerObservers) { // This lets sugars force a recomputation, handy for very simple // implementations of eg max. - if (newValue !== undefined) { - var fireObservers = triggerObservers && (newValue !== this.cache[this.propertyName]); + if (newValue === this.cache[this.propertyName]) { + return; + } - if (fireObservers) { - propertyWillChange(this.context, this.propertyName); - } + if (triggerObservers) { + propertyWillChange(this.context, this.propertyName); + } + if (newValue === undefined) { + delete this.cache[this.propertyName]; + } else { this.cache[this.propertyName] = newValue; + } - if (fireObservers) { - propertyDidChange(this.context, this.propertyName); - } - } else { - delete this.cache[this.propertyName]; + if (triggerObservers) { + propertyDidChange(this.context, this.propertyName); } } }; /** @@ -18020,11 +17822,11 @@ return actionContext; } }).property('actionContext'), /** - Send an "action" with an "actionContext" to a "target". The action, 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'), @@ -18500,11 +18302,11 @@ */ willMergeMixin: function(props) { var hashName; if (!props._actions) { - Ember.assert(this + " 'actions' should not be a function", typeof(props.actions) !== 'function'); + Ember.assert("'actions' should not be a function", typeof(props.actions) !== 'function'); if (typeOf(props.actions) === 'object') { hashName = 'actions'; } else if (typeOf(props.events) === 'object') { Ember.deprecate('Action handlers contained in an `events` object are deprecated in favor of putting them in an `actions` object', false); @@ -21021,12 +20823,11 @@ } }); ``` The itemController instances will have a `parentController` property set to - either the the `parentController` property of the `ArrayController` - or to the `ArrayController` instance itself. + to the `ArrayController` instance. @class ArrayController @namespace Ember @extends Ember.ArrayProxy @uses Ember.SortableMixin @@ -21123,10 +20924,19 @@ content: Ember.computed(function () { return Ember.A(); }), + /** + * Flag to mark as being "virtual". Used to keep this instance + * from participating in the parentController hierarchy. + * + * @private + * @type Boolean + */ + _isVirtual: false, + controllerAt: function(idx, object, controllerClass) { var container = get(this, 'container'), subControllers = get(this, '_subControllers'), subController = subControllers[idx], factory, fullName; @@ -21136,14 +20946,18 @@ fullName = "controller:" + controllerClass; if (!container.has(fullName)) { throw new Ember.Error('Could not resolve itemController: "' + controllerClass + '"'); } - + var parentController; + if (this._isVirtual) { + parentController = get(this, 'parentController'); + } + parentController = parentController || this; subController = container.lookupFactory(fullName).create({ target: this, - parentController: get(this, 'parentController') || this, + parentController: parentController, content: object }); subControllers[idx] = subController; @@ -23503,10 +23317,12 @@ // Loop through all of the configured bindings. These will be either // property names ('isUrgent') or property paths relative to the view // ('content.isUrgent') a_forEach(classBindings, function(binding) { + Ember.assert("classNameBindings must not have spaces in them. Multiple class name bindings can be provided as elements of an array, e.g. ['foo', ':bar']", binding.indexOf(' ') === -1); + // Variable in which the old class value is saved. The observer function // closes over this variable, so it knows which string to remove when // the property changes. var oldClass; // Extract just the property name from bindings like 'foo:bar' @@ -26036,11 +25852,11 @@ context of the surrounding context or outer controller: ```handlebars {{#app-profile person=currentUser}} <p>Admin mode</p> - {{! Executed in the controllers context. }} + {{! Executed in the controller's context. }} {{/app-profile}} ``` ```handlebars <!-- app-profile template --> @@ -26192,13 +26008,13 @@ ```javascript App.PlayButtonComponent = Ember.Component.extend({ click: function(){ if (this.get('isPlaying')) { - this.triggerAction('play'); + this.sendAction('play'); } else { - this.triggerAction('stop'); + this.sendAction('stop'); } } }); ``` @@ -27227,34 +27043,20 @@ var handlebarsGet = Ember.Handlebars.get = function(root, path, options) { var data = options && options.data, normalizedPath = normalizePath(root, path, data), value; - if (Ember.FEATURES.isEnabled("ember-handlebars-caps-lookup")) { - - // If the path starts with a capital letter, look it up on Ember.lookup, - // which defaults to the `window` object in browsers. - if (Ember.isGlobalPath(path)) { - value = Ember.get(Ember.lookup, path); - } else { - - // In cases where the path begins with a keyword, change the - // root to the value represented by that keyword, and ensure - // the path is relative to it. - value = Ember.get(normalizedPath.root, normalizedPath.path); - } - - } else { + root = normalizedPath.root; path = normalizedPath.path; value = Ember.get(root, path); if (value === undefined && root !== Ember.lookup && Ember.isGlobalPath(path)) { value = Ember.get(Ember.lookup, path); } - } + return value; }; Ember.Handlebars.resolveParams = function(context, params, options) { @@ -29782,10 +29584,11 @@ var itemController = get(this, 'itemController'); var binding; if (itemController) { var controller = get(this, 'controller.container').lookupFactory('controller:array').create({ + _isVirtual: true, parentController: get(this, 'controller'), itemController: itemController, target: get(this, 'controller'), _eachView: this }); @@ -34419,34 +34222,22 @@ } else { this.push(options.path, name, null, options.queryParams); } - if (Ember.FEATURES.isEnabled("ember-routing-named-substates")) { - // For namespace-preserving nested resource (e.g. resource('foo.bar') within - // resource('foo')) we only want to use the last route name segment to determine - // the names of the error/loading substates (e.g. 'bar_loading') - name = name.split('.').pop(); - route(this, name + '_loading'); - route(this, name + '_error', { path: "/_unused_dummy_error_path_route_" + name + "/:error" }); - } - }, + }, push: function(url, name, callback, queryParams) { var parts = name.split('.'); if (url === "" || url === "/" || parts[parts.length-1] === "index") { this.explicitIndex = true; } this.matches.push([url, name, callback, queryParams]); }, route: function(name, options) { route(this, name, options); - if (Ember.FEATURES.isEnabled("ember-routing-named-substates")) { - route(this, name + '_loading'); - route(this, name + '_error', { path: "/_unused_dummy_error_path_route_" + name + "/:error" }); - } - }, + }, generate: function() { var dslMatches = this.matches; if (!this.explicitIndex) { @@ -34642,31 +34433,39 @@ /** Initializes the current router instance and sets up the change handling event listeners used by the instances `location` implementation. + A property named `initialURL` will be used to determine the initial URL. + If no value is found `/` will be used. + @method startRouting @private */ startRouting: function() { this.router = this.router || this.constructor.map(Ember.K); var router = this.router, location = get(this, 'location'), container = this.container, - self = this; + self = this, + initialURL = get(this, 'initialURL'); this._setupRouter(router, location); container.register('view:default', DefaultView); container.register('view:toplevel', Ember.View.extend()); location.onUpdateURL(function(url) { self.handleURL(url); }); - this.handleURL(location.getURL()); + if (typeof initialURL === "undefined") { + initialURL = location.getURL(); + } + + this.handleURL(initialURL); }, /** Handles updating the paths and notifying any listeners of the URL change. @@ -34868,19 +34667,11 @@ args[0] = args[0] || '/'; var passedName = args[0], name, self = this, isQueryParamsOnly = false, queryParams; - if (Ember.FEATURES.isEnabled("query-params-new")) { - if (args[args.length - 1].hasOwnProperty('queryParams')) { - if (args.length === 1) { - isQueryParamsOnly = true; - } - queryParams = args[args.length - 1].queryParams; - } - } - + if (!isQueryParamsOnly && passedName.charAt(0) !== '/') { if (!this.router.hasRoute(passedName)) { name = args[0] = passedName + '.index'; } else { name = passedName; @@ -35132,18 +34923,11 @@ var router = parentRoute.router, childName, targetChildRouteName = originatingChildRoute.routeName.split('.').pop(), namespace = parentRoute.routeName === 'application' ? '' : parentRoute.routeName + '.'; - if (Ember.FEATURES.isEnabled("ember-routing-named-substates")) { - // First, try a named loading state, e.g. 'foo_loading' - childName = namespace + targetChildRouteName + '_' + name; - if (routeHasBeenDefined(router, childName)) { - return childName; - } - } - + // Second, try general loading state, e.g. 'loading' childName = namespace + name; if (routeHasBeenDefined(router, childName)) { return childName; } @@ -35322,14 +35106,11 @@ @private @method exit */ exit: function() { - if (Ember.FEATURES.isEnabled("query-params-new")) { - this.controller._deactivateQueryParamObservers(); - } - this.deactivate(); + this.deactivate(); this.teardownViews(); }, /** @private @@ -35365,15 +35146,37 @@ @default null */ 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. + + ```js + var PostsList = Ember.Route.extend({ + templateName: 'posts/list' + }); + + App.PostsIndexRoute = PostsList.extend(); + App.PostsArchivedRoute = PostsList.extend(); + ``` + + @property templateName + @type String + @default null + */ + templateName: null, + + /** The name of the controller to associate with this route. By default, Ember will lookup a route's controller that matches the name of the route (i.e. `App.PostController` for `App.PostRoute`). However, - if you would to like define a specific controller to use, you can do so + 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. @@ -35593,63 +35396,11 @@ @type Hash @default null */ _actions: { finalizeQueryParamChange: function(params, finalParams) { - if (Ember.FEATURES.isEnabled("query-params-new")) { - // In this hook we receive a list of raw URL query - // param changes. We need to take any - - var controller = this.controller; - var changes = controller._queryParamChangesDuringSuspension; - var queryParams = get(controller, '_queryParamHash'); - - // Loop through all the query params that - // this controller knows about. - for (var k in queryParams) { - if (queryParams.hasOwnProperty(k)) { - - // Do a reverse lookup to see if the changed query - // param URL key corresponds to a QP property on - // this controller. - if (queryParams[k] in params) { - // Update this controller property in a way that - // won't fire observers. - controller._finalizingQueryParams = true; - if (!changes || !(k in changes)) { - // Only update the controller if the query param - // value wasn't overriden in setupController. - - // Arrays coming from router.js should be Emberized. - var newValue = params[queryParams[k]]; - newValue = Ember.isArray(newValue) ? Ember.A(newValue) : newValue; - set(controller, k, newValue); - } - controller._finalizingQueryParams = false; - - // Delete from params so that child routes - // don't also try to respond to changes to - // non-fully-qualified query param name changes. - delete params[queryParams[k]]; - } - - // Query params are ordered. This action bubbles up - // the route hierarchy so we unshift so that the final - // order of query params goes from root to leaf. - finalParams.unshift({ - key: queryParams[k], - value: get(controller, k) - }); } - } - - controller._queryParamChangesDuringSuspension = null; - - // Bubble so that parent routes can claim QPs. - return true; - } - } }, /** @deprecated @@ -35887,35 +35638,19 @@ // Assign the route's controller so that it can more easily be // referenced in action handlers this.controller = controller; - if (Ember.FEATURES.isEnabled("query-params-new")) { - // TODO: configurable _queryParamScope - if (controllerName !== 'application') { - this.controller._queryParamScope = controllerName; - } - this.controller._activateQueryParamObservers(); - } - + if (this.setupControllers) { Ember.deprecate("Ember.Route.setupControllers is deprecated. Please use Ember.Route.setupController(controller, model) instead."); this.setupControllers(controller, context); } else { - if (Ember.FEATURES.isEnabled("query-params-new")) { - // Prevent updates to query params in setupController - // from firing another transition. Updating QPs in - // setupController will only affect the final - // generated URL. - controller._finalizingQueryParams = true; - controller._queryParamChangesDuringSuspension = {}; - this.setupController(controller, context, transition); - controller._finalizingQueryParams = false; - } else { + this.setupController(controller, context); - } + } if (this.renderTemplates) { Ember.deprecate("Ember.Route.renderTemplates is deprecated. Please use Ember.Route.renderTemplate(controller, model) instead."); this.renderTemplates(context); @@ -36143,15 +35878,13 @@ @private Router.js hook. */ deserialize: function(params, transition) { - if (Ember.FEATURES.isEnabled("query-params-new")) { - return this.model(this.paramsFor(this.routeName), transition); - } else { + return this.model(params, transition); - } + }, /** @method findModel @@ -36188,10 +35921,12 @@ Ember.assert("You used the dynamic segment " + name + "_id in your route " + routeName + ", but " + namespace + "." + classify(name) + " did not exist and you did not override your route's `model` " + "hook.", modelClass); + if (!modelClass) { return; } + return modelClass.find(value); } }; }), @@ -36616,46 +36351,11 @@ delete this.lastRenderedTemplate; } }); -if (Ember.FEATURES.isEnabled("query-params-new")) { - Ember.Route.reopen({ - paramsFor: function(name) { - var route = this.container.lookup('route:' + name); - if (!route) { - return {}; - } - - var transition = this.router.router.activeTransition; - var queryParamsHash = this.router._queryParamNamesForSingle(route.routeName); - - var params, queryParams; - if (transition) { - params = transition.params[name] || {}; - queryParams = transition.queryParams; - } else { - var state = this.router.router.state; - params = state.params[name] || {}; - queryParams = state.queryParams; - } - - this.router._queryParamOverrides(params, queryParamsHash.queryParams, function(name, resultsName, colonized) { - // Replace the controller-supplied value with more up - // to date values (e.g. from an incoming transition). - var value = (resultsName in queryParams) ? - queryParams[resultsName] : params[resultsName]; - delete params[resultsName]; - params[colonized.split(':').pop()] = value; - }); - - return params; - } - }); -} - function parentRoute(route) { var handlerInfos = route.router.router.state.handlerInfos; if (!handlerInfos) { return; } @@ -37245,14 +36945,11 @@ // If contexts aren't present, consider the linkView unloaded. return; } } - if (Ember.FEATURES.isEnabled("query-params-new")) { - resolvedParams.push({ queryParams: get(this, 'queryParams') }); - } - + return resolvedParams; }).property('resolvedParams', 'queryParams'), queryParamsObject: null, queryParams: Ember.computed(function computeLinkViewQueryParams() { @@ -37628,21 +37325,11 @@ return Ember.Handlebars.helpers.view.call(this, LinkView, options); }); - if (Ember.FEATURES.isEnabled("query-params-new")) { - Ember.Handlebars.registerHelper('query-params', function queryParamsHelper(options) { - Ember.assert(fmt("The `query-params` helper only accepts hash parameters, e.g. (query-params queryParamPropertyName='%@') as opposed to just (query-params '%@')", [options, options]), arguments.length === 1); - - return QueryParams.create({ - values: options.hash, - types: options.hashTypes - }); - }); - } - + /** See [link-to](/api/classes/Ember.Handlebars.helpers.html#method_link-to) @method linkTo @for Ember.Handlebars.helpers @@ -37932,11 +37619,11 @@ } options.hash.viewName = Ember.String.camelize(name); var templateName = 'template:' + name; - Ember.assert("You used `{{render '" + name + "'}}`, but '" + name + "' can not be found as either a template or a view.", container.has("view:" + name) || container.has(templateName)); + Ember.assert("You used `{{render '" + name + "'}}`, but '" + name + "' can not be found as either a template or a view.", container.has("view:" + name) || container.has(templateName) || options.fn); options.hash.template = container.lookup(templateName); options.hash.controller = controller; if (router && !context) { @@ -38385,99 +38072,11 @@ Ember.deprecate("replaceWith is deprecated. Please use replaceRoute."); return this.replaceRoute.apply(this, arguments); } }); -if (Ember.FEATURES.isEnabled("query-params-new")) { - Ember.ControllerMixin.reopen({ - concatenatedProperties: ['queryParams'], - - queryParams: null, - - _queryParamScope: null, - - _finalizingQueryParams: false, - _queryParamHash: Ember.computed(function computeQueryParamHash() { - - // Given: queryParams: ['foo', 'bar:baz'] on controller:thing - // _queryParamHash should yield: { 'foo': 'thing[foo]' } - - var result = {}; - var queryParams = this.queryParams; - if (!queryParams) { - return result; - } - - for (var i = 0, len = queryParams.length; i < len; ++i) { - var full = queryParams[i]; - var parts = full.split(':'); - var key = parts[0]; - var urlKey = parts[1]; - if (!urlKey) { - if (this._queryParamScope) { - urlKey = this._queryParamScope + '[' + key + ']'; - } else { - urlKey = key; - } - } - result[key] = urlKey; - } - - return result; - }), - - _activateQueryParamObservers: function() { - var queryParams = get(this, '_queryParamHash'); - - for (var k in queryParams) { - if (queryParams.hasOwnProperty(k)) { - this.addObserver(k, this, this._queryParamChanged); - this.addObserver(k + '.[]', this, this._queryParamChanged); - } - } - }, - - _deactivateQueryParamObservers: function() { - var queryParams = get(this, '_queryParamHash'); - - for (var k in queryParams) { - if (queryParams.hasOwnProperty(k)) { - this.removeObserver(k, this, this._queryParamChanged); - this.removeObserver(k + '.[]', this, this._queryParamChanged); - } - } - }, - - _queryParamChanged: function(controller, key) { - // Normalize array observer firings. - if (key.substr(-3) === '.[]') { - key = key.substr(0, key.length-3); - } - - if (this._finalizingQueryParams) { - var changes = this._queryParamChangesDuringSuspension; - if (changes) { - changes[key] = true; - } - return; - } - - var queryParams = get(this, '_queryParamHash'); - queuedQueryParamChanges[queryParams[key]] = Ember.copy(get(this, key)); - Ember.run.once(this, this._fireQueryParamTransition); - }, - - _fireQueryParamTransition: function() { - this.transitionToRoute({ queryParams: queuedQueryParamChanges }); - queuedQueryParamChanges = {}; - }, - - _queryParamChangesDuringSuspension: null - }); -} - })(); (function() { @@ -38924,23 +38523,11 @@ @private @method getURL */ getURL: function() { - if (Ember.FEATURES.isEnabled("query-params-new")) { - // location.hash is not used because it is inconsistently - // URL-decoded between browsers. - var href = get(this, 'location').href, - hashIndex = href.indexOf('#'); - - if ( hashIndex === -1 ) { - return ""; - } else { - return href.substr(hashIndex + 1); - } - } - // Default implementation without feature flag enabled + // Default implementation without feature flag enabled return get(this, 'location').hash.substr(1); }, /** Set the `location.hash` and remembers what was set. This prevents @@ -39086,15 +38673,11 @@ rootURL = rootURL.replace(/\/$/, ''); baseURL = baseURL.replace(/\/$/, ''); var url = path.replace(baseURL, '').replace(rootURL, ''); - if (Ember.FEATURES.isEnabled("query-params-new")) { - var search = location.search || ''; - url += search; - } - + return url; }, /** Uses `history.pushState` to update the url without a page reload. @@ -41495,14 +41078,11 @@ // if adapter is not manually set default to QUnit if (!Ember.Test.adapter) { Ember.Test.adapter = Ember.Test.QUnitAdapter.create(); } - if (Ember.FEATURES.isEnabled('ember-testing-simple-setup')){ - this.testingSetup = true; - } - }, + }, /** This will be used as the container to inject the test helpers into. By default the helpers are injected into `window`. @@ -41645,24 +41225,12 @@ application.deferReadiness(); } } }); - if (Ember.FEATURES.isEnabled('ember-testing-simple-setup')){ - Application.initializer({ - name: 'setupForTesting and injectTestHelpers when created with testing = true', + }); - initialize: function(container, application){ - if (application.testing && !application.testingSetup) { - application.setupForTesting(); - application.injectTestHelpers(); - } - } - }); - } -}); - })(); (function() { @@ -41849,14 +41417,21 @@ return get(router, 'location').getURL(); } function visit(app, url) { - Ember.run(app, 'advanceReadiness'); + var router = app.__container__.lookup('router:main'); + router.location.setURL(url); - app.__container__.lookup('router:main').location.setURL(url); - Ember.run(app, app.handleURL, url); + if (app._readinessDeferrals > 0) { + router['initialURL'] = url; + Ember.run(app, 'advanceReadiness'); + delete router['initialURL']; + } else { + Ember.run(app, app.handleURL, url); + } + return wait(app); } function click(app, selector, context) { var $el = findWithAssert(app, selector, context); @@ -42115,85 +41690,10 @@ */ asyncHelper('wait', wait); asyncHelper('andThen', andThen); -if (Ember.FEATURES.isEnabled('ember-testing-routing-helpers')){ - /** - Returns the currently active route name. - Example: - - ``` - function validateRouteName(){ - equal(currentRouteName(), 'some.path', "correct route was transitioned into."); - } - - visit('/some/path').then(validateRouteName) - - ``` - - @method currentRouteName - @return {Object} The name of the currently active route. - */ - helper('currentRouteName', currentRouteName); - - /** - Returns the current path. - - Example: - - ``` - function validateURL(){ - equal(currentPath(), 'some.path.index', "correct path was transitioned into."); - } - - click('#some-link-id').then(validateURL); - - ``` - - @method currentPath - @return {Object} The currently active path. - */ - helper('currentPath', currentPath); - - /** - Returns the current URL. - - Example: - - ``` - function validateURL(){ - equal(currentURL(), '/some/path', "correct URL was transitioned into."); - } - - click('#some-link-id').then(validateURL); - - ``` - - @method currentURL - @return {Object} The currently active URL. - */ - helper('currentURL', currentURL); -} - -if (Ember.FEATURES.isEnabled('ember-testing-triggerEvent-helper')) { - /** - Triggers the given event on the element identified by the provided selector. - - Example: - - ```javascript - triggerEvent('#some-elem-id', 'blur'); - ``` - - @method triggerEvent - @param {String} selector jQuery selector for finding element on the DOM - @param {String} event The event to be triggered. - @return {RSVP.Promise} - */ - asyncHelper('triggerEvent', triggerEvent); -} })();