Many fixes for Ember 1.9.0

This commit is contained in:
Robin Ward 2014-12-10 11:34:00 -05:00
parent 61101736cb
commit 5659b93c71
29 changed files with 9429 additions and 8052 deletions

View File

@ -104,8 +104,8 @@ end
gem 'onebox'
gem 'ember-rails'
gem 'ember-source', '1.6.0.beta.2'
gem 'handlebars-source', '1.3.0'
gem 'ember-source', '1.9.0.beta.4'
gem 'handlebars-source', '2.0.0'
gem 'barber'
gem 'message_bus'

View File

@ -77,8 +77,8 @@ GEM
handlebars-source
jquery-rails (>= 1.0.17)
railties (>= 3.1)
ember-source (1.6.0.beta.2)
handlebars-source (~> 1.0)
ember-source (1.9.0.beta.4)
handlebars-source (~> 2.0)
erubis (2.7.0)
eventmachine (1.0.3)
excon (0.39.6)
@ -129,7 +129,7 @@ GEM
given_core (3.5.4)
sorcerer (>= 0.3.7)
guess_html_encoding (0.0.9)
handlebars-source (1.3.0)
handlebars-source (2.0.0)
hashie (3.3.1)
highline (1.6.21)
hike (1.2.3)
@ -414,7 +414,7 @@ DEPENDENCIES
certified
email_reply_parser
ember-rails
ember-source (= 1.6.0.beta.2)
ember-source (= 1.9.0.beta.4)
eventmachine
fabrication (= 2.9.8)
fakeweb (~> 1.3.0)
@ -426,7 +426,7 @@ DEPENDENCIES
fog (= 1.22.1)
foreman
gctools
handlebars-source (= 1.3.0)
handlebars-source (= 2.0.0)
highline
hiredis
htmlentities

View File

