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:
@@ -1,9 +1,14 @@
|
||||
.DS_Store
|
||||
.gitignore
|
||||
.rvmrc
|
||||
.jshintrc
|
||||
.travis.yml
|
||||
.rspec
|
||||
Gemfile
|
||||
Gemfile.lock
|
||||
Rakefile
|
||||
*.gemspec
|
||||
*.nuspec
|
||||
bench/*
|
||||
spec/*
|
||||
src/*
|
||||
|
||||
+23
-10
@@ -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.
|
||||
|
||||
@@ -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');
|
||||
},
|
||||
|
||||
|
||||
@@ -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,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))
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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([])
|
||||
;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user