summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkpdecker <kpdecker@gmail.com>2012-08-21 12:49:40 -0500
committerkpdecker <kpdecker@gmail.com>2012-08-21 12:49:40 -0500
commitdc0426d836027b611b61ebdf0a491e9e6ab889db (patch)
tree8ef9806dbd558719dad3f90a344230bb416a70a2
parentfc99d90337b6a9e21a498d8b4f52fdc9ad7b156c (diff)
parent6761d4c6d16893f1a347d69956f926f56124e841 (diff)
downloadhandlebars.js-dc0426d836027b611b61ebdf0a491e9e6ab889db.zip
handlebars.js-dc0426d836027b611b61ebdf0a491e9e6ab889db.tar.gz
handlebars.js-dc0426d836027b611b61ebdf0a491e9e6ab889db.tar.bz2
Merge with upstream/master
-rwxr-xr-xbin/handlebars24
-rw-r--r--lib/handlebars/compiler/compiler.js8
-rw-r--r--spec/parser_spec.rb4
-rw-r--r--spec/qunit_spec.js27
-rw-r--r--src/handlebars.l1
5 files changed, 61 insertions, 3 deletions
diff --git a/bin/handlebars b/bin/handlebars
index 2c03b0b..7a2fc1c 100755
--- a/bin/handlebars
+++ b/bin/handlebars
@@ -7,6 +7,17 @@ var optimist = require('optimist')
'description': 'Output File',
'alias': 'output'
},
+ 'a': {
+ 'type': 'boolean',
+ 'description': 'Exports amd style (require.js)',
+ 'alias': 'amd'
+ },
+ 'h': {
+ 'type': 'string',
+ 'description': 'Path to handlebar.js (only valid for amd-style)',
+ 'alias': 'handlebarPath',
+ 'default': ''
+ },
'k': {
'type': 'string',
'description': 'Known helpers',
@@ -78,7 +89,12 @@ if (argv.known) {
var output = [];
if (!argv.simple) {
- output.push('(function() {\n var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};\n');
+ if (argv.amd) {
+ output.push('define([\'' + argv.handlebarPath + 'handlebars\'], function(Handlebars) {\n');
+ } else {
+ output.push('(function() {\n');
+ }
+ output.push(' var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};\n');
}
function processTemplate(template, root) {
var path = template,
@@ -121,7 +137,11 @@ argv._.forEach(function(template) {
// Output the content
if (!argv.simple) {
- output.push('})();');
+ if (argv.amd) {
+ output.push('});');
+ } else {
+ output.push('})();');
+ }
}
output = output.join('');
diff --git a/lib/handlebars/compiler/compiler.js b/lib/handlebars/compiler/compiler.js
index ca59725..108d055 100644
--- a/lib/handlebars/compiler/compiler.js
+++ b/lib/handlebars/compiler/compiler.js
@@ -240,7 +240,13 @@ Handlebars.JavaScriptCompiler = function() {};
ID: function(id) {
this.addDepth(id.depth);
this.opcode('getContext', id.depth);
- this.opcode('lookupOnContext', id.parts[0]);
+
+ var name = id.parts[0];
+ if (!name) {
+ this.opcode('pushContext');
+ } else {
+ this.opcode('lookupOnContext', id.parts[0]);
+ }
for(var i=1, l=id.parts.length; i<l; i++) {
this.opcode('lookup', id.parts[i]);
diff --git a/spec/parser_spec.rb b/spec/parser_spec.rb
index 3fe9029..2b234d3 100644
--- a/spec/parser_spec.rb
+++ b/spec/parser_spec.rb
@@ -172,6 +172,10 @@ describe "Parser" do
mustache id("foo"), [], hash(["bar", "ID:baz"], ["bat", "\"bam\""])
end
+ ast_for("{{foo bat='bam'}}").should == root do
+ mustache id("foo"), [], hash(["bat", "\"bam\""])
+ end
+
ast_for("{{foo omg bar=baz bat=\"bam\"}}").should == root do
mustache id("foo"), [id("omg")], hash(["bar", id("baz")], ["bat", string("bam")])
end
diff --git a/spec/qunit_spec.js b/spec/qunit_spec.js
index f405530..cbbc138 100644
--- a/spec/qunit_spec.js
+++ b/spec/qunit_spec.js
@@ -187,6 +187,20 @@ test("this keyword in paths", function() {
shouldCompileTo(string, hash, "helloHelloHELLO", "This keyword evaluates in more complex paths");
});
+test("this keyword in helpers", function() {
+ var helpers = {foo: function(value, options) {
+ return 'bar ' + value;
+ }};
+ var string = "{{#goodbyes}}{{foo this}}{{/goodbyes}}";
+ var hash = {goodbyes: ["goodbye", "Goodbye", "GOODBYE"]};
+ shouldCompileTo(string, [hash, helpers], "bar goodbyebar Goodbyebar GOODBYE",
+ "This keyword in paths evaluates to current context");
+
+ string = "{{#hellos}}{{foo this/text}}{{/hellos}}";
+ hash = {hellos: [{text: "hello"}, {text: "Hello"}, {text: "HELLO"}]};
+ shouldCompileTo(string, [hash, helpers], "bar hellobar Hellobar HELLO", "This keyword evaluates in more complex paths");
+});
+
suite("inverted sections");
test("inverted sections with unset value", function() {
@@ -1002,6 +1016,19 @@ test("block helpers can take an optional hash", function() {
equals(result, "GOODBYE CRUEL world 12 TIMES", "Hash parameters output");
});
+test("block helpers can take an optional hash with single quoted stings", function() {
+ var template = CompilerContext.compile("{{#goodbye cruel='CRUEL' times=12}}world{{/goodbye}}");
+
+ var helpers = {
+ goodbye: function(options) {
+ return "GOODBYE " + options.hash.cruel + " " + options.fn(this) + " " + options.hash.times + " TIMES";
+ }
+ };
+
+ var result = template({}, {helpers: helpers});
+ equals(result, "GOODBYE CRUEL world 12 TIMES", "Hash parameters output");
+});
+
test("block helpers can take an optional hash with booleans", function() {
var helpers = {
goodbye: function(options) {
diff --git a/src/handlebars.l b/src/handlebars.l
index f81fcdb..2e0c4f7 100644
--- a/src/handlebars.l
+++ b/src/handlebars.l
@@ -31,6 +31,7 @@
<mu>"}}}" { this.popState(); return 'CLOSE'; }
<mu>"}}" { this.popState(); return 'CLOSE'; }
<mu>'"'("\\"["]|[^"])*'"' { yytext = yytext.substr(1,yyleng-2).replace(/\\"/g,'"'); return 'STRING'; }
+<mu>"'"("\\"[']|[^'])*"'" { yytext = yytext.substr(1,yyleng-2).replace(/\\"/g,'"'); return 'STRING'; }
<mu>"@"[a-zA-Z]+ { yytext = yytext.substr(1); return 'DATA'; }
<mu>"true"/[}\s] { return 'BOOLEAN'; }
<mu>"false"/[}\s] { return 'BOOLEAN'; }