Skip to content

Commit

Permalink
Allow whitespace control on comments
Browse files Browse the repository at this point in the history
This changes the call signature for the CommentNode constructor, which is a potentially breaking change for AST users.

Fixes #866
  • Loading branch information
kpdecker committed Nov 2, 2014
1 parent 9fbf7aa commit f30b3ea
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 12 deletions.
7 changes: 3 additions & 4 deletions lib/handlebars/compiler/ast.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,14 +196,13 @@ var AST = {
this.stringModeValue = bool === "true";
},

CommentNode: function(comment, locInfo) {
CommentNode: function(comment, strip, locInfo) {
LocationInfo.call(this, locInfo);
this.type = "comment";
this.comment = comment;

this.strip = {
inlineStandalone: true
};
this.strip = strip;
strip.inlineStandalone = true;
}
};

Expand Down
5 changes: 5 additions & 0 deletions lib/handlebars/compiler/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ export function stripFlags(open, close) {
};
}

export function stripComment(comment) {
return comment.replace(/^\{\{~?\!-?-?/, '')
.replace(/-?-?~?\}\}$/, '');
}


export function prepareBlock(mustache, program, inverseAndProgram, close, inverted, locInfo) {
/*jshint -W040 */
Expand Down
2 changes: 1 addition & 1 deletion spec/ast.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ describe('ast', function() {
describe("CommentNode", function(){

it('stores location info', function(){
var comment = new handlebarsEnv.AST.CommentNode("HI", LOCATION_INFO);
var comment = new handlebarsEnv.AST.CommentNode("HI", {}, LOCATION_INFO);
testLocationInfoStorage(comment);
});
});
Expand Down
3 changes: 3 additions & 0 deletions spec/basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ describe("basic context", function() {
shouldCompileTo("{{! Goodbye}}Goodbye\n{{cruel}}\n{{world}}!",
{cruel: "cruel", world: "world"}, "Goodbye\ncruel\nworld!",
"comments are ignored");

shouldCompileTo(' {{~! comment ~}} blah', {}, 'blah');
shouldCompileTo(' {{~!-- long-comment --~}} blah', {}, 'blah');
});

it("boolean", function() {
Expand Down
6 changes: 3 additions & 3 deletions spec/tokenizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,19 +217,19 @@ describe('Tokenizer', function() {
it('tokenizes a comment as "COMMENT"', function() {
var result = tokenize("foo {{! this is a comment }} bar {{ baz }}");
shouldMatchTokens(result, ['CONTENT', 'COMMENT', 'CONTENT', 'OPEN', 'ID', 'CLOSE']);
shouldBeToken(result[1], "COMMENT", " this is a comment ");
shouldBeToken(result[1], "COMMENT", "{{! this is a comment }}");
});

it('tokenizes a block comment as "COMMENT"', function() {
var result = tokenize("foo {{!-- this is a {{comment}} --}} bar {{ baz }}");
shouldMatchTokens(result, ['CONTENT', 'COMMENT', 'CONTENT', 'OPEN', 'ID', 'CLOSE']);
shouldBeToken(result[1], "COMMENT", " this is a {{comment}} ");
shouldBeToken(result[1], "COMMENT", "{{!-- this is a {{comment}} --}}");
});

it('tokenizes a block comment with whitespace as "COMMENT"', function() {
var result = tokenize("foo {{!-- this is a\n{{comment}}\n--}} bar {{ baz }}");
shouldMatchTokens(result, ['CONTENT', 'COMMENT', 'CONTENT', 'OPEN', 'ID', 'CLOSE']);
shouldBeToken(result[1], "COMMENT", " this is a\n{{comment}}\n");
shouldBeToken(result[1], "COMMENT", "{{!-- this is a\n{{comment}}\n--}}");
});

it('tokenizes open and closing blocks as OPEN_BLOCK, ID, CLOSE ..., OPEN_ENDBLOCK ID CLOSE', function() {
Expand Down
16 changes: 13 additions & 3 deletions src/handlebars.l
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ ID [^\s!"#%-,\.\/;->@\[-\^`\{-~]+/{LOOKAHEAD}
}
<raw>[^\x00]*?/("{{{{/") { return 'CONTENT'; }

<com>[\s\S]*?"--}}" strip(0,4); this.popState(); return 'COMMENT';
<com>[\s\S]*?"--"{RIGHT_STRIP}?"}}" {
this.popState();
return 'COMMENT';
}

<mu>"(" return 'OPEN_SEXPR';
<mu>")" return 'CLOSE_SEXPR';
Expand All @@ -76,8 +79,15 @@ ID [^\s!"#%-,\.\/;->@\[-\^`\{-~]+/{LOOKAHEAD}
<mu>"{{"{LEFT_STRIP}?\s*"else" return 'OPEN_INVERSE';
<mu>"{{"{LEFT_STRIP}?"{" return 'OPEN_UNESCAPED';
<mu>"{{"{LEFT_STRIP}?"&" return 'OPEN';
<mu>"{{!--" this.popState(); this.begin('com');
<mu>"{{!"[\s\S]*?"}}" strip(3,5); this.popState(); return 'COMMENT';
<mu>"{{"{LEFT_STRIP}?"!--" {
this.unput(yytext);
this.popState();
this.begin('com');
}
<mu>"{{"{LEFT_STRIP}?"!"[\s\S]*?"}}" {
this.popState();
return 'COMMENT';
}
<mu>"{{"{LEFT_STRIP}? return 'OPEN';

<mu>"=" return 'EQUALS';
Expand Down
2 changes: 1 addition & 1 deletion src/handlebars.yy
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ statement
| rawBlock -> $1
| partial -> $1
| CONTENT -> new yy.ContentNode($1, @$)
| COMMENT -> new yy.CommentNode($1, @$)
| COMMENT -> new yy.CommentNode(yy.stripComment($1), yy.stripFlags($1, $1), @$)
;

rawBlock
Expand Down

0 comments on commit f30b3ea

Please sign in to comment.