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 `