From ff67b137c4111100280d58c96c2c777318a7d89c Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 10 Feb 2018 11:46:23 -0500 Subject: [PATCH] empty blocks are a dev warning, not an error --- src/parse/state/mustache.ts | 9 --------- src/validate/html/index.ts | 11 +++++++++++ src/validate/index.ts | 5 +++-- .../parser/samples/error-each-blocks-empty/input.html | 1 - .../error-each-blocks-keyed-whitespace/error.json | 8 -------- .../error-each-blocks-keyed-whitespace/input.html | 11 ----------- .../samples/error-each-blocks-whitespace/error.json | 8 -------- .../samples/error-each-blocks-whitespace/input.html | 11 ----------- test/validator/index.js | 6 ++++-- .../validator/samples/empty-block-dev.solo/_config.js | 3 +++ .../validator/samples/empty-block-dev.solo/input.html | 3 +++ .../samples/empty-block-dev.solo/warnings.json} | 4 ++-- test/validator/samples/empty-block-prod/input.html | 3 +++ test/validator/samples/empty-block-prod/warnings.json | 1 + 14 files changed, 30 insertions(+), 54 deletions(-) delete mode 100644 test/parser/samples/error-each-blocks-empty/input.html delete mode 100644 test/parser/samples/error-each-blocks-keyed-whitespace/error.json delete mode 100644 test/parser/samples/error-each-blocks-keyed-whitespace/input.html delete mode 100644 test/parser/samples/error-each-blocks-whitespace/error.json delete mode 100644 test/parser/samples/error-each-blocks-whitespace/input.html create mode 100644 test/validator/samples/empty-block-dev.solo/_config.js create mode 100644 test/validator/samples/empty-block-dev.solo/input.html rename test/{parser/samples/error-each-blocks-empty/error.json => validator/samples/empty-block-dev.solo/warnings.json} (93%) create mode 100644 test/validator/samples/empty-block-prod/input.html create mode 100644 test/validator/samples/empty-block-prod/warnings.json diff --git a/src/parse/state/mustache.ts b/src/parse/state/mustache.ts index 20331368d8..6e44f7c15e 100644 --- a/src/parse/state/mustache.ts +++ b/src/parse/state/mustache.ts @@ -5,13 +5,6 @@ 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 @@ -81,8 +74,6 @@ export default function mustache(parser: Parser) { } // strip leading/trailing whitespace as necessary - if (isEmpty(block.children)) parser.error(`Empty block`, block.start); - const charBefore = parser.template[block.start - 1]; const charAfter = parser.template[parser.index]; const trimBefore = !charBefore || whitespace.test(charBefore); diff --git a/src/validate/html/index.ts b/src/validate/html/index.ts index b2a190696f..9ae50baca1 100644 --- a/src/validate/html/index.ts +++ b/src/validate/html/index.ts @@ -12,6 +12,13 @@ const meta = new Map([ [':Head', validateHead] ]); +function isEmptyBlock(node: Node) { + if (!/Block$/.test(node.type) || !node.children) return false; + if (node.children.length > 1) return false; + const child = node.children[0]; + return !child || (child.type === 'Text' && !/\S/.test(child.data)); +} + export default function validateHtml(validator: Validator, html: Node) { const refs = new Map(); const refCallees: Node[] = []; @@ -58,6 +65,10 @@ export default function validateHtml(validator: Validator, html: Node) { } } + if (validator.options.dev && isEmptyBlock(node)) { + validator.warn('Empty block', node.start); + } + if (node.children) { if (node.type === 'Element') elementStack.push(node); stack.push(node); diff --git a/src/validate/index.ts b/src/validate/index.ts index b57f2b0c2a..da603a437b 100644 --- a/src/validate/index.ts +++ b/src/validate/index.ts @@ -93,7 +93,7 @@ export default function validate( stylesheet: Stylesheet, options: CompileOptions ) { - const { onwarn, onerror, name, filename, store } = options; + const { onwarn, onerror, name, filename, store, dev } = options; try { if (name && !/^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(name)) { @@ -114,7 +114,8 @@ export default function validate( onwarn, name, filename, - store + store, + dev }); if (parsed.js) { diff --git a/test/parser/samples/error-each-blocks-empty/input.html b/test/parser/samples/error-each-blocks-empty/input.html deleted file mode 100644 index 00b4b07d5a..0000000000 --- a/test/parser/samples/error-each-blocks-empty/input.html +++ /dev/null @@ -1 +0,0 @@ -{{#each foos as foo}}{{/each}} diff --git a/test/parser/samples/error-each-blocks-keyed-whitespace/error.json b/test/parser/samples/error-each-blocks-keyed-whitespace/error.json deleted file mode 100644 index 6ecdc198bd..0000000000 --- a/test/parser/samples/error-each-blocks-keyed-whitespace/error.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "message": "Empty block", - "loc": { - "line": 1, - "column": 0 - }, - "pos": 0 -} diff --git a/test/parser/samples/error-each-blocks-keyed-whitespace/input.html b/test/parser/samples/error-each-blocks-keyed-whitespace/input.html deleted file mode 100644 index 6984d4ae88..0000000000 --- a/test/parser/samples/error-each-blocks-keyed-whitespace/input.html +++ /dev/null @@ -1,11 +0,0 @@ -{{#each foos as foo @id}} -{{/each}} - diff --git a/test/parser/samples/error-each-blocks-whitespace/error.json b/test/parser/samples/error-each-blocks-whitespace/error.json deleted file mode 100644 index 6ecdc198bd..0000000000 --- a/test/parser/samples/error-each-blocks-whitespace/error.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "message": "Empty block", - "loc": { - "line": 1, - "column": 0 - }, - "pos": 0 -} diff --git a/test/parser/samples/error-each-blocks-whitespace/input.html b/test/parser/samples/error-each-blocks-whitespace/input.html deleted file mode 100644 index 2b4af0cac6..0000000000 --- a/test/parser/samples/error-each-blocks-whitespace/input.html +++ /dev/null @@ -1,11 +0,0 @@ -{{#each foos as foo}} -{{/each}} - diff --git a/test/validator/index.js b/test/validator/index.js index 176d060faf..0a132a7c9e 100644 --- a/test/validator/index.js +++ b/test/validator/index.js @@ -1,6 +1,6 @@ import * as fs from "fs"; import assert from "assert"; -import { svelte, tryToLoadJson } from "../helpers.js"; +import { svelte, loadConfig, tryToLoadJson } from "../helpers.js"; describe("validate", () => { fs.readdirSync("test/validator/samples").forEach(dir => { @@ -15,6 +15,7 @@ describe("validate", () => { } (solo ? it.only : skip ? it.skip : it)(dir, () => { + const config = loadConfig(`./validator/samples/${dir}/_config.js`); const filename = `test/validator/samples/${dir}/input.html`; const input = fs.readFileSync(filename, "utf-8").replace(/\s+$/, ""); @@ -32,7 +33,8 @@ describe("validate", () => { pos: warning.pos, loc: warning.loc }); - } + }, + dev: config.dev }); assert.deepEqual(warnings, expectedWarnings); diff --git a/test/validator/samples/empty-block-dev.solo/_config.js b/test/validator/samples/empty-block-dev.solo/_config.js new file mode 100644 index 0000000000..e26996239d --- /dev/null +++ b/test/validator/samples/empty-block-dev.solo/_config.js @@ -0,0 +1,3 @@ +export default { + dev: true +}; \ No newline at end of file diff --git a/test/validator/samples/empty-block-dev.solo/input.html b/test/validator/samples/empty-block-dev.solo/input.html new file mode 100644 index 0000000000..53e2ca8333 --- /dev/null +++ b/test/validator/samples/empty-block-dev.solo/input.html @@ -0,0 +1,3 @@ +{{#each things as thing}} + +{{/each}} \ No newline at end of file diff --git a/test/parser/samples/error-each-blocks-empty/error.json b/test/validator/samples/empty-block-dev.solo/warnings.json similarity index 93% rename from test/parser/samples/error-each-blocks-empty/error.json rename to test/validator/samples/empty-block-dev.solo/warnings.json index 6ecdc198bd..6cbc567ada 100644 --- a/test/parser/samples/error-each-blocks-empty/error.json +++ b/test/validator/samples/empty-block-dev.solo/warnings.json @@ -1,8 +1,8 @@ -{ +[{ "message": "Empty block", "loc": { "line": 1, "column": 0 }, "pos": 0 -} +}] \ No newline at end of file diff --git a/test/validator/samples/empty-block-prod/input.html b/test/validator/samples/empty-block-prod/input.html new file mode 100644 index 0000000000..53e2ca8333 --- /dev/null +++ b/test/validator/samples/empty-block-prod/input.html @@ -0,0 +1,3 @@ +{{#each things as thing}} + +{{/each}} \ No newline at end of file diff --git a/test/validator/samples/empty-block-prod/warnings.json b/test/validator/samples/empty-block-prod/warnings.json new file mode 100644 index 0000000000..0637a088a0 --- /dev/null +++ b/test/validator/samples/empty-block-prod/warnings.json @@ -0,0 +1 @@ +[] \ No newline at end of file