mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-27 17:46:05 -05:00
PERF: use raw rendering for topic list
rename my handlebars helper to "raw", create ember compat handlebars to handle rendering patch ember rails to use the correct precompiler
This commit is contained in:
parent
e3b88d3688
commit
5729e7df6f
11 changed files with 153 additions and 14 deletions
|
@ -1,4 +1,4 @@
|
|||
Handlebars.registerHelper('handlebars', function(property, options) {
|
||||
Handlebars.registerHelper('raw', function(property, options) {
|
||||
|
||||
var template = Em.TEMPLATES[property + ".raw"];
|
||||
var params = options.hash;
|
||||
|
@ -13,7 +13,3 @@ Handlebars.registerHelper('handlebars', function(property, options) {
|
|||
|
||||
return new Handlebars.SafeString(template(params));
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('get', function(property) {
|
||||
return Em.get(this, property);
|
||||
});
|
105
app/assets/javascripts/discourse/lib/ember_compat_handlebars.js
Normal file
105
app/assets/javascripts/discourse/lib/ember_compat_handlebars.js
Normal file
|
@ -0,0 +1,105 @@
|
|||
// keep IIF for simpler testing
|
||||
|
||||
// EmberCompatHandlebars is a mechanism for quickly rendering templates which is Ember aware
|
||||
// templates are highly compatible with Ember so you don't need to worry about calling "get"
|
||||
// and computed properties function, additionally it uses stringParams like Ember does
|
||||
|
||||
(function(){
|
||||
|
||||
// compat with ie8 in case this gets picked up elsewhere
|
||||
var objectCreate = Object.create || function(parent) {
|
||||
function F() {}
|
||||
F.prototype = parent;
|
||||
return new F();
|
||||
};
|
||||
|
||||
|
||||
var RawHandlebars = objectCreate(Handlebars);
|
||||
|
||||
RawHandlebars.helper = function() {};
|
||||
RawHandlebars.helpers = objectCreate(Handlebars.helpers);
|
||||
|
||||
RawHandlebars.helpers.get = function(context, options){
|
||||
var firstContext = options.contexts[0];
|
||||
var val = firstContext[context];
|
||||
val = val === undefined ? Em.get(firstContext, context): val;
|
||||
return val;
|
||||
};
|
||||
|
||||
// adds compatability so this works with stringParams
|
||||
var stringCompatHelper = function(fn){
|
||||
|
||||
var old = RawHandlebars.helpers[fn];
|
||||
RawHandlebars.helpers[fn] = function(context,options){
|
||||
return old.apply(this, [
|
||||
RawHandlebars.helpers.get(context,options),
|
||||
options
|
||||
]);
|
||||
};
|
||||
};
|
||||
|
||||
stringCompatHelper("each");
|
||||
stringCompatHelper("if");
|
||||
stringCompatHelper("unless");
|
||||
stringCompatHelper("with");
|
||||
|
||||
|
||||
RawHandlebars.Compiler = function() {};
|
||||
RawHandlebars.Compiler.prototype = objectCreate(Handlebars.Compiler.prototype);
|
||||
RawHandlebars.Compiler.prototype.compiler = RawHandlebars.Compiler;
|
||||
|
||||
RawHandlebars.JavaScriptCompiler = function() {};
|
||||
|
||||
RawHandlebars.JavaScriptCompiler.prototype = objectCreate(Handlebars.JavaScriptCompiler.prototype);
|
||||
RawHandlebars.JavaScriptCompiler.prototype.compiler = RawHandlebars.JavaScriptCompiler;
|
||||
RawHandlebars.JavaScriptCompiler.prototype.namespace = "Discourse.EmberCompatHandlebars";
|
||||
|
||||
|
||||
RawHandlebars.Compiler.prototype.mustache = function(mustache) {
|
||||
if ( !(mustache.params.length || mustache.hash)) {
|
||||
|
||||
var id = new Handlebars.AST.IdNode([{ part: 'get' }]);
|
||||
|
||||
if (!mustache.escaped) {
|
||||
mustache.hash = mustache.hash || new Handlebars.AST.HashNode([]);
|
||||
mustache.hash.pairs.push(["unescaped", new Handlebars.AST.StringNode("true")]);
|
||||
}
|
||||
mustache = new Handlebars.AST.MustacheNode([id].concat([mustache.id]), mustache.hash, !mustache.escaped);
|
||||
}
|
||||
|
||||
return Handlebars.Compiler.prototype.mustache.call(this, mustache);
|
||||
};
|
||||
|
||||
RawHandlebars.precompile = function(value, asObject) {
|
||||
var ast = Handlebars.parse(value);
|
||||
|
||||
var options = {
|
||||
knownHelpers: {
|
||||
get: true
|
||||
},
|
||||
data: true,
|
||||
stringParams: true
|
||||
};
|
||||
|
||||
asObject = asObject === undefined ? true : asObject;
|
||||
|
||||
var environment = new RawHandlebars.Compiler().compile(ast, options);
|
||||
return new RawHandlebars.JavaScriptCompiler().compile(environment, options, undefined, asObject);
|
||||
};
|
||||
|
||||
|
||||
RawHandlebars.compile = function(string) {
|
||||
var ast = Handlebars.parse(string);
|
||||
// this forces us to rewrite helpers
|
||||
var options = { data: true, stringParams: true };
|
||||
var environment = new RawHandlebars.Compiler().compile(ast, options);
|
||||
var templateSpec = new RawHandlebars.JavaScriptCompiler().compile(environment, options, undefined, true);
|
||||
|
||||
var template = RawHandlebars.template(templateSpec);
|
||||
|
||||
return template;
|
||||
};
|
||||
|
||||
Discourse.EmberCompatHandlebars = RawHandlebars;
|
||||
|
||||
})();
|
|
@ -48,7 +48,7 @@
|
|||
{{number topic.views numberKey="views_long"}}
|
||||
</td>
|
||||
|
||||
{{handlebars "list/activity_column" topic=topic class="num" tagName="td"}}
|
||||
{{raw "list/activity_column" topic=topic class="num" tagName="td"}}
|
||||
</tr>
|
||||
{{/grouped-each}}
|
||||
</tbody>
|
||||
|
|
|
@ -1 +1 @@
|
|||
<{{this.tagName}} class="{{cold-age-class "topic.createdAt" startDate="topic.bumpedAt" class=this.class}} activity" title="{{get "topic.bumpedAtTitle"}}"><a href="{{get "topic.lastPostUrl"}}">{{format-date "topic.bumpedAt" format="tiny" noTitle=true}}</a></{{this.tagName}}>
|
||||
<{{this.tagName}} class="{{class}} {{cold-age-class topic.createdAt startDate=topic.bumpedAt class=""}} activity" title="{{topic.bumpedAtTitle}}"><a href="{{topic.lastPostUrl}}">{{format-date topic.bumpedAt format="tiny" noTitle=true}}</a></{{this.tagName}}>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
{{#unless hideCategory}}
|
||||
<td class='category'>{{category-link "category" showParent=true}}</td>
|
||||
<td class='category'>{{category-link category showParent=true}}</td>
|
||||
{{/unless}}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<td class='posters'>
|
||||
{{#each posters}}
|
||||
<a href="{{get "user.path"}}" data-user-card="{{this.user.username}}" class="{{get "extras"}}">{{avatar this usernamePath="user.username" imageSize="small"}}</a>
|
||||
<a href="{{user.path}}" data-user-card="{{user.username}}" class="{{extras}}">{{avatar this usernamePath="user.username" imageSize="small"}}</a>
|
||||
{{/each}}
|
||||
</td>
|
||||
|
|
|
@ -27,10 +27,10 @@
|
|||
{{/if}}
|
||||
</td>
|
||||
|
||||
{{handlebars "list/category_column" hideCategory=hideCategory category=category}}
|
||||
{{handlebars "list/posters_column" posters=posters}}
|
||||
{{raw "list/category_column" hideCategory=hideCategory category=category}}
|
||||
{{raw "list/posters_column" posters=posters}}
|
||||
|
||||
{{posts-count-column topic=model class="num" action="showTopicEntrance"}}
|
||||
<td class="num views {{unbound viewsHeat}}">{{number views numberKey="views_long"}}</td>
|
||||
|
||||
{{handlebars "list/activity_column" topic=model class="num" tagName="td"}}
|
||||
{{raw "list/activity_column" topic=model class="num" tagName="td"}}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<div class="topic-item-stats clearfix">
|
||||
<div class="pull-right">
|
||||
{{posts-count-column topic=topic tagName="div" class="num posts" action="clickedPosts"}}
|
||||
{{handlebars "list/activity_column" topic=topic tagName="div" class="num activity last"}}
|
||||
{{raw "list/activity_column" topic=topic tagName="div" class="num activity last"}}
|
||||
</div>
|
||||
{{#unless controller.hideCategory}}
|
||||
<div class='category'>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
{{posts-count-column topic=this tagName="div" class="num posts" action="showTopicEntrance"}}
|
||||
<div class='num activity last'>
|
||||
<a href="{{lastPostUrl}}" title='{{i18n last_post}}: {{{raw-date bumped_at}}}'>{{last_poster_username}}</a>
|
||||
{{handlebars "list/activity_column" topic=this tagName="span" class="age"}}
|
||||
{{raw "list/activity_column" topic=this tagName="span" class="age"}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
|
|
|
@ -8,8 +8,10 @@
|
|||
// This is a BUG we should fix
|
||||
// it is only required here cause preview is not loading it using LAB
|
||||
//= require highlight.pack.js
|
||||
//
|
||||
|
||||
// Stuff we need to load first
|
||||
//= require ./discourse/lib/ember_compat_handlebars
|
||||
//= require ./discourse/lib/computed
|
||||
//= require ./discourse/mixins/scrolling
|
||||
//= require_tree ./discourse/mixins
|
||||
|
|
36
lib/freedom_patches/ember_compat_handlebars.rb
Normal file
36
lib/freedom_patches/ember_compat_handlebars.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
# barber patches to re-route raw compilation via ember compat handlebars
|
||||
#
|
||||
|
||||
module Barber
|
||||
class EmberCompatPrecompiler < Barber::Precompiler
|
||||
|
||||
def self.call(template)
|
||||
"Handlebars.template(#{compile(template)})"
|
||||
end
|
||||
|
||||
def sources
|
||||
[handlebars, precompiler]
|
||||
end
|
||||
|
||||
def precompiler
|
||||
@precompiler ||= StringIO.new <<END
|
||||
var Discourse = {};
|
||||
#{File.read(Rails.root + "app/assets/javascripts/discourse/lib/ember_compat_handlebars.js")}
|
||||
var Barber = {
|
||||
precompile: function(string) {
|
||||
return Discourse.EmberCompatHandlebars.precompile(string).toString();
|
||||
}
|
||||
};
|
||||
END
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Ember::Handlebars::Template
|
||||
def precompile_handlebars(string)
|
||||
"Discourse.EmberCompatHandlebars.template(#{Barber::EmberCompatPrecompiler.compile(string)});"
|
||||
end
|
||||
def compile_handlebars(string)
|
||||
"Discourse.EmberCompatHandlebars.compile(#{indent(string).inspect});"
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue