From 02574812eecb3a93efc672c34a8ea29f5ec42250 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 7 Feb 2018 09:11:28 -0500 Subject: [PATCH] error on unclosed comments and blocks with only whitespace --- src/parse/index.ts | 4 ++-- src/parse/state/mustache.ts | 9 ++++++++- src/parse/state/tag.ts | 2 +- .../samples/error-comment-unclosed/error.json | 6 +++--- .../error-each-blocks-keyed-whitespace/input.html | 14 +++++++------- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/parse/index.ts b/src/parse/index.ts index c81d2f61b0..91d7c3253d 100644 --- a/src/parse/index.ts +++ b/src/parse/index.ts @@ -112,14 +112,14 @@ export class Parser { throw new ParseError(message, this.template, index, this.filename); } - eat(str: string, required?: boolean) { + eat(str: string, required?: boolean, message?: string) { if (this.match(str)) { this.index += str.length; return true; } if (required) { - this.error(`Expected ${str}`); + this.error(message || `Expected ${str}`); } return false; diff --git a/src/parse/state/mustache.ts b/src/parse/state/mustache.ts index bd1db07460..20331368d8 100644 --- a/src/parse/state/mustache.ts +++ b/src/parse/state/mustache.ts @@ -5,6 +5,13 @@ import reservedNames from '../../utils/reservedNames'; import { Parser } from '../index'; import { Node } from '../../interfaces'; +function isEmpty(nodes: Node[]) { + if (!nodes || nodes.length > 1) return false; + if (nodes.length === 0) return true; + if (nodes.length > 1) return false; + return nodes[0].type === 'Text' && !/\S/.test(nodes[0].data); +} + function trimWhitespace(block: Node, trimBefore: boolean, trimAfter: boolean) { if (!block.children) return; // AwaitBlock @@ -74,7 +81,7 @@ export default function mustache(parser: Parser) { } // strip leading/trailing whitespace as necessary - if (block.children && !block.children.length) parser.error(`Empty block`, block.start); + if (isEmpty(block.children)) parser.error(`Empty block`, block.start); const charBefore = parser.template[block.start - 1]; const charAfter = parser.template[parser.index]; diff --git a/src/parse/state/tag.ts b/src/parse/state/tag.ts index a659dc6d3d..d5c5be04a7 100644 --- a/src/parse/state/tag.ts +++ b/src/parse/state/tag.ts @@ -71,7 +71,7 @@ export default function tag(parser: Parser) { if (parser.eat('!--')) { const data = parser.readUntil(/-->/); - parser.eat('-->'); + parser.eat('-->', true, 'comment was left open, expected -->'); parser.current().children.push({ start, diff --git a/test/parser/samples/error-comment-unclosed/error.json b/test/parser/samples/error-comment-unclosed/error.json index 2502a32735..f392e12fa1 100644 --- a/test/parser/samples/error-comment-unclosed/error.json +++ b/test/parser/samples/error-comment-unclosed/error.json @@ -1,8 +1,8 @@ { - "message": "comment was left open", + "message": "comment was left open, expected -->", "loc": { "line": 1, - "column": 0 + "column": 24 }, - "pos": 0 + "pos": 24 } diff --git a/test/parser/samples/error-each-blocks-keyed-whitespace/input.html b/test/parser/samples/error-each-blocks-keyed-whitespace/input.html index c801984a56..6984d4ae88 100644 --- a/test/parser/samples/error-each-blocks-keyed-whitespace/input.html +++ b/test/parser/samples/error-each-blocks-keyed-whitespace/input.html @@ -1,11 +1,11 @@ {{#each foos as foo @id}} {{/each}}