diff options
author | kpdecker <kpdecker@gmail.com> | 2013-09-02 16:19:28 -0500 |
---|---|---|
committer | kpdecker <kpdecker@gmail.com> | 2013-09-02 16:19:28 -0500 |
commit | 192887cedce6e6155bb1a079ab2802ff28fbd2bf (patch) | |
tree | 8d4165b322cac9c54ecbd94743403d5937070f2a | |
parent | 530f1903aa8ceb80b632d4dc12fcb701b046a946 (diff) | |
parent | 87b5d4ee61605b026506e92c9e8873d867c5f150 (diff) | |
download | handlebars.js-192887cedce6e6155bb1a079ab2802ff28fbd2bf.zip handlebars.js-192887cedce6e6155bb1a079ab2802ff28fbd2bf.tar.gz handlebars.js-192887cedce6e6155bb1a079ab2802ff28fbd2bf.tar.bz2 |
Merge commit '87b5d4ee61605b026506e92c9e8873d867c5f150' into es6-modules
Conflicts:
dist/handlebars.js
dist/handlebars.runtime.js
lib/handlebars/base.js
lib/handlebars/utils.js
-rw-r--r-- | .npmignore | 5 | ||||
-rw-r--r-- | README.markdown | 33 | ||||
-rw-r--r-- | Rakefile | 4 | ||||
-rw-r--r-- | lib/handlebars/base.js | 2 | ||||
-rw-r--r-- | lib/handlebars/compiler/javascript-compiler.js | 6 | ||||
-rw-r--r-- | lib/handlebars/utils.js | 4 | ||||
-rw-r--r-- | release-notes.md | 2 | ||||
-rw-r--r-- | spec/builtins.js | 2 | ||||
-rw-r--r-- | spec/parser.js | 4 | ||||
-rw-r--r-- | src/handlebars.l | 46 | ||||
-rw-r--r-- | src/handlebars.yy | 2 |
11 files changed, 71 insertions, 39 deletions
@@ -1,9 +1,14 @@ .DS_Store .gitignore .rvmrc +.jshintrc +.travis.yml +.rspec Gemfile Gemfile.lock Rakefile +*.gemspec +*.nuspec bench/* spec/* src/* diff --git a/README.markdown b/README.markdown index a279c1a..781113d 100644 --- a/README.markdown +++ b/README.markdown @@ -355,28 +355,41 @@ Known Issues * Using a variable, helper, or partial named `class` causes errors in IE browsers. (Instead, use `className`) Handlebars in the Wild ------------------ +---------------------- + +* [Assemble](http://assemble.io), by [@jonschlinkert](https://github.com/jonschlinkert) + and [@doowb](https://github.com/doowb), is a static site generator that uses Handlebars.js + as its template engine. +* [Ember.js](http://www.emberjs.com) makes Handlebars.js the primary way to + structure your views, also with automatic data binding support. +* [handlebars_assets](http://github.com/leshill/handlebars_assets): A Rails Asset Pipeline gem + from Les Hill (@leshill). +* [handlebars-helpers](https://github.com/assemble/handlebars-helpers) is an extensive library + with 100+ handlebars helpers. +* [hbs](http://github.com/donpark/hbs): An Express.js view engine adapter for Handlebars.js, + from Don Park. * [jblotus](http://github.com/jblotus) created [http://tryhandlebarsjs.com](http://tryhandlebarsjs.com) for anyone who would like to try out Handlebars.js in their browser. -* Don Park wrote an Express.js view engine adapter for Handlebars.js called - [hbs](http://github.com/donpark/hbs). +* [jQuery plugin](http://71104.github.io/jquery-handlebars/): allows you to use + Handlebars.js with [jQuery](http://jquery.com/). +* [Lumbar](http://walmartlabs.github.io/lumbar) provides easy module-based template management for + handlebars projects. * [sammy.js](http://github.com/quirkey/sammy) by Aaron Quint, a.k.a. quirkey, supports Handlebars.js as one of its template plugins. * [SproutCore](http://www.sproutcore.com) uses Handlebars.js as its main templating engine, extending it with automatic data binding support. -* [Ember.js](http://www.emberjs.com) makes Handlebars.js the primary way to - structure your views, also with automatic data binding support. -* Les Hill (@leshill) wrote a Rails Asset Pipeline gem named - [handlebars_assets](http://github.com/leshill/handlebars_assets). -* [Gist about Synchronous and asynchronous loading of external handlebars templates](https://gist.github.com/2287070) -* [Lumbar](walmartlabs.github.io/lumbar) provides easy module-based template management for handlebars projects. * [YUI](http://yuilibrary.com/yui/docs/handlebars/) implements a port of handlebars -* This [jQuery plugin](http://71104.github.io/jquery-handlebars/) allows you to use Handlebars.js with [jQuery](http://jquery.com/). + +External Resources +------------------ + +* [Gist about Synchronous and asynchronous loading of external handlebars templates](https://gist.github.com/2287070) Have a project using Handlebars? Send us a [pull request](https://github.com/wycats/handlebars.js/pull/new/master)! Helping Out ----------- + To build Handlebars.js you'll need a few things installed. * Node.js @@ -79,8 +79,8 @@ task :build => [:compile] do |task| Rake::Task["dist/handlebars.js"].execute Rake::Task["dist/handlebars.runtime.js"].execute - system "./node_modules/.bin/uglifyjs --comments -o dist/handlebars.min.js dist/handlebars.js" - system "./node_modules/.bin/uglifyjs --comments -o dist/handlebars.runtime.min.js dist/handlebars.runtime.js" + system "./node_modules/.bin/uglifyjs -m -c --comments -o dist/handlebars.min.js dist/handlebars.js" + system "./node_modules/.bin/uglifyjs -m -c --comments -o dist/handlebars.runtime.min.js dist/handlebars.runtime.js" end # Updates the various version numbers. diff --git a/lib/handlebars/base.js b/lib/handlebars/base.js index 2e0411d..a6cd7ff 100644 --- a/lib/handlebars/base.js +++ b/lib/handlebars/base.js @@ -117,7 +117,7 @@ function registerDefaultHelpers(instance) { var type = toString.call(conditional); if(type === functionType) { conditional = conditional.call(this); } - if(!conditional || isEmpty(conditional)) { + if (isEmpty(conditional)) { return options.inverse(this); } else { return options.fn(this); diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js index a416431..d3bd258 100644 --- a/lib/handlebars/compiler/javascript-compiler.js +++ b/lib/handlebars/compiler/javascript-compiler.js @@ -348,10 +348,10 @@ JavaScriptCompiler.prototype = { // [lookupData] // // On stack, before: ... - // On stack, after: data[id], ... + // On stack, after: data, ... // - // Push the result of looking up `id` on the current data - lookupData: function(id) { + // Push the data lookup operator + lookupData: function() { this.push('data'); }, diff --git a/lib/handlebars/utils.js b/lib/handlebars/utils.js index d14795c..26d2b54 100644 --- a/lib/handlebars/utils.js +++ b/lib/handlebars/utils.js @@ -19,7 +19,7 @@ export function SafeString(string) { }; SafeString.prototype.toString = function() { - return this.string.toString(); + return "" + this.string; }; var escape = { @@ -57,7 +57,7 @@ export function escapeExpression(string) { // Force a string conversion as this will be done by the append regardless and // the regex test will do this transparently behind the scenes, causing issues if // an object's to string has escaped characters in it. - string = string.toString(); + string = "" + string; if(!possible.test(string)) { return string; } return string.replace(badChars, escapeChar); diff --git a/release-notes.md b/release-notes.md index d2800f9..e7f5ca0 100644 --- a/release-notes.md +++ b/release-notes.md @@ -2,6 +2,8 @@ ## Development +- [#602](https://github.com/wycats/handlebars.js/pull/602) - Handle zero uniformly between mustache conditionals and the if helper ([@artiee](https://github.com/artiee)) +- [#535](https://github.com/wycats/handlebars.js/pull/535) - Fix for probably JIT error under Safari. ([@sorentwo](https://github.com/sorentwo)) - [#537](https://github.com/wycats/handlebars.js/issues/537) - Add CommonJS and AMD loader support ([@spikebrehm](https://github.com/spikebrehm)) - [#544](https://github.com/wycats/handlebars.js/issues/544) - Push travis builds to build server ([@fivetanley](https://github.com/fivetanley)) diff --git a/spec/builtins.js b/spec/builtins.js index bf77d1a..c594294 100644 --- a/spec/builtins.js +++ b/spec/builtins.js @@ -20,6 +20,8 @@ describe('builtin helpers', function() { "if with non-empty array shows the contents"); shouldCompileTo(string, {goodbye: [], world: "world"}, "cruel world!", "if with empty array does not show the contents"); + shouldCompileTo(string, {goodbye: 0, world: "world"}, "GOODBYE cruel world!", + "if with zero does show the contents"); }); it("if with function argument", function() { diff --git a/spec/parser.js b/spec/parser.js index 06a60db..3397105 100644 --- a/spec/parser.js +++ b/spec/parser.js @@ -108,11 +108,11 @@ describe('parser', function() { }); it('parses empty blocks with empty inverse section', function() { - ast_for("{{#foo}}{{^}}{{/foo}}").should.equal("BLOCK:\n {{ ID:foo [] }}\n PROGRAM:\n {{^}}\n"); + ast_for("{{#foo}}{{^}}{{/foo}}").should.equal("BLOCK:\n {{ ID:foo [] }}\n PROGRAM:\n"); }); it('parses empty blocks with empty inverse (else-style) section', function() { - ast_for("{{#foo}}{{else}}{{/foo}}").should.equal("BLOCK:\n {{ ID:foo [] }}\n PROGRAM:\n {{^}}\n"); + ast_for("{{#foo}}{{else}}{{/foo}}").should.equal("BLOCK:\n {{ ID:foo [] }}\n PROGRAM:\n"); }); it('parses non-empty blocks with empty inverse section', function() { diff --git a/src/handlebars.l b/src/handlebars.l index 5fd0bcd..018096b 100644 --- a/src/handlebars.l +++ b/src/handlebars.l @@ -1,12 +1,32 @@ %x mu emu com +%{ + +function strip(start, end) { + return yytext = yytext.substr(start, yyleng-end); +} + +%} + + +/* +ID is the inverse of control characters. +Control characters ranges: + [\s] Whitespace + [!"#%-,\./] !, ", #, %, &, ', (, ), *, +, ,, ., /, Exceptions in range: $, - + [;->@] ;, <, =, >, @, Exceptions in range: :, ? + [\[-\^`] [, \, ], ^, `, Exceptions in range: _ + [\{-~] {, |, }, ~ +*/ +ID [^\s!"#%-,\.\/;->@\[-\^`\{-~]+/[=}\s\/.] + %% "\\\\"/("{{") yytext = "\\"; return 'CONTENT'; [^\x00]*?/("{{") { if(yytext.slice(-1) !== "\\") this.begin("mu"); - if(yytext.slice(-1) === "\\") yytext = yytext.substr(0,yyleng-1), this.begin("emu"); + if(yytext.slice(-1) === "\\") strip(0,1), this.begin("emu"); if(yytext) return 'CONTENT'; } @@ -14,11 +34,11 @@ <emu>[^\x00]{2,}?/("{{"|<<EOF>>) { if(yytext.slice(-1) !== "\\") this.popState(); - if(yytext.slice(-1) === "\\") yytext = yytext.substr(0,yyleng-1); + if(yytext.slice(-1) === "\\") strip(0,1); return 'CONTENT'; } -<com>[\s\S]*?"--}}" yytext = yytext.substr(0, yyleng-4); this.popState(); return 'COMMENT'; +<com>[\s\S]*?"--}}" strip(0,4); this.popState(); return 'COMMENT'; <mu>"{{>" return 'OPEN_PARTIAL'; <mu>"{{#" return 'OPEN_BLOCK'; @@ -28,7 +48,7 @@ <mu>"{{{" return 'OPEN_UNESCAPED'; <mu>"{{&" return 'OPEN'; <mu>"{{!--" this.popState(); this.begin('com'); -<mu>"{{!"[\s\S]*?"}}" yytext = yytext.substr(3,yyleng-5); this.popState(); return 'COMMENT'; +<mu>"{{!"[\s\S]*?"}}" strip(3,5); this.popState(); return 'COMMENT'; <mu>"{{" return 'OPEN'; <mu>"=" return 'EQUALS'; @@ -38,26 +58,16 @@ <mu>\s+ /*ignore whitespace*/ <mu>"}}}" this.popState(); return 'CLOSE_UNESCAPED'; <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>'"'("\\"["]|[^"])*'"' yytext = strip(1,2).replace(/\\"/g,'"'); return 'STRING'; +<mu>"'"("\\"[']|[^'])*"'" yytext = strip(1,2).replace(/\\'/g,"'"); return 'STRING'; <mu>"@" return 'DATA'; <mu>"true"/[}\s] return 'BOOLEAN'; <mu>"false"/[}\s] return 'BOOLEAN'; <mu>\-?[0-9]+/[}\s] return 'INTEGER'; -/* -ID is the inverse of control characters. -Control characters ranges: - [\s] Whitespace - [!"#%-,\./] !, ", #, %, &, ', (, ), *, +, ,, ., /, Exceptions in range: $, - - [;->@] ;, <, =, >, @, Exceptions in range: :, ? - [\[-\^`] [, \, ], ^, `, Exceptions in range: _ - [\{-~] {, |, }, ~ -*/ -<mu>[^\s!"#%-,\.\/;->@\[-\^`\{-~]+/[=}\s\/.] return 'ID'; +<mu>{ID} return 'ID'; -<mu>'['[^\]]*']' yytext = yytext.substr(1, yyleng-2); return 'ID'; +<mu>'['[^\]]*']' yytext = strip(1,2); return 'ID'; <mu>. return 'INVALID'; <INITIAL,mu><<EOF>> return 'EOF'; - diff --git a/src/handlebars.yy b/src/handlebars.yy index 5764f6f..d2f24c4 100644 --- a/src/handlebars.yy +++ b/src/handlebars.yy @@ -13,7 +13,7 @@ program | statements simpleInverse statements -> new yy.ProgramNode($1, $3) | statements simpleInverse -> new yy.ProgramNode($1, []) | statements -> new yy.ProgramNode($1) - | simpleInverse -> new yy.ProgramNode([], []) + | simpleInverse -> new yy.ProgramNode([]) | "" -> new yy.ProgramNode([]) ; |