Merge commit '87b5d4ee61605b026506e92c9e8873d867c5f150' into es6-modules

Conflicts:
	dist/handlebars.js
	dist/handlebars.runtime.js
	lib/handlebars/base.js
	lib/handlebars/utils.js
This commit is contained in:
kpdecker
2013-09-02 16:19:28 -05:00
11 changed files with 96 additions and 64 deletions
+5
View File
@@ -1,9 +1,14 @@
.DS_Store
.gitignore
.rvmrc
.jshintrc
.travis.yml
.rspec
Gemfile
Gemfile.lock
Rakefile
*.gemspec
*.nuspec
bench/*
spec/*
src/*
+23 -10
View File
@@ -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
+2 -2
View File
@@ -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.
+1 -1
View File
@@ -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);
@@ -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');
},
+2 -2
View File
@@ -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);
+2
View File
@@ -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))
+2
View File
@@ -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() {
+2 -2
View File
@@ -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() {
+53 -43
View File
@@ -1,49 +1,14 @@
%x mu emu com
%%
%{
"\\\\"/("{{") 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) return 'CONTENT';
}
function strip(start, end) {
return yytext = yytext.substr(start, yyleng-end);
}
[^\x00]+ return 'CONTENT';
%}
<emu>[^\x00]{2,}?/("{{"|<<EOF>>) {
if(yytext.slice(-1) !== "\\") this.popState();
if(yytext.slice(-1) === "\\") yytext = yytext.substr(0,yyleng-1);
return 'CONTENT';
}
<com>[\s\S]*?"--}}" yytext = yytext.substr(0, yyleng-4); this.popState(); return 'COMMENT';
<mu>"{{>" return 'OPEN_PARTIAL';
<mu>"{{#" return 'OPEN_BLOCK';
<mu>"{{/" return 'OPEN_ENDBLOCK';
<mu>"{{^" return 'OPEN_INVERSE';
<mu>"{{"\s*"else" return 'OPEN_INVERSE';
<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>"{{" return 'OPEN';
<mu>"=" return 'EQUALS';
<mu>"."/[}\/ ] return 'ID';
<mu>".." return 'ID';
<mu>[\/.] return 'SEP';
<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>"@" 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.
@@ -54,10 +19,55 @@ Control characters ranges:
[\[-\^`] [, \, ], ^, `, Exceptions in range: _
[\{-~] {, |, }, ~
*/
<mu>[^\s!"#%-,\.\/;->@\[-\^`\{-~]+/[=}\s\/.] return 'ID';
ID [^\s!"#%-,\.\/;->@\[-\^`\{-~]+/[=}\s\/.]
<mu>'['[^\]]*']' yytext = yytext.substr(1, yyleng-2); return 'ID';
%%
"\\\\"/("{{") yytext = "\\"; return 'CONTENT';
[^\x00]*?/("{{") {
if(yytext.slice(-1) !== "\\") this.begin("mu");
if(yytext.slice(-1) === "\\") strip(0,1), this.begin("emu");
if(yytext) return 'CONTENT';
}
[^\x00]+ return 'CONTENT';
<emu>[^\x00]{2,}?/("{{"|<<EOF>>) {
if(yytext.slice(-1) !== "\\") this.popState();
if(yytext.slice(-1) === "\\") strip(0,1);
return 'CONTENT';
}
<com>[\s\S]*?"--}}" strip(0,4); this.popState(); return 'COMMENT';
<mu>"{{>" return 'OPEN_PARTIAL';
<mu>"{{#" return 'OPEN_BLOCK';
<mu>"{{/" return 'OPEN_ENDBLOCK';
<mu>"{{^" return 'OPEN_INVERSE';
<mu>"{{"\s*"else" return 'OPEN_INVERSE';
<mu>"{{{" return 'OPEN_UNESCAPED';
<mu>"{{&" return 'OPEN';
<mu>"{{!--" this.popState(); this.begin('com');
<mu>"{{!"[\s\S]*?"}}" strip(3,5); this.popState(); return 'COMMENT';
<mu>"{{" return 'OPEN';
<mu>"=" return 'EQUALS';
<mu>"."/[}\/ ] return 'ID';
<mu>".." return 'ID';
<mu>[\/.] return 'SEP';
<mu>\s+ /*ignore whitespace*/
<mu>"}}}" this.popState(); return 'CLOSE_UNESCAPED';
<mu>"}}" this.popState(); return 'CLOSE';
<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';
<mu>{ID} return 'ID';
<mu>'['[^\]]*']' yytext = strip(1,2); return 'ID';
<mu>. return 'INVALID';
<INITIAL,mu><<EOF>> return 'EOF';
+1 -1
View File
@@ -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([])
;