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
This commit is contained in:
kpdecker
2014-11-02 11:55:52 -06:00
parent 9fbf7aa753
commit f30b3ea329
7 changed files with 29 additions and 12 deletions
+3 -4
View File
@@ -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;
}
};
+5
View File
@@ -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 */
+1 -1
View File
@@ -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);
});
});
+3
View File
@@ -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() {
+3 -3
View File
@@ -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() {
+13 -3
View File
@@ -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';
@@ -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';
+1 -1
View File
@@ -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