Skip to content

Commit f30b3ea

Browse files
committed
Allow whitespace control on comments
This changes the call signature for the CommentNode constructor, which is a potentially breaking change for AST users. Fixes #866
1 parent 9fbf7aa commit f30b3ea

7 files changed

Lines changed: 29 additions & 12 deletions

File tree

lib/handlebars/compiler/ast.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,14 +196,13 @@ var AST = {
196196
this.stringModeValue = bool === "true";
197197
},
198198

199-
CommentNode: function(comment, locInfo) {
199+
CommentNode: function(comment, strip, locInfo) {
200200
LocationInfo.call(this, locInfo);
201201
this.type = "comment";
202202
this.comment = comment;
203203

204-
this.strip = {
205-
inlineStandalone: true
206-
};
204+
this.strip = strip;
205+
strip.inlineStandalone = true;
207206
}
208207
};
209208

lib/handlebars/compiler/helpers.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ export function stripFlags(open, close) {
77
};
88
}
99

10+
export function stripComment(comment) {
11+
return comment.replace(/^\{\{~?\!-?-?/, '')
12+
.replace(/-?-?~?\}\}$/, '');
13+
}
14+
1015

1116
export function prepareBlock(mustache, program, inverseAndProgram, close, inverted, locInfo) {
1217
/*jshint -W040 */

spec/ast.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ describe('ast', function() {
137137
describe("CommentNode", function(){
138138

139139
it('stores location info', function(){
140-
var comment = new handlebarsEnv.AST.CommentNode("HI", LOCATION_INFO);
140+
var comment = new handlebarsEnv.AST.CommentNode("HI", {}, LOCATION_INFO);
141141
testLocationInfoStorage(comment);
142142
});
143143
});

spec/basic.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ describe("basic context", function() {
3333
shouldCompileTo("{{! Goodbye}}Goodbye\n{{cruel}}\n{{world}}!",
3434
{cruel: "cruel", world: "world"}, "Goodbye\ncruel\nworld!",
3535
"comments are ignored");
36+
37+
shouldCompileTo(' {{~! comment ~}} blah', {}, 'blah');
38+
shouldCompileTo(' {{~!-- long-comment --~}} blah', {}, 'blah');
3639
});
3740

3841
it("boolean", function() {

spec/tokenizer.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,19 +217,19 @@ describe('Tokenizer', function() {
217217
it('tokenizes a comment as "COMMENT"', function() {
218218
var result = tokenize("foo {{! this is a comment }} bar {{ baz }}");
219219
shouldMatchTokens(result, ['CONTENT', 'COMMENT', 'CONTENT', 'OPEN', 'ID', 'CLOSE']);
220-
shouldBeToken(result[1], "COMMENT", " this is a comment ");
220+
shouldBeToken(result[1], "COMMENT", "{{! this is a comment }}");
221221
});
222222

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

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

235235
it('tokenizes open and closing blocks as OPEN_BLOCK, ID, CLOSE ..., OPEN_ENDBLOCK ID CLOSE', function() {

src/handlebars.l

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,10 @@ ID [^\s!"#%-,\.\/;->@\[-\^`\{-~]+/{LOOKAHEAD}
5656
}
5757
<raw>[^\x00]*?/("{{{{/") { return 'CONTENT'; }
5858

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

6164
<mu>"(" return 'OPEN_SEXPR';
6265
<mu>")" return 'CLOSE_SEXPR';
@@ -76,8 +79,15 @@ ID [^\s!"#%-,\.\/;->@\[-\^`\{-~]+/{LOOKAHEAD}
7679
<mu>"{{"{LEFT_STRIP}?\s*"else" return 'OPEN_INVERSE';
7780
<mu>"{{"{LEFT_STRIP}?"{" return 'OPEN_UNESCAPED';
7881
<mu>"{{"{LEFT_STRIP}?"&" return 'OPEN';
79-
<mu>"{{!--" this.popState(); this.begin('com');
80-
<mu>"{{!"[\s\S]*?"}}" strip(3,5); this.popState(); return 'COMMENT';
82+
<mu>"{{"{LEFT_STRIP}?"!--" {
83+
this.unput(yytext);
84+
this.popState();
85+
this.begin('com');
86+
}
87+
<mu>"{{"{LEFT_STRIP}?"!"[\s\S]*?"}}" {
88+
this.popState();
89+
return 'COMMENT';
90+
}
8191
<mu>"{{"{LEFT_STRIP}? return 'OPEN';
8292

8393
<mu>"=" return 'EQUALS';

src/handlebars.yy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ statement
1818
| rawBlock -> $1
1919
| partial -> $1
2020
| CONTENT -> new yy.ContentNode($1, @$)
21-
| COMMENT -> new yy.CommentNode($1, @$)
21+
| COMMENT -> new yy.CommentNode(yy.stripComment($1), yy.stripFlags($1, $1), @$)
2222
;
2323

2424
rawBlock

0 commit comments

Comments
 (0)