diff --git a/Gemfile.lock b/Gemfile.lock index 9e430cde5ff..fde60ce7edf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,9 +7,9 @@ GIT GIT remote: git://github.com/emberjs/ember-rails.git - revision: 587a55a8c53aae2193a3602895e89311eb8544b0 + revision: 57bbe3202725e55a8e4eaccba83d663b26bcf024 specs: - ember-rails (0.9.2) + ember-rails (0.10.1) active_model_serializers barber execjs (>= 1.2) @@ -17,7 +17,7 @@ GIT GIT remote: git://github.com/rails-api/active_model_serializers.git - revision: cef10cf01dfe18f72060bda279d5246c156ae737 + revision: 0114e492388ff84defcd1afbbb315e547849cb96 specs: active_model_serializers (0.5.2) activemodel (>= 3.0) @@ -100,7 +100,7 @@ GEM builder archive-tar-minitar (0.5.2) arel (3.0.2) - barber (0.2.0) + barber (0.3.0) execjs better_errors (0.5.0) coderay (>= 1.0.0) @@ -238,7 +238,7 @@ GEM mixlib-shellout (1.1.0) mocha (0.10.5) metaclass (~> 0.0.1) - multi_json (1.5.1) + multi_json (1.6.1) multipart-post (1.1.5) mustache (0.99.4) net-scp (1.0.4) diff --git a/app/assets/javascripts/application.js.erb b/app/assets/javascripts/application.js.erb index 5f44e5f57f0..cf93c51f140 100644 --- a/app/assets/javascripts/application.js.erb +++ b/app/assets/javascripts/application.js.erb @@ -12,7 +12,7 @@ // Externals we need to load first //= require ./external/jquery-1.8.2.js //= require ./external/jquery.ui.widget.js -//= require ./external/handlebars-1.0.rc.2.js +//= require ./external/handlebars-1.0.rc.3.js //= require ./external/ember.js // Pagedown customizations diff --git a/app/assets/javascripts/discourse/templates/header.js.handlebars b/app/assets/javascripts/discourse/templates/header.js.handlebars index f655bb9e314..ab13bc0f1a4 100644 --- a/app/assets/javascripts/discourse/templates/header.js.handlebars +++ b/app/assets/javascripts/discourse/templates/header.js.handlebars @@ -2,9 +2,13 @@
{{#if controller.showExtraInfo}} + {{#linkTo list.popular}}{{{Discourse.logoSmall}}}{{/linkTo}} + {{else}} + {{#linkTo list.popular}}{{/linkTo}} + {{/if}}
diff --git a/app/assets/javascripts/discourse/views/user/user_private_messages_view.js.coffee b/app/assets/javascripts/discourse/views/user/user_private_messages_view.js.coffee index 9abcae50d58..2c684790b40 100644 --- a/app/assets/javascripts/discourse/views/user/user_private_messages_view.js.coffee +++ b/app/assets/javascripts/discourse/views/user/user_private_messages_view.js.coffee @@ -1,6 +1,5 @@ window.Discourse.UserPrivateMessagesView = Ember.View.extend templateName: 'user/private_messages' - elementId: 'user-private-messages' selectCurrent: (evt) -> t = $(evt.currentTarget) diff --git a/app/assets/javascripts/external/ember.js b/app/assets/javascripts/external/ember.js index 0dec4a332c4..f9666c071ae 100644 --- a/app/assets/javascripts/external/ember.js +++ b/app/assets/javascripts/external/ember.js @@ -1,5 +1,5 @@ -// Version: v1.0.0-pre.2-608-g538b7a0 -// Last commit: 538b7a0 (2013-02-03 17:48:00 -0800) +// Version: v1.0.0-pre.2-723-g052062c +// Last commit: 052062c (2013-02-18 19:32:17 -0800) (function() { @@ -150,8 +150,8 @@ Ember.deprecateFunc = function(message, func) { })(); -// Version: v1.0.0-pre.2-608-g538b7a0 -// Last commit: 538b7a0 (2013-02-03 17:48:00 -0800) +// Version: v1.0.0-pre.2-723-g052062c +// Last commit: 052062c (2013-02-18 19:32:17 -0800) (function() { @@ -211,7 +211,7 @@ var define, requireModule; @class Ember @static - @version 1.0.0-pre.4 + @version 1.0.0-rc.1 */ if ('undefined' === typeof Ember) { @@ -238,10 +238,10 @@ Ember.toString = function() { return "Ember"; }; /** @property VERSION @type String - @default '1.0.0-pre.4' + @default '1.0.0-rc.1' @final */ -Ember.VERSION = '1.0.0-pre.4'; +Ember.VERSION = '1.0.0-rc.1'; /** Standard environmental variables. You can define these in a global `ENV` @@ -651,7 +651,7 @@ Ember.generateGuid = function generateGuid(obj, prefix) { @method guidFor @for Ember - @param obj {Object} any object, string, number, Element, or primitive + @param {Object} obj any object, string, number, Element, or primitive @return {String} the unique guid for this instance. */ Ember.guidFor = function guidFor(obj) { @@ -1001,8 +1001,8 @@ var needsFinallyFix = (function() { @method tryFinally @for Ember - @param {Function} function The function to run the try callback - @param {Function} function The function to run the finally callback + @param {Function} tryable The function to run the try callback + @param {Function} finalizer The function to run the finally callback @param [binding] @return {anything} The return value is the that of the finalizer, unless that valueis undefined, in which case it is the return value @@ -1051,9 +1051,9 @@ if (needsFinallyFix) { @method tryCatchFinally @for Ember - @param {Function} function The function to run the try callback - @param {Function} function The function to run the catchable callback - @param {Function} function The function to run the finally callback + @param {Function} tryable The function to run the try callback + @param {Function} catchable The function to run the catchable callback + @param {Function} finalizer The function to run the finally callback @param [binding] @return {anything} The return value is the that of the finalizer, unless that value is undefined, in which case it is the return value @@ -1565,8 +1565,8 @@ OrderedSet.prototype = { /** @method forEach - @param {Function} function - @param target + @param {Function} fn + @param self */ forEach: function(fn, self) { // allow mutation during iteration @@ -2087,7 +2087,7 @@ Ember.setPath = Ember.deprecateFunc('setPath is deprecated since set now support @method trySet @for Ember @param {Object} obj The object to modify. - @param {String} keyName The property key to set + @param {String} path The property path to set @param {Object} value The value to set */ Ember.trySet = function(root, path, value) { @@ -3757,6 +3757,7 @@ function actionsDiff(obj, eventName, otherActions) { @param {String} eventName @param {Object|Function} targetOrMethod A target object or a function @param {Function|String} method A function or the name of a function to be called on `target` + @param {Boolean} once A flag whether a function should only be called once */ function addListener(obj, eventName, target, method, once) { Ember.assert("You must pass at least an object and event name to Ember.addListener", !!obj && !!eventName); @@ -3942,6 +3943,7 @@ function watchedEvents(obj) { @param obj @param {String} eventName @param {Array} params + @param {Array} actions @return true */ function sendEvent(obj, eventName, params, actions) { @@ -4729,7 +4731,7 @@ Binding.prototype = { `get()` - see that method for more information. @method from - @param {String} propertyPath the property path to connect to + @param {String} path the property path to connect to @return {Ember.Binding} `this` */ from: function(path) { @@ -4747,7 +4749,7 @@ Binding.prototype = { `get()` - see that method for more information. @method to - @param {String|Tuple} propertyPath A property path or tuple + @param {String|Tuple} path A property path or tuple @return {Ember.Binding} `this` */ to: function(path) { @@ -5883,7 +5885,8 @@ define("rsvp", callbacks, callbackTuple, callback, binding, event; if (callbacks = allCallbacks[eventName]) { - for (var i=0, l=callbacks.length; i= 0 && idx < length) { + var controllerClass = this.lookupItemController(object); + if (controllerClass) { + return this.controllerAt(idx, object, controllerClass); + } } + + // When `controllerClass` is falsy, we have not opted in to using item + // controllers, so return the object directly. + + // When the index is out of range, we want to return the "out of range" + // value, whatever that might be. Rather than make assumptions + // (e.g. guessing `null` or `undefined`) we defer this to `arrangedContent`. + return object; }, arrangedContentDidChange: function() { this._super(); - this._resetSubContainers(); + this._resetSubControllers(); }, arrayContentDidChange: function(idx, removedCnt, addedCnt) { - var subContainers = get(this, 'subContainers'), - subContainersToRemove = subContainers.slice(idx, idx+removedCnt); + var subControllers = get(this, '_subControllers'), + subControllersToRemove = subControllers.slice(idx, idx+removedCnt); - forEach(subContainersToRemove, function(subContainer) { - if (subContainer) { subContainer.destroy(); } + forEach(subControllersToRemove, function(subController) { + if (subController) { subController.destroy(); } }); - replace(subContainers, idx, removedCnt, new Array(addedCnt)); + replace(subControllers, idx, removedCnt, new Array(addedCnt)); - // The shadow array of subcontainers must be updated before we trigger + // The shadow array of subcontrollers must be updated before we trigger // observers, otherwise observers will get the wrong subcontainer when // calling `objectAt` this._super(idx, removedCnt, addedCnt); @@ -12425,42 +12481,40 @@ Ember.ArrayController = Ember.ArrayProxy.extend(Ember.ControllerMixin, init: function() { this._super(); - this._resetSubContainers(); + if (!this.get('content')) { Ember.defineProperty(this, 'content', undefined, Ember.A()); } + this.set('_subControllers', Ember.A()); }, controllerAt: function(idx, object, controllerClass) { var container = get(this, 'container'), - subContainers = get(this, 'subContainers'), - subContainer = subContainers[idx], - controller; + subControllers = get(this, '_subControllers'), + subController = subControllers[idx]; - if (!subContainer) { - subContainer = subContainers[idx] = container.child(); + if (!subController) { + subController = container.lookup("controller:" + controllerClass, { singleton: false }); + subControllers[idx] = subController; } - controller = subContainer.lookup("controller:" + controllerClass); - if (!controller) { + if (!subController) { throw new Error('Could not resolve itemController: "' + controllerClass + '"'); } - controller.set('target', this); - controller.set('content', object); + subController.set('target', this); + subController.set('content', object); - return controller; + return subController; }, - subContainers: null, + _subControllers: null, - _resetSubContainers: function() { - var subContainers = get(this, 'subContainers'); + _resetSubControllers: function() { + var subControllers = get(this, '_subControllers'); - if (subContainers) { - forEach(subContainers, function(subContainer) { - if (subContainer) { subContainer.destroy(); } - }); - } + forEach(subControllers, function(subController) { + if (subController) { subController.destroy(); } + }); - this.set('subContainers', Ember.A()); + this.set('_subControllers', Ember.A()); } }); @@ -12518,7 +12572,7 @@ Ember Runtime */ var jQuery = Ember.imports.jQuery; -Ember.assert("Ember Views require jQuery 1.7 (>= 1.7.2), 1.8 or 1.9", jQuery && (jQuery().jquery.match(/^1\.(7(?!$)(?!\.[01])|8|9)(\.\d+)?(pre|rc\d?)?/) || Ember.ENV.FORCE_JQUERY)); +Ember.assert("Ember Views require jQuery 1.8 or 1.9", jQuery && (jQuery().jquery.match(/^1\.(8|9)(\.\d+)?(pre|rc\d?)?/) || Ember.ENV.FORCE_JQUERY)); /** Alias for jQuery @@ -12798,17 +12852,19 @@ Ember._RenderBuffer.prototype = elementAttributes: null, /** - The value for this attribute. Values cannot be set via attr after - jQuery 1.9, they need to be set with val() instead. + A hash keyed on the name of the properties and whose value will be + applied to that property. For example, if you wanted to apply a + `checked=true` property to an element, you would set the + elementProperties hash to `{'checked':true}`. - You should not maintain this value yourself, rather, you should use - the `val()` method of `Ember.RenderBuffer`. + You should not maintain this hash yourself, rather, you should use + the `prop()` method of `Ember.RenderBuffer`. - @property elementValue - @type String - @default null + @property elementProperties + @type Hash + @default {} */ - elementValue: null, + elementProperties: null, /** The tagname of the element an instance of `Ember.RenderBuffer` represents. @@ -12918,26 +12974,6 @@ Ember._RenderBuffer.prototype = return this; }, - /** - Adds an value which will be rendered to the element. - - @method val - @param {String} value The value to set - @chainable - @return {Ember.RenderBuffer|String} this or the current value - */ - val: function(value) { - var elementValue = this.elementValue; - - if (arguments.length === 0) { - return elementValue; - } else { - this.elementValue = value; - } - - return this; - }, - /** Remove an attribute from the list of attributes to render. @@ -12952,6 +12988,41 @@ Ember._RenderBuffer.prototype = return this; }, + /** + Adds an property which will be rendered to the element. + + @method prop + @param {String} name The name of the property + @param {String} value The value to add to the property + @chainable + @return {Ember.RenderBuffer|String} this or the current property value + */ + prop: function(name, value) { + var properties = this.elementProperties = (this.elementProperties || {}); + + if (arguments.length === 1) { + return properties[name]; + } else { + properties[name] = value; + } + + return this; + }, + + /** + Remove an property from the list of properties to render. + + @method removeProp + @param {String} name The name of the property + @chainable + */ + removeProp: function(name) { + var properties = this.elementProperties; + if (properties) { delete properties[name]; } + + return this; + }, + /** Adds a style to the style attribute which will be rendered to the element. @@ -12985,9 +13056,9 @@ Ember._RenderBuffer.prototype = id = this.elementId, classes = this.classes, attrs = this.elementAttributes, - value = this.elementValue, + props = this.elementProperties, style = this.elementStyle, - prop; + attr, prop; buffer.push('<' + tagName); @@ -13015,19 +13086,30 @@ Ember._RenderBuffer.prototype = } if (attrs) { - for (prop in attrs) { - if (attrs.hasOwnProperty(prop)) { - buffer.push(' ' + prop + '="' + this._escapeAttribute(attrs[prop]) + '"'); + for (attr in attrs) { + if (attrs.hasOwnProperty(attr)) { + buffer.push(' ' + attr + '="' + this._escapeAttribute(attrs[attr]) + '"'); } } this.elementAttributes = null; } - if (value) { - buffer.push(' value="' + this._escapeAttribute(value) + '"'); + if (props) { + for (prop in props) { + if (props.hasOwnProperty(prop)) { + var value = props[prop]; + if (value || typeof(value) === 'number') { + if (value === true) { + buffer.push(' ' + prop + '="' + prop + '"'); + } else { + buffer.push(' ' + prop + '="' + this._escapeAttribute(props[prop]) + '"'); + } + } + } + } - this.elementValue = null; + this.elementProperties = null; } buffer.push('>'); @@ -13049,9 +13131,9 @@ Ember._RenderBuffer.prototype = id = this.elementId, classes = this.classes, attrs = this.elementAttributes, - value = this.elementValue, + props = this.elementProperties, style = this.elementStyle, - styleBuffer = '', prop; + styleBuffer = '', attr, prop; if (id) { $element.attr('id', id); @@ -13075,19 +13157,23 @@ Ember._RenderBuffer.prototype = } if (attrs) { - for (prop in attrs) { - if (attrs.hasOwnProperty(prop)) { - $element.attr(prop, attrs[prop]); + for (attr in attrs) { + if (attrs.hasOwnProperty(attr)) { + $element.attr(attr, attrs[attr]); } } this.elementAttributes = null; } - if (value) { - $element.val(value); + if (props) { + for (prop in props) { + if (props.hasOwnProperty(prop)) { + $element.prop(prop, props[prop]); + } + } - this.elementValue = null; + this.elementProperties = null; } return element; @@ -13458,7 +13544,7 @@ var childViewsProperty = Ember.computed(function() { ret.replace = function (idx, removedCount, addedViews) { if (view instanceof Ember.ContainerView) { - Ember.deprecate("Manipulating a Ember.ContainerView through its childViews property is deprecated. Please use the ContainerView instance itself as an Ember.MutableArray."); + Ember.deprecate("Manipulating an Ember.ContainerView through its childViews property is deprecated. Please use the ContainerView instance itself as an Ember.MutableArray."); return view.replace(idx, removedCount, addedViews); } throw new Error("childViews is immutable"); @@ -15779,56 +15865,20 @@ Ember.View.views = {}; Ember.View.childViewsProperty = childViewsProperty; Ember.View.applyAttributeBindings = function(elem, name, value) { - if (name === 'value') { - Ember.View.applyValueBinding(elem, value); - } else { - Ember.View.applyAttributeBinding(elem, name, value); - } -}; - -Ember.View.applyAttributeBinding = function(elem, name, value) { var type = Ember.typeOf(value); - var currentValue = elem.attr(name); // if this changes, also change the logic in ember-handlebars/lib/helpers/binding.js - if ( - ( - ( type === 'string' ) || - ( type === 'number' && !isNaN(value) ) || - ( type === 'boolean' && value ) - ) && ( - value !== currentValue - ) - ) { - elem.attr(name, value); - } else if (!value) { - elem.removeAttr(name); - } -}; - -Ember.View.applyValueBinding = function(elem, value) { - var type = Ember.typeOf(value); - var currentValue = elem.val(); - - // if this changes, also change the logic in ember-handlebars/lib/helpers/binding.js - if ( - ( - ( type === 'string' ) || - ( type === 'number' && !isNaN(value) ) || - ( type === 'boolean' && value ) - ) && ( - value !== currentValue - ) - ) { - if (elem.caretPosition) { - var caretPosition = elem.caretPosition(); - elem.val(value); - elem.setCaretPosition(caretPosition); - } else { - elem.val(value); + if (name !== 'value' && (type === 'string' || (type === 'number' && !isNaN(value)))) { + if (value !== elem.attr(name)) { + elem.attr(name, value); + } + } else if (name === 'value' || type === 'boolean') { + if (value !== elem.prop(name)) { + // value and booleans should always be properties + elem.prop(name, value); } } else if (!value) { - elem.val(''); + elem.removeAttr(name); } }; @@ -16674,7 +16724,7 @@ var get = Ember.get, set = Ember.set, fmt = Ember.String.fmt; } else { viewClass = App.SongView; } - this._super(viewClass, attrs); + return this._super(viewClass, attrs); } }); ``` @@ -17421,7 +17471,7 @@ var objectCreate = Object.create || function(parent) { }; var Handlebars = this.Handlebars || Ember.imports.Handlebars; -Ember.assert("Ember Handlebars requires Handlebars 1.0.rc.2 or greater", Handlebars && Handlebars.VERSION.match(/^1\.0\.rc\.[23456789]+/)); +Ember.assert("Ember Handlebars requires Handlebars 1.0.0-rc.3 or greater", Handlebars && Handlebars.VERSION.match(/^1\.0\.[0-9](\.rc\.[23456789]+)?/)); /** Prepares the Handlebars templating library for use inside Ember's view @@ -17835,7 +17885,7 @@ Ember.Handlebars.registerHelper('helperMissing', function(path, options) { Ember.Handlebars.registerBoundHelper = function(name, fn) { var dependentKeys = slice.call(arguments, 2); - Ember.Handlebars.registerHelper(name, function() { + function helper() { var properties = slice.call(arguments, 0, -1), numProperties = properties.length, options = arguments[arguments.length - 1], @@ -17897,7 +17947,10 @@ Ember.Handlebars.registerBoundHelper = function(name, fn) { for (var i=0, l=dependentKeys.length; iGreetings Sara
``` - + ### Representing each item with a Controller. By default the controller lookup within an `{{#each}}` block will be the controller of the template where the `{{#each}}` was used. If each @@ -20077,10 +20128,10 @@ GroupedEach.prototype = { `itemController` option which references a controller by lookup name. Each item in the loop will be wrapped in an instance of this controller and the item itself will be set to the `content` property of that controller. - + This is useful in cases where properties of model objects need transformation or synthesis for display: - + ```javascript App.DeveloperController = Ember.ObjectController.extend({ isAvailableForHire: function(){ @@ -20088,17 +20139,17 @@ GroupedEach.prototype = { }.property('isEmployed', 'isSeekingWork') }) ``` - + ```handlebars - {{#each person in Developers itemController="developer"}} + {{#each person in developers itemController="developer"}} {{person.name}} {{#if person.isAvailableForHire}}Hire me!{{/if}} {{/each}} ``` - + @method each @for Ember.Handlebars.helpers @param [name] {String} name for item (used with `in`) - @param path {String} path + @param [path] {String} path @param [options] {Object} Handlebars key/value pairs of options @param [options.itemViewClass] {String} a path to a view class used for each item @param [options.itemController] {String} name of a controller to be created for each item @@ -20157,6 +20208,14 @@ Ember.Handlebars.registerHelper('each', function(path, options) { ``` + ```handlebars + {{#if isUser}} + {{template "user_info"}} + {{else}} + {{template "unlogged_user_info"}} + {{/if}} + ``` + This helper looks for templates in the global `Ember.TEMPLATES` hash. If you add ` ``` + ```handlebars + {{#if isUser}} + {{template "user_info"}} + {{else}} + {{template "unlogged_user_info"}} + {{/if}} + ``` + This helper looks for templates in the global `Ember.TEMPLATES` hash. If you add `