@ -1,11 +1,3 @@
/**
This view is used for rendering a basic list of topics.
@class BasicTopicListComponent
@extends Discourse.View
@namespace Discourse
@module Discourse
**/
export default Ember.Component.extend({
loading: Ember.computed.not('loaded'),

View File

@ -4,9 +4,9 @@ var classify = Ember.String.classify;
var get = Ember.get;
var LOADING_WHITELIST = ['badges', 'userActivity', 'userPrivateMessages', 'admin', 'adminFlags',
'user', 'preferences', 'adminEmail', 'adminUsersList'],
_dummyRoute,
_loadingView;
'user', 'preferences', 'adminEmail', 'adminUsersList'];
var _dummyRoute;
var _loadingView;
function loadingResolver(cb) {
return function(parsedName) {
@ -150,8 +150,7 @@ export default Ember.DefaultResolver.extend({
// Try to find a template with slash instead of first underscore, e.g. foo_bar_baz => foo/bar_baz
findSlashedTemplate: function(parsedName) {
var decamelized = parsedName.fullNameWithoutType.decamelize();
var slashed = decamelized.replace("_", "/");
return Ember.TEMPLATES[slashed];
return Ember.TEMPLATES[decamelized.replace("_", "/")] || Ember.TEMPLATES[decamelized.replace('.', '/')];
},
// Try to find a template within a special admin namespace, e.g. adminEmail => admin/templates/email

View File

@ -1,5 +1,8 @@
var safe = Handlebars.SafeString;
// TODO: Remove me when ES6ified
var registerUnbound = require('discourse/helpers/register-unbound', null, null, true).default;
/**
Bound avatar helper.
@ -56,25 +59,18 @@ Handlebars.registerHelper('age-with-tooltip', function(property, options) {
return new safe(Discourse.Formatter.autoUpdatingRelativeAge(dt, {title: true}));
});
/**
Display logic for numbers.
@method number
@for Handlebars
**/
Handlebars.registerHelper('number', function(property, options) {
var orig = parseInt(Ember.Handlebars.get(this, property, options), 10);
registerUnbound('number', function(orig, params) {
orig = parseInt(orig, 10);
if (isNaN(orig)) { orig = 0; }
var title = orig;
if (options.hash.numberKey) {
title = I18n.t(options.hash.numberKey, { number: orig });
if (params.numberKey) {
title = I18n.t(params.numberKey, { number: orig });
}
var classNames = 'number';
if (options.hash['class']) {
classNames += ' ' + Ember.Handlebars.get(this, options.hash['class'], options);
if (params['class']) {
classNames += ' ' + params['class'];
}
var result = "<span class='" + classNames + "'";

View File

@ -1,5 +1,4 @@
import { categoryLinkHTML } from 'discourse/lib/html-builder';
import registerUnbound from 'discourse/helpers/register-unbound';
Handlebars.registerHelper('category-link', function(property, options) {
return categoryLinkHTML(Ember.Handlebars.get(this, property, options), options);
});
registerUnbound('category-link', categoryLinkHTML);

View File

@ -2,8 +2,7 @@ Handlebars.registerHelper('custom-html', function(name, contextString, options)
var html = Discourse.HTML.getCustomHTML(name);
if (html) { return html; }
var container = (options || contextString).data.keywords.controller.container;
var container = (options || contextString).data.view.container;
if (container.lookup('template:' + name)) {
return Ember.Handlebars.helpers.partial.apply(this, arguments);
}

View File

@ -1,27 +1,24 @@
import registerUnbound from 'discourse/helpers/register-unbound';
/**
Display logic for dates. It is unbound in Ember but will use jQuery to
update the dates on a regular interval.
**/
Handlebars.registerHelper('format-date', function(property, options) {
var leaveAgo, format = 'medium', title = true;
var hash = property.hash || (options && options.hash);
registerUnbound('format-date', function(val, params) {
var leaveAgo,
format = 'medium',
title = true;
if (hash) {
if (hash.leaveAgo) {
leaveAgo = hash.leaveAgo === "true";
}
if (hash.path) {
property = hash.path;
}
if (hash.format) {
format = hash.format;
}
if (hash.noTitle) {
title = false;
}
if (params.leaveAgo) {
leaveAgo = params.leaveAgo === "true";
}
if (params.format) {
format = params.format;
}
if (params.noTitle) {
title = false;
}
var val = Ember.Handlebars.get(this, property, options);
if (val) {
var date = new Date(val);
return new Handlebars.SafeString(Discourse.Formatter.autoUpdatingRelativeAge(date, {format: format, title: title, leaveAgo: leaveAgo}));

View File

@ -1,3 +1,6 @@
// TODO: Remove me when ES6ified
var registerUnbound = require('discourse/helpers/register-unbound', null, null, true).default;
/**
We always prefix with "js." to select exactly what we want passed
through to the front end.
@ -17,26 +20,8 @@ I18n.toHumanSize = function(number, options) {
return oldI18ntoHumanSize.apply(this, [number, options]);
};
/**
Look up a translation for an i18n key in our dictionary.
@method i18n
@for Handlebars
**/
Handlebars.registerHelper('i18n', function(property, options) {
// Resolve any properties
var params = options.hash,
self = this;
if (options.types[0] !== "STRING") {
Em.warn("Using the `{{i18n}}` helper without quotes is deprecated.");
}
_.each(params, function(value, key) {
params[key] = Em.Handlebars.get(self, value, options);
});
return I18n.t(property, params);
registerUnbound('i18n', function(key, params) {
return I18n.t(key, params);
});
/**

View File

@ -3,6 +3,9 @@ Handlebars.registerHelper('raw', function(property, options) {
template = Discourse.__container__.lookup('template:' + templateName),
params = options.hash;
// {{raw}} helper is broken!
return;
if (!template) {
Ember.warn('Could not find raw template: ' + templateName);
return;
@ -11,7 +14,7 @@ Handlebars.registerHelper('raw', function(property, options) {
if (params) {
for (var prop in params) {
if (options.hashTypes[prop] === "ID") {
params[prop] = Ember.Handlebars.get(this, params[prop], options);
params[prop] = Ember.get(this, params[prop], options);
}
}
}

View File

@ -0,0 +1,26 @@
function registerUnbound(name, fn) {
Handlebars.registerHelper(name, function(property, options) {
if (options.types[0] === "ID") {
property = options.data.view.getStream(property).value();
}
var params = {},
hash = options.hash;
if (hash) {
Ember.keys(options.hash).forEach(function(k) {
var type = options.hashTypes[k];
if (type === "STRING") {
params[k] = hash[k];
} else if (type === "ID") {
params[k] = options.data.view.getStream(hash[k]).value();
}
});
}
return fn(property, params);
});
}
export default registerUnbound;

View File

@ -1,6 +1,6 @@
Handlebars.registerHelper('topic-link', function(property, options) {
var topic = Ember.Handlebars.get(this, property, options),
title = topic.get('fancy_title');
import registerUnbound from 'discourse/helpers/register-unbound';
registerUnbound('topic-link', function(topic) {
var title = topic.get('fancy_title');
return new Handlebars.SafeString("<a href='" + topic.get('lastUnreadUrl') + "' class='title'>" + title + "</a>");
});

View File

@ -1,3 +1,5 @@
import registerUnbound from 'discourse/helpers/register-unbound';
export function renderAvatar(user, options) {
options = options || {};
@ -39,9 +41,6 @@ export function renderAvatar(user, options) {
}
}
Handlebars.registerHelper('avatar', function(user, options) {
if (typeof user === 'string') {
user = Ember.Handlebars.get(this, user, options);
}
return new Handlebars.SafeString(renderAvatar.call(this, user, options.hash));
registerUnbound('avatar', function(user, params) {
return new Handlebars.SafeString(renderAvatar.call(this, user, params));
});

View File

@ -17,34 +17,34 @@
</thead>
<tbody>
{{#each topics}}
<tr {{bind-attr class="archived"}}>
{{#each t in topics}}
<tr {{bind-attr class="t.archived"}}>
<td class='main-link'>
{{topic-status topic=this}}
<a class='title' href="{{unbound lastUnreadUrl}}">{{{unbound fancy_title}}}</a>
{{topic-post-badges unread=unread
newPosts=new_posts
unseen=unseen
url=lastUnreadUrl}}
{{topic-status topic=t}}
<a class='title' href="{{unbound t.lastUnreadUrl}}">{{{unbound t.fancy_title}}}</a>
{{topic-post-badges unread=t.unread
newPosts=t.new_posts
unseen=t.unseen
url=t.lastUnreadUrl}}
</td>
{{raw "list/category-column" hideCategory=controller.hideCategory category=category}}
{{raw "list/category-column" hideCategory=controller.hideCategory category=t.category}}
{{posts-count-column topic=this class="num" action="clickedPosts"}}
{{posts-count-column topic=t class="num" action="clickedPosts"}}
{{#if controller.showParticipants}}
<td class='participants'>
{{#each participants}}
<a href="{{unbound user.path}}" data-user-card="{{unbound user.username}}" class="{{unbound extras}}">{{avatar this usernamePath="user.username" imageSize="small"}}</a>
{{#each p in t.participants}}
<a href="{{unbound p.user.path}}" data-user-card="{{unbound p.user.username}}" class="{{unbound p.extras}}">{{avatar p usernamePath="user.username" imageSize="small"}}</a>
{{/each}}
</td>
{{/if}}
<td {{bind-attr class=":num :views viewsHeat"}}>
{{number views numberKey="views_long"}}
<td {{bind-attr class=":num :views t.viewsHeat"}}>
{{number t.views numberKey="views_long"}}
</td>
{{raw "list/activity-column" topic=this class="num" tagName="td"}}
{{raw "list/activity-column" topic=t class="num" tagName="td"}}
</tr>
{{/each}}
</tbody>

View File

@ -64,7 +64,7 @@
</tr>
</thead>
<tbody>
{{each topics itemController="topic-list-item" itemView="topic-list-item"}}
{{each content in topics itemController="topic-list-item" itemView="topic-list-item"}}
</tbody>
</table>
{{/if}}

View File

@ -3,7 +3,7 @@
<div class='item'>
<div class='clearfix info'>
{{#link-to 'user' user class="avatar-link"}}<div class='avatar-wrapper'>{{avatar user imageSize="large" extraClasses="actor" ignoreTitle="true"}}</div>{{/link-to}}
<span class='time'>{{format-date path="created_at" leaveAgo="true"}}</span>
<span class='time'>{{format-date created_at leaveAgo="true"}}</span>
<span class="title">
<a href="{{unbound url}}">{{unbound title}}</a>
</span>

View File

@ -11,10 +11,10 @@
{{outlet "modalBody"}}
{{#each errors}}
{{#each error in errors}}
<div class="alert alert-error">
<button class="close" data-dismiss="alert">×</button>
{{this}}
{{error}}
</div>
{{/each}}

View File

@ -58,15 +58,15 @@
{{#if user}}
<div class="metadata">
<h3><span class='desc'>{{i18n 'last_post'}}</span> {{format-date path="user.last_posted_at" leaveAgo="true"}}</h3>
<h3><span class='desc'>{{i18n 'joined'}}</span> {{format-date path="user.created_at" leaveAgo="true"}}</h3>
<h3><span class='desc'>{{i18n 'last_post'}}</span> {{format-date user.last_posted_at leaveAgo="true"}}</h3>
<h3><span class='desc'>{{i18n 'joined'}}</span> {{format-date user.created_at leaveAgo="true"}}</h3>
</div>
{{/if}}
{{#if showBadges}}
<div class="badge-section">
{{#each user.featured_user_badges}}
{{user-badge badge=badge}}
{{#each ub in user.featured_user_badges}}
{{user-badge badge=ub.badge}}
{{/each}}
{{#if showMoreBadges}}
{{#link-to 'user.badges' user class="btn more-user-badges"}}

View File

@ -1,5 +1,5 @@
<section class='user-content user-badges-list'>
{{#each}}
{{user-badge badge=badge count=count}}
{{#each ub in model}}
{{user-badge badge=ub.badge count=ub.count}}
{{/each}}
</section>

View File

@ -14,11 +14,11 @@
</div>
{{/if}}
{{#each itemController="notification"}}
<div {{bind-attr class=":item :notification read::unread"}}>
{{notification-item notification=this scope=scope}}
{{#each n in model itemController="notification"}}
<div {{bind-attr class=":item :notification read::n.unread"}}>
{{notification-item notification=n scope=n.scope}}
<span class="time">
{{format-date path="created_at" leaveAgo="true"}}
{{format-date n.created_at leaveAgo="true"}}
</span>
</div>
{{/each}}

View File

@ -7,7 +7,7 @@
</div>
</a>
<span class="time">
{{format-date path="created_at" leaveAgo="true"}}
{{format-date created_at leaveAgo="true"}}
</span>
<span class="title">
<a href="{{unbound url}}">{{unbound topic_title}}</a>
@ -17,7 +17,7 @@
</span>
{{#if deleted}}
<span class="delete-info">
<i class="fa fa-trash-o"></i> {{avatar deleted_by imageSize="tiny" extraClasses="actor" ignoreTitle="true"}} {{format-date path="deleted_at" leaveAgo="true"}}
<i class="fa fa-trash-o"></i> {{avatar deleted_by imageSize="tiny" extraClasses="actor" ignoreTitle="true"}} {{format-date deleted_at leaveAgo="true"}}
</span>
{{/if}}
</div>

View File

@ -1,25 +1,25 @@
{{#each model.content}}
<div {{bind-attr class=":item hidden deleted moderator_action"}}>
{{#each item in model.content}}
<div {{bind-attr class=":item item.hidden item.deleted item.moderator_action"}}>
<div class='clearfix info'>
<a href="{{unbound userUrl}}" data-user-card="{{unbound username}}" class='avatar-link'><div class='avatar-wrapper'>{{avatar this imageSize="large" extraClasses="actor" ignoreTitle="true"}}</div></a>
<span class='time'>{{format-date path="created_at"}}</span>
<a href="{{unbound item.userUrl}}" data-user-card="{{unbound item.username}}" class='avatar-link'><div class='avatar-wrapper'>{{avatar item imageSize="large" extraClasses="actor" ignoreTitle="true"}}</div></a>
<span class='time'>{{format-date item.created_at}}</span>
<span class="title">
<a href="{{unbound postUrl}}">{{unbound title}}</a>
<a href="{{unbound item.postUrl}}">{{unbound item.title}}</a>
</span>
<span class="category">{{category-link category}}</span>
<span class="category">{{category-link item.category}}</span>
</div>
<p class='excerpt'>{{{unbound excerpt}}}</p>
{{#each children}}
<p class='excerpt'>{{{unbound item.excerpt}}}</p>
{{#each child in item.children}}
<div class='child-actions'>
<i class="icon {{unbound icon}}"></i>
{{#each items}}
{{#if removableBookmark}}
<button class="btn btn-default remove-bookmark" {{action "removeBookmark" this}}>
<i class="icon {{unbound child.icon}}"></i>
{{#each grandChild in child.items}}
{{#if grandChild.removableBookmark}}
<button class="btn btn-default remove-bookmark" {{action "removeBookmark" grandChild}}>
{{fa-icon 'times'}} {{i18n "bookmarks.remove"}}
</button>
{{/if}}
<a href="{{unbound userUrl}}" data-user-card="{{unbound username}}" class='avatar-link'><div class='avatar-wrapper'>{{avatar this imageSize="tiny" extraClasses="actor" ignoreTitle="true"}}</div></a>
{{#if edit_reason}} &mdash; <span class="edit-reason">{{unbound edit_reason}}</span>{{/if}}
<a href="{{unbound grandChild.userUrl}}" data-user-card="{{unbound grandChild.username}}" class='avatar-link'><div class='avatar-wrapper'>{{avatar grandChild imageSize="tiny" extraClasses="actor" ignoreTitle="true"}}</div></a>
{{#if grandChild.edit_reason}} &mdash; <span class="edit-reason">{{unbound grandChild.edit_reason}}</span>{{/if}}
{{/each}}
</div>
{{/each}}

View File

@ -121,8 +121,8 @@
{{#if custom_groups}}
<dt>{{i18n 'groups.title' count=custom_groups.length}}</dt>
<dd class='groups'>
{{#each custom_groups}}
<span>{{#link-to 'group' this class="group-link"}}{{name}}{{/link-to}}</span>
{{#each group in custom_groups}}
<span>{{#link-to 'group' group class="group-link"}}{{group.name}}{{/link-to}}</span>
{{/each}}
</dd>
{{/if}}

View File

@ -1,9 +1,4 @@
// These will help us migrate up to the new ember's default behavior
window.ENV = {
MANDATORY_SETTER: false,
FEATURES: {'query-params-new': true}
};
window.ENV = { };
window.Discourse = {};
Discourse.SiteSettings = {};

View File

@ -1,3 +1,4 @@
//= require ./discourse/helpers/register-unbound
//= require ./discourse/helpers/i18n_helpers
//= require ./discourse/mixins/ajax
//= require ./discourse

View File

@ -0,0 +1,16 @@
module Ember
module Handlebars
class Template < Tilt::Template
# Wrap in an IIFE in development mode to get the correct filename
def compile_ember_handlebars(string)
if ::Rails.env.development?
"(function() { try { return Ember.Handlebars.compile(#{indent(string).inspect}); } catch(err) { throw err; } })()"
else
"Handlebars.compile(#{indent(string).inspect});"
end
end
end
end
end

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff