diff --git a/app/views/layouts/_templates.haml b/app/views/layouts/_templates.haml
index 625d7bb8f..70d26edcf 100644
--- a/app/views/layouts/_templates.haml
+++ b/app/views/layouts/_templates.haml
@@ -3,3 +3,9 @@
- template_name = File.basename(template, ".jst").gsub("_","-")
%script{:id => "#{template_name}-template", :type => 'text/template'}
!= File.read(templates_dir.join(template))
+
+- #don't tell my mom I did this, okay?
+- Dir[templates_dir.to_s + "/*.handlebars"].each do |template|
+ - template_name = File.basename(template, ".handlebars").gsub("_","-")
+ %script{:id => "#{template_name}-template", :type => 'text/template'}
+ != File.read(templates_dir.join(template))
diff --git a/app/views/templates/static_text.handlebars b/app/views/templates/static_text.handlebars
new file mode 100644
index 000000000..1c37e4a9c
--- /dev/null
+++ b/app/views/templates/static_text.handlebars
@@ -0,0 +1 @@
+{{ text }}
diff --git a/app/views/templates/static_text.jst b/app/views/templates/static_text.jst
deleted file mode 100644
index 41f6ae6d9..000000000
--- a/app/views/templates/static_text.jst
+++ /dev/null
@@ -1 +0,0 @@
-<%= text %>
diff --git a/app/views/templates/stream_faces.handlebars b/app/views/templates/stream_faces.handlebars
new file mode 100644
index 000000000..981fb390a
--- /dev/null
+++ b/app/views/templates/stream_faces.handlebars
@@ -0,0 +1,5 @@
+{{#people}}
+
+
+
+{{/people}}
diff --git a/app/views/templates/stream_faces.jst b/app/views/templates/stream_faces.jst
deleted file mode 100644
index 687793d5b..000000000
--- a/app/views/templates/stream_faces.jst
+++ /dev/null
@@ -1,5 +0,0 @@
-<% _.each(people, function(person) { %>
-
-
-
-<% }) %>
diff --git a/config/assets.yml b/config/assets.yml
index 18ab3a21b..375a1fa4b 100644
--- a/config/assets.yml
+++ b/config/assets.yml
@@ -9,6 +9,7 @@ javascripts:
main:
- public/javascripts/vendor/underscore.js
- public/javascripts/vendor/backbone.js
+ - public/javascripts/vendor/handlebars-1.0.0.beta.6.js
- public/javascripts/vendor/markdown/*
- public/javascripts/app/app.js
- public/javascripts/app/helpers/*
diff --git a/public/javascripts/app/views.js b/public/javascripts/app/views.js
index 4ff454ecb..bd3c24301 100644
--- a/public/javascripts/app/views.js
+++ b/public/javascripts/app/views.js
@@ -22,9 +22,18 @@ app.views.Base = Backbone.View.extend({
},
renderTemplate : function(){
- var templateHTML = $(this.template_name).html(); //don't forget to regenerate your jasmine fixtures ;-)
- this.template = _.template(templateHTML);
+ var templateHTML //don't forget to regenerate your jasmine fixtures ;-)
var presenter = _.isFunction(this.presenter) ? this.presenter() : this.presenter
+
+ if(this.legacyTemplate) {
+ templateHTML = $(this.template_name).html();
+ this.template = _.template(templateHTML);
+ } else {
+ window.templateCache = window.templateCache || {}
+ templateHTML = $("#" + this.templateName + "-template").html(); //don't forget to regenerate your jasmine fixtures ;-)
+ this.template = templateCache[this.templateName] = templateCache[this.templateName] || Handlebars.compile(templateHTML);
+ }
+
$(this.el).html(this.template(presenter));
this.postRenderTemplate();
},
diff --git a/public/javascripts/app/views/comment_view.js b/public/javascripts/app/views/comment_view.js
index 167d4547b..e05fcfc6d 100644
--- a/public/javascripts/app/views/comment_view.js
+++ b/public/javascripts/app/views/comment_view.js
@@ -1,5 +1,6 @@
app.views.Comment = app.views.Content.extend({
+ legacyTemplate : true,
template_name: "#comment-template",
tagName : "li",
diff --git a/public/javascripts/app/views/commment_stream_view.js b/public/javascripts/app/views/commment_stream_view.js
index 10fccdb7a..9f8ea5455 100644
--- a/public/javascripts/app/views/commment_stream_view.js
+++ b/public/javascripts/app/views/commment_stream_view.js
@@ -1,5 +1,6 @@
app.views.CommentStream = app.views.Base.extend({
+ legacyTemplate : true,
template_name: "#comment-stream-template",
className : "comment_stream",
diff --git a/public/javascripts/app/views/content_view.js b/public/javascripts/app/views/content_view.js
index 461f7f6f8..ba0a5feca 100644
--- a/public/javascripts/app/views/content_view.js
+++ b/public/javascripts/app/views/content_view.js
@@ -1,4 +1,5 @@
app.views.Content = app.views.StreamObject.extend({
+ legacyTemplate : true,
presenter : function(){
var model = this.model
return _.extend(this.defaultPresenter(), {
diff --git a/public/javascripts/app/views/feedback_view.js b/public/javascripts/app/views/feedback_view.js
index bfa7110ad..4ab7c4c63 100644
--- a/public/javascripts/app/views/feedback_view.js
+++ b/public/javascripts/app/views/feedback_view.js
@@ -1,4 +1,5 @@
app.views.Feedback = app.views.StreamObject.extend({
+ legacyTemplate : true,
template_name: "#feedback-template",
className : "info",
diff --git a/public/javascripts/app/views/header_view.js b/public/javascripts/app/views/header_view.js
index 287aea407..c9a2db120 100644
--- a/public/javascripts/app/views/header_view.js
+++ b/public/javascripts/app/views/header_view.js
@@ -1,4 +1,5 @@
app.views.Header = app.views.Base.extend({
+ legacyTemplate : true,
template_name : "#header-template",
diff --git a/public/javascripts/app/views/likes_info_view.js b/public/javascripts/app/views/likes_info_view.js
index d889b1c67..9d87af7be 100644
--- a/public/javascripts/app/views/likes_info_view.js
+++ b/public/javascripts/app/views/likes_info_view.js
@@ -1,11 +1,12 @@
app.views.LikesInfo = app.views.StreamObject.extend({
+ legacyTemplate : true,
template_name : "#likes-info-template",
className : "likes_container",
events : {
- "click .expand_likes" : "showAvatars"
+ "click .expand_likes" : "showAvatars"
},
tooltipSelector : ".avatar",
@@ -15,12 +16,12 @@ app.views.LikesInfo = app.views.StreamObject.extend({
},
showAvatars : function(evt){
- if(evt) { evt.preventDefault() }
- var self = this;
- this.model.likes.fetch()
- .done(function(resp){
+ if(evt) { evt.preventDefault() }
+ var self = this;
+ this.model.likes.fetch()
+ .done(function(resp){
// set like attribute and like collection
self.model.set({likes : self.model.likes.reset(resp)})
- })
- }
+ })
+ }
});
diff --git a/public/javascripts/app/views/post_view.js b/public/javascripts/app/views/post_view.js
index 94011ecfc..de99742d5 100644
--- a/public/javascripts/app/views/post_view.js
+++ b/public/javascripts/app/views/post_view.js
@@ -1,4 +1,5 @@
app.views.Post = app.views.StreamObject.extend({
+ legacyTemplate : true,
template_name: "#stream-element-template",
@@ -28,11 +29,14 @@ app.views.Post = app.views.StreamObject.extend({
//subviews
this.commentStreamView = new app.views.CommentStream({ model : this.model});
- this.likesInfoView = new app.views.LikesInfo({ model : this.model});
return this;
},
+ likesInfoView : function(){
+ return new app.views.LikesInfo({ model : this.model});
+ },
+
feedbackView : function(){
if(!window.app.user().current_user ) { return null }
return new app.views.Feedback({model : this.model});
diff --git a/public/javascripts/app/views/stream_faces_view.js b/public/javascripts/app/views/stream_faces_view.js
index ae5232fc7..eb2075462 100644
--- a/public/javascripts/app/views/stream_faces_view.js
+++ b/public/javascripts/app/views/stream_faces_view.js
@@ -1,6 +1,5 @@
app.views.StreamFaces = app.views.Base.extend({
-
- template_name : "#stream-faces-template",
+ templateName : "stream-faces",
className : "stream-faces",
diff --git a/public/javascripts/app/views/stream_view.js b/public/javascripts/app/views/stream_view.js
index 837dacffe..99d1dbcd2 100644
--- a/public/javascripts/app/views/stream_view.js
+++ b/public/javascripts/app/views/stream_view.js
@@ -1,4 +1,5 @@
app.views.Stream = Backbone.View.extend({
+ legacyTemplate : true,
events: {
"click #paginate": "render"
},
diff --git a/public/javascripts/vendor/handlebars-1.0.0.beta.6.js b/public/javascripts/vendor/handlebars-1.0.0.beta.6.js
new file mode 100644
index 000000000..83119ff88
--- /dev/null
+++ b/public/javascripts/vendor/handlebars-1.0.0.beta.6.js
@@ -0,0 +1,1550 @@
+// lib/handlebars/base.js
+var Handlebars = {};
+
+Handlebars.VERSION = "1.0.beta.6";
+
+Handlebars.helpers = {};
+Handlebars.partials = {};
+
+Handlebars.registerHelper = function(name, fn, inverse) {
+ if(inverse) { fn.not = inverse; }
+ this.helpers[name] = fn;
+};
+
+Handlebars.registerPartial = function(name, str) {
+ this.partials[name] = str;
+};
+
+Handlebars.registerHelper('helperMissing', function(arg) {
+ if(arguments.length === 2) {
+ return undefined;
+ } else {
+ throw new Error("Could not find property '" + arg + "'");
+ }
+});
+
+var toString = Object.prototype.toString, functionType = "[object Function]";
+
+Handlebars.registerHelper('blockHelperMissing', function(context, options) {
+ var inverse = options.inverse || function() {}, fn = options.fn;
+
+
+ var ret = "";
+ var type = toString.call(context);
+
+ if(type === functionType) { context = context.call(this); }
+
+ if(context === true) {
+ return fn(this);
+ } else if(context === false || context == null) {
+ return inverse(this);
+ } else if(type === "[object Array]") {
+ if(context.length > 0) {
+ for(var i=0, j=context.length; i 0) {
+ for(var i=0, j=context.length; i 2) {
+ expected.push("'" + this.terminals_[p] + "'");
+ }
+ var errStr = "";
+ if (this.lexer.showPosition) {
+ errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + this.terminals_[symbol] + "'";
+ } else {
+ errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
+ }
+ this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
+ }
+ }
+ if (action[0] instanceof Array && action.length > 1) {
+ throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
+ }
+ switch (action[0]) {
+ case 1:
+ stack.push(symbol);
+ vstack.push(this.lexer.yytext);
+ lstack.push(this.lexer.yylloc);
+ stack.push(action[1]);
+ symbol = null;
+ if (!preErrorSymbol) {
+ yyleng = this.lexer.yyleng;
+ yytext = this.lexer.yytext;
+ yylineno = this.lexer.yylineno;
+ yyloc = this.lexer.yylloc;
+ if (recovering > 0)
+ recovering--;
+ } else {
+ symbol = preErrorSymbol;
+ preErrorSymbol = null;
+ }
+ break;
+ case 2:
+ len = this.productions_[action[1]][1];
+ yyval.$ = vstack[vstack.length - len];
+ yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
+ r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
+ if (typeof r !== "undefined") {
+ return r;
+ }
+ if (len) {
+ stack = stack.slice(0, -1 * len * 2);
+ vstack = vstack.slice(0, -1 * len);
+ lstack = lstack.slice(0, -1 * len);
+ }
+ stack.push(this.productions_[action[1]][0]);
+ vstack.push(yyval.$);
+ lstack.push(yyval._$);
+ newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
+ stack.push(newState);
+ break;
+ case 3:
+ return true;
+ }
+ }
+ return true;
+}
+};/* Jison generated lexer */
+var lexer = (function(){
+
+var lexer = ({EOF:1,
+parseError:function parseError(str, hash) {
+ if (this.yy.parseError) {
+ this.yy.parseError(str, hash);
+ } else {
+ throw new Error(str);
+ }
+ },
+setInput:function (input) {
+ this._input = input;
+ this._more = this._less = this.done = false;
+ this.yylineno = this.yyleng = 0;
+ this.yytext = this.matched = this.match = '';
+ this.conditionStack = ['INITIAL'];
+ this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
+ return this;
+ },
+input:function () {
+ var ch = this._input[0];
+ this.yytext+=ch;
+ this.yyleng++;
+ this.match+=ch;
+ this.matched+=ch;
+ var lines = ch.match(/\n/);
+ if (lines) this.yylineno++;
+ this._input = this._input.slice(1);
+ return ch;
+ },
+unput:function (ch) {
+ this._input = ch + this._input;
+ return this;
+ },
+more:function () {
+ this._more = true;
+ return this;
+ },
+pastInput:function () {
+ var past = this.matched.substr(0, this.matched.length - this.match.length);
+ return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
+ },
+upcomingInput:function () {
+ var next = this.match;
+ if (next.length < 20) {
+ next += this._input.substr(0, 20-next.length);
+ }
+ return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
+ },
+showPosition:function () {
+ var pre = this.pastInput();
+ var c = new Array(pre.length + 1).join("-");
+ return pre + this.upcomingInput() + "\n" + c+"^";
+ },
+next:function () {
+ if (this.done) {
+ return this.EOF;
+ }
+ if (!this._input) this.done = true;
+
+ var token,
+ match,
+ col,
+ lines;
+ if (!this._more) {
+ this.yytext = '';
+ this.match = '';
+ }
+ var rules = this._currentRules();
+ for (var i=0;i < rules.length; i++) {
+ match = this._input.match(this.rules[rules[i]]);
+ if (match) {
+ lines = match[0].match(/\n.*/g);
+ if (lines) this.yylineno += lines.length;
+ this.yylloc = {first_line: this.yylloc.last_line,
+ last_line: this.yylineno+1,
+ first_column: this.yylloc.last_column,
+ last_column: lines ? lines[lines.length-1].length-1 : this.yylloc.last_column + match[0].length}
+ this.yytext += match[0];
+ this.match += match[0];
+ this.matches = match;
+ this.yyleng = this.yytext.length;
+ this._more = false;
+ this._input = this._input.slice(match[0].length);
+ this.matched += match[0];
+ token = this.performAction.call(this, this.yy, this, rules[i],this.conditionStack[this.conditionStack.length-1]);
+ if (token) return token;
+ else return;
+ }
+ }
+ if (this._input === "") {
+ return this.EOF;
+ } else {
+ this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
+ {text: "", token: null, line: this.yylineno});
+ }
+ },
+lex:function lex() {
+ var r = this.next();
+ if (typeof r !== 'undefined') {
+ return r;
+ } else {
+ return this.lex();
+ }
+ },
+begin:function begin(condition) {
+ this.conditionStack.push(condition);
+ },
+popState:function popState() {
+ return this.conditionStack.pop();
+ },
+_currentRules:function _currentRules() {
+ return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
+ },
+topState:function () {
+ return this.conditionStack[this.conditionStack.length-2];
+ },
+pushState:function begin(condition) {
+ this.begin(condition);
+ }});
+lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
+
+var YYSTATE=YY_START
+switch($avoiding_name_collisions) {
+case 0:
+ if(yy_.yytext.slice(-1) !== "\\") this.begin("mu");
+ if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1), this.begin("emu");
+ if(yy_.yytext) return 14;
+
+break;
+case 1: return 14;
+break;
+case 2: this.popState(); return 14;
+break;
+case 3: return 24;
+break;
+case 4: return 16;
+break;
+case 5: return 20;
+break;
+case 6: return 19;
+break;
+case 7: return 19;
+break;
+case 8: return 23;
+break;
+case 9: return 23;
+break;
+case 10: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.popState(); return 15;
+break;
+case 11: return 22;
+break;
+case 12: return 34;
+break;
+case 13: return 33;
+break;
+case 14: return 33;
+break;
+case 15: return 36;
+break;
+case 16: /*ignore whitespace*/
+break;
+case 17: this.popState(); return 18;
+break;
+case 18: this.popState(); return 18;
+break;
+case 19: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 28;
+break;
+case 20: return 30;
+break;
+case 21: return 30;
+break;
+case 22: return 29;
+break;
+case 23: return 33;
+break;
+case 24: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 33;
+break;
+case 25: return 'INVALID';
+break;
+case 26: return 5;
+break;
+}
+};
+lexer.rules = [/^[^\x00]*?(?=(\{\{))/,/^[^\x00]+/,/^[^\x00]{2,}?(?=(\{\{))/,/^\{\{>/,/^\{\{#/,/^\{\{\//,/^\{\{\^/,/^\{\{\s*else\b/,/^\{\{\{/,/^\{\{&/,/^\{\{![\s\S]*?\}\}/,/^\{\{/,/^=/,/^\.(?=[} ])/,/^\.\./,/^[\/.]/,/^\s+/,/^\}\}\}/,/^\}\}/,/^"(\\["]|[^"])*"/,/^true(?=[}\s])/,/^false(?=[}\s])/,/^[0-9]+(?=[}\s])/,/^[a-zA-Z0-9_$-]+(?=[=}\s\/.])/,/^\[[^\]]*\]/,/^./,/^$/];
+lexer.conditions = {"mu":{"rules":[3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"INITIAL":{"rules":[0,1,26],"inclusive":true}};return lexer;})()
+parser.lexer = lexer;
+return parser;
+})();
+if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
+exports.parser = handlebars;
+exports.parse = function () { return handlebars.parse.apply(handlebars, arguments); }
+exports.main = function commonjsMain(args) {
+ if (!args[1])
+ throw new Error('Usage: '+args[0]+' FILE');
+ if (typeof process !== 'undefined') {
+ var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8");
+ } else {
+ var cwd = require("file").path(require("file").cwd());
+ var source = cwd.join(args[1]).read({charset: "utf-8"});
+ }
+ return exports.parser.parse(source);
+}
+if (typeof module !== 'undefined' && require.main === module) {
+ exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args);
+}
+};
+;
+// lib/handlebars/compiler/base.js
+Handlebars.Parser = handlebars;
+
+Handlebars.parse = function(string) {
+ Handlebars.Parser.yy = Handlebars.AST;
+ return Handlebars.Parser.parse(string);
+};
+
+Handlebars.print = function(ast) {
+ return new Handlebars.PrintVisitor().accept(ast);
+};
+
+Handlebars.logger = {
+ DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
+
+ // override in the host environment
+ log: function(level, str) {}
+};
+
+Handlebars.log = function(level, str) { Handlebars.logger.log(level, str); };
+;
+// lib/handlebars/compiler/ast.js
+(function() {
+
+ Handlebars.AST = {};
+
+ Handlebars.AST.ProgramNode = function(statements, inverse) {
+ this.type = "program";
+ this.statements = statements;
+ if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
+ };
+
+ Handlebars.AST.MustacheNode = function(params, hash, unescaped) {
+ this.type = "mustache";
+ this.id = params[0];
+ this.params = params.slice(1);
+ this.hash = hash;
+ this.escaped = !unescaped;
+ };
+
+ Handlebars.AST.PartialNode = function(id, context) {
+ this.type = "partial";
+
+ // TODO: disallow complex IDs
+
+ this.id = id;
+ this.context = context;
+ };
+
+ var verifyMatch = function(open, close) {
+ if(open.original !== close.original) {
+ throw new Handlebars.Exception(open.original + " doesn't match " + close.original);
+ }
+ };
+
+ Handlebars.AST.BlockNode = function(mustache, program, close) {
+ verifyMatch(mustache.id, close);
+ this.type = "block";
+ this.mustache = mustache;
+ this.program = program;
+ };
+
+ Handlebars.AST.InverseNode = function(mustache, program, close) {
+ verifyMatch(mustache.id, close);
+ this.type = "inverse";
+ this.mustache = mustache;
+ this.program = program;
+ };
+
+ Handlebars.AST.ContentNode = function(string) {
+ this.type = "content";
+ this.string = string;
+ };
+
+ Handlebars.AST.HashNode = function(pairs) {
+ this.type = "hash";
+ this.pairs = pairs;
+ };
+
+ Handlebars.AST.IdNode = function(parts) {
+ this.type = "ID";
+ this.original = parts.join(".");
+
+ var dig = [], depth = 0;
+
+ for(var i=0,l=parts.length; i": ">",
+ '"': """,
+ "'": "'",
+ "`": "`"
+ };
+
+ var badChars = /&(?!\w+;)|[<>"'`]/g;
+ var possible = /[&<>"'`]/;
+
+ var escapeChar = function(chr) {
+ return escape[chr] || "&";
+ };
+
+ Handlebars.Utils = {
+ escapeExpression: function(string) {
+ // don't escape SafeStrings, since they're already safe
+ if (string instanceof Handlebars.SafeString) {
+ return string.toString();
+ } else if (string == null || string === false) {
+ return "";
+ }
+
+ if(!possible.test(string)) { return string; }
+ return string.replace(badChars, escapeChar);
+ },
+
+ isEmpty: function(value) {
+ if (typeof value === "undefined") {
+ return true;
+ } else if (value === null) {
+ return true;
+ } else if (value === false) {
+ return true;
+ } else if(Object.prototype.toString.call(value) === "[object Array]" && value.length === 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ };
+})();;
+// lib/handlebars/compiler/compiler.js
+Handlebars.Compiler = function() {};
+Handlebars.JavaScriptCompiler = function() {};
+
+(function(Compiler, JavaScriptCompiler) {
+ Compiler.OPCODE_MAP = {
+ appendContent: 1,
+ getContext: 2,
+ lookupWithHelpers: 3,
+ lookup: 4,
+ append: 5,
+ invokeMustache: 6,
+ appendEscaped: 7,
+ pushString: 8,
+ truthyOrFallback: 9,
+ functionOrFallback: 10,
+ invokeProgram: 11,
+ invokePartial: 12,
+ push: 13,
+ assignToHash: 15,
+ pushStringParam: 16
+ };
+
+ Compiler.MULTI_PARAM_OPCODES = {
+ appendContent: 1,
+ getContext: 1,
+ lookupWithHelpers: 2,
+ lookup: 1,
+ invokeMustache: 3,
+ pushString: 1,
+ truthyOrFallback: 1,
+ functionOrFallback: 1,
+ invokeProgram: 3,
+ invokePartial: 1,
+ push: 1,
+ assignToHash: 1,
+ pushStringParam: 1
+ };
+
+ Compiler.DISASSEMBLE_MAP = {};
+
+ for(var prop in Compiler.OPCODE_MAP) {
+ var value = Compiler.OPCODE_MAP[prop];
+ Compiler.DISASSEMBLE_MAP[value] = prop;
+ }
+
+ Compiler.multiParamSize = function(code) {
+ return Compiler.MULTI_PARAM_OPCODES[Compiler.DISASSEMBLE_MAP[code]];
+ };
+
+ Compiler.prototype = {
+ compiler: Compiler,
+
+ disassemble: function() {
+ var opcodes = this.opcodes, opcode, nextCode;
+ var out = [], str, name, value;
+
+ for(var i=0, l=opcodes.length; i 0) {
+ this.source[1] = this.source[1] + ", " + locals.join(", ");
+ }
+
+ // Generate minimizer alias mappings
+ if (!this.isChild) {
+ var aliases = []
+ for (var alias in this.context.aliases) {
+ this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
+ }
+ }
+
+ if (this.source[1]) {
+ this.source[1] = "var " + this.source[1].substring(2) + ";";
+ }
+
+ // Merge children
+ if (!this.isChild) {
+ this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
+ }
+
+ if (!this.environment.isSimple) {
+ this.source.push("return buffer;");
+ }
+
+ var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
+
+ for(var i=0, l=this.environment.depths.list.length; i this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
+ return "stack" + this.stackSlot;
+ },
+
+ popStack: function() {
+ return "stack" + this.stackSlot--;
+ },
+
+ topStack: function() {
+ return "stack" + this.stackSlot;
+ },
+
+ quotedString: function(str) {
+ return '"' + str
+ .replace(/\\/g, '\\\\')
+ .replace(/"/g, '\\"')
+ .replace(/\n/g, '\\n')
+ .replace(/\r/g, '\\r') + '"';
+ }
+ };
+
+ var reservedWords = (
+ "break else new var" +
+ " case finally return void" +
+ " catch for switch while" +
+ " continue function this with" +
+ " default if throw" +
+ " delete in try" +
+ " do instanceof typeof" +
+ " abstract enum int short" +
+ " boolean export interface static" +
+ " byte extends long super" +
+ " char final native synchronized" +
+ " class float package throws" +
+ " const goto private transient" +
+ " debugger implements protected volatile" +
+ " double import public let yield"
+ ).split(" ");
+
+ var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
+
+ for(var i=0, l=reservedWords.length; i