From c4ad36023cad01b7e9ce8191ae79d85bf6eb08be Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 25 Jun 2017 16:32:24 -0400 Subject: [PATCH 1/5] move whitespace logic out of parse and into preprocess --- src/generators/dom/preprocess.ts | 71 +++++++++++-------- src/generators/server-side-rendering/index.ts | 2 +- src/parse/index.ts | 37 ++-------- src/parse/state/tag.ts | 22 ------ src/parse/utils/stripWhitespace.ts | 52 ++++++++++++++ test/parser/index.js | 2 +- .../samples/whitespace-normal/input.html | 1 + .../samples/whitespace-normal/output.json | 68 ++++++++++++++++++ .../samples/whitespace-normal/_config.js | 14 ++++ .../samples/whitespace-normal/main.html | 1 + .../component-data-dynamic/_actual.html | 6 +- .../samples/component-data-empty/_actual.html | 4 +- .../component-data-static/_actual.html | 6 +- .../samples/component-yield/_actual.html | 4 +- .../samples/component/_actual.html | 4 +- 15 files changed, 199 insertions(+), 95 deletions(-) create mode 100644 src/parse/utils/stripWhitespace.ts create mode 100644 test/parser/samples/whitespace-normal/input.html create mode 100644 test/parser/samples/whitespace-normal/output.json create mode 100644 test/runtime/samples/whitespace-normal/_config.js create mode 100644 test/runtime/samples/whitespace-normal/main.html diff --git a/src/generators/dom/preprocess.ts b/src/generators/dom/preprocess.ts index dc3ff59717..2fab6d45d6 100644 --- a/src/generators/dom/preprocess.ts +++ b/src/generators/dom/preprocess.ts @@ -34,7 +34,8 @@ const preprocessors = { generator: DomGenerator, block: Block, state: State, - node: Node + node: Node, + stripWhitespace: boolean ) => { const dependencies = block.findDependencies(node.expression); block.addDependencies(dependencies); @@ -48,7 +49,8 @@ const preprocessors = { generator: DomGenerator, block: Block, state: State, - node: Node + node: Node, + stripWhitespace: boolean ) => { const dependencies = block.findDependencies(node.expression); block.addDependencies(dependencies); @@ -59,7 +61,7 @@ const preprocessors = { node._state = getChildState(state, { basename, name }); }, - Text: (generator: DomGenerator, block: Block, state: State, node: Node) => { + Text: (generator: DomGenerator, block: Block, state: State, node: Node, stripWhitespace: boolean) => { node._state = getChildState(state); if (!/\S/.test(node.data)) { @@ -75,7 +77,8 @@ const preprocessors = { generator: DomGenerator, block: Block, state: State, - node: Node + node: Node, + stripWhitespace: boolean ) => { const blocks: Block[] = []; let dynamic = false; @@ -93,7 +96,7 @@ const preprocessors = { node._state = getChildState(state); blocks.push(node._block); - preprocessChildren(generator, node._block, node._state, node); + preprocessChildren(generator, node._block, node._state, node, stripWhitespace); if (node._block.dependencies.size > 0) { dynamic = true; @@ -117,7 +120,8 @@ const preprocessors = { generator, node.else._block, node.else._state, - node.else + node.else, + stripWhitespace ); if (node.else._block.dependencies.size > 0) { @@ -142,7 +146,8 @@ const preprocessors = { generator: DomGenerator, block: Block, state: State, - node: Node + node: Node, + stripWhitespace: boolean ) => { const dependencies = block.findDependencies(node.expression); block.addDependencies(dependencies); @@ -189,7 +194,7 @@ const preprocessors = { }); generator.blocks.push(node._block); - preprocessChildren(generator, node._block, node._state, node); + preprocessChildren(generator, node._block, node._state, node, stripWhitespace); block.addDependencies(node._block.dependencies); node._block.hasUpdateMethod = node._block.dependencies.size > 0; @@ -205,7 +210,8 @@ const preprocessors = { generator, node.else._block, node.else._state, - node.else + node.else, + stripWhitespace ); node.else._block.hasUpdateMethod = node.else._block.dependencies.size > 0; } @@ -215,7 +221,8 @@ const preprocessors = { generator: DomGenerator, block: Block, state: State, - node: Node + node: Node, + stripWhitespace: boolean ) => { node.attributes.forEach((attribute: Node) => { if (attribute.type === 'Attribute' && attribute.value !== true) { @@ -305,11 +312,12 @@ const preprocessors = { }); generator.blocks.push(node._block); - preprocessChildren(generator, node._block, node._state, node); + preprocessChildren(generator, node._block, node._state, node, stripWhitespace); block.addDependencies(node._block.dependencies); node._block.hasUpdateMethod = node._block.dependencies.size > 0; } else { - preprocessChildren(generator, block, node._state, node); + if (node.name === 'pre' || node.name === 'textarea') stripWhitespace = false; + preprocessChildren(generator, block, node._state, node, stripWhitespace); } } }, @@ -320,7 +328,7 @@ function preprocessChildren( block: Block, state: State, node: Node, - isTopLevel: boolean = false + stripWhitespace: boolean ) { // glue text nodes together const cleaned: Node[] = []; @@ -333,32 +341,22 @@ function preprocessChildren( lastChild.data += child.data; lastChild.end = child.end; } else { - cleaned.push(child); + if (child.type === 'Text' && stripWhitespace && cleaned.length === 0) { + child.data = trimStart(child.data); + if (child.data) cleaned.push(child); + } else { + cleaned.push(child); + } } lastChild = child; }); - if (isTopLevel) { - // trim leading and trailing whitespace from the top level - const firstChild = cleaned[0]; - if (firstChild && firstChild.type === 'Text') { - firstChild.data = trimStart(firstChild.data); - if (!firstChild.data) cleaned.shift(); - } - - const lastChild = cleaned[cleaned.length - 1]; - if (lastChild && lastChild.type === 'Text') { - lastChild.data = trimEnd(lastChild.data); - if (!lastChild.data) cleaned.pop(); - } - } - lastChild = null; cleaned.forEach((child: Node) => { - const preprocess = preprocessors[child.type]; - if (preprocess) preprocess(generator, block, state, child); + const preprocessor = preprocessors[child.type]; + if (preprocessor) preprocessor(generator, block, state, child, stripWhitespace); if (lastChild) { lastChild.next = child; @@ -368,6 +366,17 @@ function preprocessChildren( lastChild = child; }); + if (lastChild) { + if (stripWhitespace && lastChild.type === 'Text') { + lastChild.data = trimEnd(lastChild.data); + if (!lastChild.data) { + cleaned.pop(); + lastChild = cleaned[cleaned.length - 1]; + lastChild.next = null; + } + } + } + if (lastChild) { lastChild.needsAnchor = !state.parentNode; } diff --git a/src/generators/server-side-rendering/index.ts b/src/generators/server-side-rendering/index.ts index 549a111f61..7b48c8f764 100644 --- a/src/generators/server-side-rendering/index.ts +++ b/src/generators/server-side-rendering/index.ts @@ -117,7 +117,7 @@ export default function ssr( } `} - return \`${generator.renderCode}\`; + return \`${generator.renderCode}\`.trim(); }; ${name}.renderCss = function () { diff --git a/src/parse/index.ts b/src/parse/index.ts index 9962e38209..f50da4b911 100644 --- a/src/parse/index.ts +++ b/src/parse/index.ts @@ -4,6 +4,7 @@ import { whitespace } from '../utils/patterns'; import { trimStart, trimEnd } from '../utils/trim'; import getCodeFrame from '../utils/getCodeFrame'; import hash from './utils/hash'; +import stripWhitespace from './utils/stripWhitespace'; import { Node, Parsed } from '../interfaces'; import CompileError from '../utils/CompileError'; @@ -77,39 +78,9 @@ export class Parser { } // trim unnecessary whitespace - while (this.html.children.length) { - const firstChild = this.html.children[0]; - this.html.start = firstChild.start; - - if (firstChild.type !== 'Text') break; - - const length = firstChild.data.length; - firstChild.data = trimStart(firstChild.data); - - if (firstChild.data === '') { - this.html.children.shift(); - } else { - this.html.start += length - firstChild.data.length; - break; - } - } - - while (this.html.children.length) { - const lastChild = this.html.children[this.html.children.length - 1]; - this.html.end = lastChild.end; - - if (lastChild.type !== 'Text') break; - - const length = lastChild.data.length; - lastChild.data = trimEnd(lastChild.data); - - if (lastChild.data === '') { - this.html.children.pop(); - } else { - this.html.end -= length - lastChild.data.length; - break; - } - } + // stripWhitespace(this.html.children); + // this.html.start = this.html.children[0] && this.html.children.start; + // this.html.end = this.html.children[this.html.children.length] && this.html.children[this.html.children.length].end; } current() { diff --git a/src/parse/state/tag.ts b/src/parse/state/tag.ts index b40e3ad3fa..6fee187dd9 100644 --- a/src/parse/state/tag.ts +++ b/src/parse/state/tag.ts @@ -62,23 +62,6 @@ const disallowedContents = new Map([ ['th', new Set(['td', 'th', 'tr'])], ]); -function stripWhitespace(element) { - if (element.children.length) { - const firstChild = element.children[0]; - const lastChild = element.children[element.children.length - 1]; - - if (firstChild.type === 'Text') { - firstChild.data = trimStart(firstChild.data); - if (!firstChild.data) element.children.shift(); - } - - if (lastChild.type === 'Text') { - lastChild.data = trimEnd(lastChild.data); - if (!lastChild.data) element.children.pop(); - } - } -} - export default function tag(parser: Parser) { const start = parser.index++; @@ -147,9 +130,6 @@ export default function tag(parser: Parser) { parent = parser.current(); } - // strip leading/trailing whitespace as necessary - stripWhitespace(parent); - parent.end = parser.index; parser.stack.pop(); @@ -158,8 +138,6 @@ export default function tag(parser: Parser) { // can this be a child of the parent element, or does it implicitly // close it, like `
  • one
  • two`? if (disallowedContents.get(parent.name).has(name)) { - stripWhitespace(parent); - parent.end = start; parser.stack.pop(); } diff --git a/src/parse/utils/stripWhitespace.ts b/src/parse/utils/stripWhitespace.ts new file mode 100644 index 0000000000..3b1402ce60 --- /dev/null +++ b/src/parse/utils/stripWhitespace.ts @@ -0,0 +1,52 @@ +import { trimStart, trimEnd } from '../../utils/trim'; +import { Node } from '../../interfaces'; + +export default function stripWhitespace(nodes: Node[]) { + while (nodes.length) { + const firstChild = nodes[0]; + + if (firstChild.type !== 'Text') break; + + const length = firstChild.data.length; + firstChild.data = trimStart(firstChild.data); + + if (firstChild.data === '') { + nodes.shift(); + } else { + break; + } + } + + while (nodes.length) { + const lastChild = nodes[nodes.length - 1]; + + if (lastChild.type !== 'Text') break; + + const length = lastChild.data.length; + lastChild.data = trimEnd(lastChild.data); + + if (lastChild.data === '') { + nodes.pop(); + } else { + break; + } + } +} + + +// function stripWhitespace(element) { +// if (element.children.length) { +// const firstChild = element.children[0]; +// const lastChild = element.children[element.children.length - 1]; + +// if (firstChild.type === 'Text') { +// firstChild.data = trimStart(firstChild.data); +// if (!firstChild.data) element.children.shift(); +// } + +// if (lastChild.type === 'Text') { +// lastChild.data = trimEnd(lastChild.data); +// if (!lastChild.data) element.children.pop(); +// } +// } +// } \ No newline at end of file diff --git a/test/parser/index.js b/test/parser/index.js index 6bdd1b6376..76ef8a7b19 100644 --- a/test/parser/index.js +++ b/test/parser/index.js @@ -2,7 +2,7 @@ import assert from 'assert'; import fs from 'fs'; import { svelte } from '../helpers.js'; -describe('parse', () => { +describe.skip('parse', () => { fs.readdirSync('test/parser/samples').forEach(dir => { if (dir[0] === '.') return; diff --git a/test/parser/samples/whitespace-normal/input.html b/test/parser/samples/whitespace-normal/input.html new file mode 100644 index 0000000000..372184ebf3 --- /dev/null +++ b/test/parser/samples/whitespace-normal/input.html @@ -0,0 +1 @@ +

    Hello {{name}}! How are you?

    diff --git a/test/parser/samples/whitespace-normal/output.json b/test/parser/samples/whitespace-normal/output.json new file mode 100644 index 0000000000..5b609c8e36 --- /dev/null +++ b/test/parser/samples/whitespace-normal/output.json @@ -0,0 +1,68 @@ +{ + "hash": 2961389466, + "html": { + "start": 0, + "end": 67, + "type": "Fragment", + "children": [ + { + "start": 0, + "end": 67, + "type": "Element", + "name": "h1", + "attributes": [], + "children": [ + { + "start": 4, + "end": 10, + "type": "Text", + "data": "Hello " + }, + { + "start": 10, + "end": 37, + "type": "Element", + "name": "strong", + "attributes": [], + "children": [ + { + "start": 18, + "end": 26, + "type": "MustacheTag", + "expression": { + "type": "Identifier", + "start": 20, + "end": 24, + "name": "name" + } + }, + { + "start": 26, + "end": 28, + "type": "Text", + "data": "! " + } + ] + }, + { + "start": 37, + "end": 62, + "type": "Element", + "name": "span", + "attributes": [], + "children": [ + { + "start": 43, + "end": 55, + "type": "Text", + "data": "How are you?" + } + ] + } + ] + } + ] + }, + "css": null, + "js": null +} \ No newline at end of file diff --git a/test/runtime/samples/whitespace-normal/_config.js b/test/runtime/samples/whitespace-normal/_config.js new file mode 100644 index 0000000000..741d0654a1 --- /dev/null +++ b/test/runtime/samples/whitespace-normal/_config.js @@ -0,0 +1,14 @@ +export default { + data: { + name: 'world' + }, + + html: `

    Hello world! How are you?

    `, + + test ( assert, component, target ) { + assert.equal( + target.textContent, + `Hello world! How are you?` + ); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/whitespace-normal/main.html b/test/runtime/samples/whitespace-normal/main.html new file mode 100644 index 0000000000..372184ebf3 --- /dev/null +++ b/test/runtime/samples/whitespace-normal/main.html @@ -0,0 +1 @@ +

    Hello {{name}}! How are you?

    diff --git a/test/server-side-rendering/samples/component-data-dynamic/_actual.html b/test/server-side-rendering/samples/component-data-dynamic/_actual.html index d27b63e162..e8984936d9 100644 --- a/test/server-side-rendering/samples/component-data-dynamic/_actual.html +++ b/test/server-side-rendering/samples/component-data-dynamic/_actual.html @@ -1,4 +1,6 @@ -

    foo: lol

    +
    +

    foo: lol

    baz: 42 (number)

    qux: this is a piece of string

    -

    quux: core

    \ No newline at end of file +

    quux: core

    +
    \ No newline at end of file diff --git a/test/server-side-rendering/samples/component-data-empty/_actual.html b/test/server-side-rendering/samples/component-data-empty/_actual.html index dab5ab5387..85fe1fe733 100644 --- a/test/server-side-rendering/samples/component-data-empty/_actual.html +++ b/test/server-side-rendering/samples/component-data-empty/_actual.html @@ -1 +1,3 @@ -

    foo: ''

    \ No newline at end of file +
    +

    foo: ''

    +
    \ No newline at end of file diff --git a/test/server-side-rendering/samples/component-data-static/_actual.html b/test/server-side-rendering/samples/component-data-static/_actual.html index 442c858e4d..93f7e1839a 100644 --- a/test/server-side-rendering/samples/component-data-static/_actual.html +++ b/test/server-side-rendering/samples/component-data-static/_actual.html @@ -1,2 +1,4 @@ -

    foo: bar

    -

    baz: 42 (number)

    \ No newline at end of file +
    +

    foo: bar

    +

    baz: 42 (number)

    +
    \ No newline at end of file diff --git a/test/server-side-rendering/samples/component-yield/_actual.html b/test/server-side-rendering/samples/component-yield/_actual.html index 3c0acf1a81..49139417a2 100644 --- a/test/server-side-rendering/samples/component-yield/_actual.html +++ b/test/server-side-rendering/samples/component-yield/_actual.html @@ -1 +1,3 @@ -

    Hello

    \ No newline at end of file +
    +

    Hello

    +
    \ No newline at end of file diff --git a/test/server-side-rendering/samples/component/_actual.html b/test/server-side-rendering/samples/component/_actual.html index 715d1a85c3..88145945c3 100644 --- a/test/server-side-rendering/samples/component/_actual.html +++ b/test/server-side-rendering/samples/component/_actual.html @@ -1 +1,3 @@ -

    i am a widget

    \ No newline at end of file +
    +

    i am a widget

    +
    \ No newline at end of file From 9488bb9dbf410816328eddccdd28cebd08ec1837 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 25 Jun 2017 17:03:06 -0400 Subject: [PATCH 2/5] only remove whitespace at end of range if safe to do so --- src/generators/dom/preprocess.ts | 38 +++++++++++++++++++------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/generators/dom/preprocess.ts b/src/generators/dom/preprocess.ts index 2fab6d45d6..50e6620e11 100644 --- a/src/generators/dom/preprocess.ts +++ b/src/generators/dom/preprocess.ts @@ -78,7 +78,8 @@ const preprocessors = { block: Block, state: State, node: Node, - stripWhitespace: boolean + stripWhitespace: boolean, + nextSibling: Node ) => { const blocks: Block[] = []; let dynamic = false; @@ -96,7 +97,7 @@ const preprocessors = { node._state = getChildState(state); blocks.push(node._block); - preprocessChildren(generator, node._block, node._state, node, stripWhitespace); + preprocessChildren(generator, node._block, node._state, node, stripWhitespace, node); if (node._block.dependencies.size > 0) { dynamic = true; @@ -121,7 +122,8 @@ const preprocessors = { node.else._block, node.else._state, node.else, - stripWhitespace + stripWhitespace, + nextSibling ); if (node.else._block.dependencies.size > 0) { @@ -147,7 +149,8 @@ const preprocessors = { block: Block, state: State, node: Node, - stripWhitespace: boolean + stripWhitespace: boolean, + nextSibling: Node ) => { const dependencies = block.findDependencies(node.expression); block.addDependencies(dependencies); @@ -194,7 +197,7 @@ const preprocessors = { }); generator.blocks.push(node._block); - preprocessChildren(generator, node._block, node._state, node, stripWhitespace); + preprocessChildren(generator, node._block, node._state, node, stripWhitespace, nextSibling); block.addDependencies(node._block.dependencies); node._block.hasUpdateMethod = node._block.dependencies.size > 0; @@ -211,7 +214,8 @@ const preprocessors = { node.else._block, node.else._state, node.else, - stripWhitespace + stripWhitespace, + nextSibling ); node.else._block.hasUpdateMethod = node.else._block.dependencies.size > 0; } @@ -222,7 +226,8 @@ const preprocessors = { block: Block, state: State, node: Node, - stripWhitespace: boolean + stripWhitespace: boolean, + nextSibling: Node ) => { node.attributes.forEach((attribute: Node) => { if (attribute.type === 'Attribute' && attribute.value !== true) { @@ -312,12 +317,12 @@ const preprocessors = { }); generator.blocks.push(node._block); - preprocessChildren(generator, node._block, node._state, node, stripWhitespace); + preprocessChildren(generator, node._block, node._state, node, stripWhitespace, nextSibling); block.addDependencies(node._block.dependencies); node._block.hasUpdateMethod = node._block.dependencies.size > 0; } else { if (node.name === 'pre' || node.name === 'textarea') stripWhitespace = false; - preprocessChildren(generator, block, node._state, node, stripWhitespace); + preprocessChildren(generator, block, node._state, node, stripWhitespace, nextSibling); } } }, @@ -328,7 +333,8 @@ function preprocessChildren( block: Block, state: State, node: Node, - stripWhitespace: boolean + stripWhitespace: boolean, + nextSibling: Node ) { // glue text nodes together const cleaned: Node[] = []; @@ -354,9 +360,9 @@ function preprocessChildren( lastChild = null; - cleaned.forEach((child: Node) => { + cleaned.forEach((child: Node, i: number) => { const preprocessor = preprocessors[child.type]; - if (preprocessor) preprocessor(generator, block, state, child, stripWhitespace); + if (preprocessor) preprocessor(generator, block, state, child, stripWhitespace, cleaned[i + 1] || nextSibling); if (lastChild) { lastChild.next = child; @@ -366,8 +372,10 @@ function preprocessChildren( lastChild = child; }); - if (lastChild) { - if (stripWhitespace && lastChild.type === 'Text') { + // We want to remove trailing whitespace inside an element/component/block, + // *unless* there is no whitespace between this node and its next sibling + if (lastChild && lastChild.type === 'Text') { + if (stripWhitespace && (!nextSibling || (nextSibling.type === 'Text' && /^\s/.test(nextSibling.data)))) { lastChild.data = trimEnd(lastChild.data); if (!lastChild.data) { cleaned.pop(); @@ -413,7 +421,7 @@ export default function preprocess( }; generator.blocks.push(block); - preprocessChildren(generator, block, state, node, true); + preprocessChildren(generator, block, state, node, true, null); block.hasUpdateMethod = block.dependencies.size > 0; return { block, state }; From df1870df8b354923c5a990c5cac6bc27ee762289 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 25 Jun 2017 17:03:32 -0400 Subject: [PATCH 3/5] update tests --- test/js/samples/use-elements-as-anchors/expected-bundle.js | 6 ++---- test/js/samples/use-elements-as-anchors/expected.js | 6 ++---- test/runtime/samples/whitespace-normal/_config.js | 2 -- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/test/js/samples/use-elements-as-anchors/expected-bundle.js b/test/js/samples/use-elements-as-anchors/expected-bundle.js index 16764bf2cf..4037f07e34 100644 --- a/test/js/samples/use-elements-as-anchors/expected-bundle.js +++ b/test/js/samples/use-elements-as-anchors/expected-bundle.js @@ -136,7 +136,7 @@ var proto = { }; function create_main_fragment ( state, component ) { - var div, text, p, text_1, text_2, text_3, text_4, p_1, text_5, text_6, text_7, text_8, if_block_4_anchor; + var div, text, p, text_1, text_2, text_3, text_4, p_1, text_5, text_6, text_8, if_block_4_anchor; var if_block = (state.a) && create_if_block( state, component ); @@ -164,7 +164,6 @@ function create_main_fragment ( state, component ) { text_5 = createText( "so can this" ); text_6 = createText( "\n\n\t" ); if ( if_block_3 ) if_block_3.create(); - text_7 = createText( "\n\n\t" ); text_8 = createText( "\n\n" ); if ( if_block_4 ) if_block_4.create(); if_block_4_anchor = createComment(); @@ -185,7 +184,6 @@ function create_main_fragment ( state, component ) { appendNode( text_5, p_1 ); appendNode( text_6, div ); if ( if_block_3 ) if_block_3.mount( div, null ); - appendNode( text_7, div ); insertNode( text_8, target, anchor ); if ( if_block_4 ) if_block_4.mount( target, anchor ); insertNode( if_block_4_anchor, target, anchor ); @@ -232,7 +230,7 @@ function create_main_fragment ( state, component ) { if ( !if_block_3 ) { if_block_3 = create_if_block_3( state, component ); if_block_3.create(); - if_block_3.mount( div, text_7 ); + if_block_3.mount( div, null ); } } else if ( if_block_3 ) { if_block_3.unmount(); diff --git a/test/js/samples/use-elements-as-anchors/expected.js b/test/js/samples/use-elements-as-anchors/expected.js index df05566744..524372861e 100644 --- a/test/js/samples/use-elements-as-anchors/expected.js +++ b/test/js/samples/use-elements-as-anchors/expected.js @@ -1,7 +1,7 @@ import { appendNode, assign, createComment, createElement, createText, detachNode, dispatchObservers, insertNode, noop, proto } from "svelte/shared.js"; function create_main_fragment ( state, component ) { - var div, text, p, text_1, text_2, text_3, text_4, p_1, text_5, text_6, text_7, text_8, if_block_4_anchor; + var div, text, p, text_1, text_2, text_3, text_4, p_1, text_5, text_6, text_8, if_block_4_anchor; var if_block = (state.a) && create_if_block( state, component ); @@ -29,7 +29,6 @@ function create_main_fragment ( state, component ) { text_5 = createText( "so can this" ); text_6 = createText( "\n\n\t" ); if ( if_block_3 ) if_block_3.create(); - text_7 = createText( "\n\n\t" ); text_8 = createText( "\n\n" ); if ( if_block_4 ) if_block_4.create(); if_block_4_anchor = createComment(); @@ -50,7 +49,6 @@ function create_main_fragment ( state, component ) { appendNode( text_5, p_1 ); appendNode( text_6, div ); if ( if_block_3 ) if_block_3.mount( div, null ); - appendNode( text_7, div ); insertNode( text_8, target, anchor ); if ( if_block_4 ) if_block_4.mount( target, anchor ); insertNode( if_block_4_anchor, target, anchor ); @@ -97,7 +95,7 @@ function create_main_fragment ( state, component ) { if ( !if_block_3 ) { if_block_3 = create_if_block_3( state, component ); if_block_3.create(); - if_block_3.mount( div, text_7 ); + if_block_3.mount( div, null ); } } else if ( if_block_3 ) { if_block_3.unmount(); diff --git a/test/runtime/samples/whitespace-normal/_config.js b/test/runtime/samples/whitespace-normal/_config.js index 741d0654a1..a196aa2236 100644 --- a/test/runtime/samples/whitespace-normal/_config.js +++ b/test/runtime/samples/whitespace-normal/_config.js @@ -3,8 +3,6 @@ export default { name: 'world' }, - html: `

    Hello world! How are you?

    `, - test ( assert, component, target ) { assert.equal( target.textContent, From c98e1f49d357c43bbc3d3d08753c1022c72842db Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 25 Jun 2017 17:15:52 -0400 Subject: [PATCH 4/5] update parser tests --- src/parse/index.ts | 16 +++-- test/parser/index.js | 2 +- .../attribute-dynamic-boolean/output.json | 5 +- .../attribute-dynamic-reserved/output.json | 2 +- .../samples/attribute-dynamic/output.json | 7 +- .../samples/attribute-escaped/output.json | 3 +- .../samples/attribute-multiple/output.json | 3 +- .../samples/attribute-shorthand/output.json | 4 +- .../attribute-static-boolean/output.json | 3 +- .../samples/attribute-static/output.json | 3 +- .../samples/attribute-unquoted/output.json | 3 +- .../samples/binding-shorthand/output.json | 3 +- test/parser/samples/binding/output.json | 5 +- test/parser/samples/comment/output.json | 3 +- .../convert-entities-in-element/output.json | 3 +- .../samples/convert-entities/output.json | 3 +- test/parser/samples/css/output.json | 65 ++++++++++--------- .../samples/each-block-else/output.json | 33 +++++----- .../samples/each-block-indexed/output.json | 15 +++-- .../samples/each-block-keyed/output.json | 13 ++-- test/parser/samples/each-block/output.json | 11 ++-- .../samples/element-with-mustache/output.json | 5 +- .../samples/element-with-text/output.json | 3 +- test/parser/samples/elements/output.json | 49 +++++++------- test/parser/samples/event-handler/output.json | 39 +++++------ test/parser/samples/if-block-else/output.json | 5 +- .../samples/if-block-elseif/output.json | 19 +++--- test/parser/samples/if-block/output.json | 5 +- .../samples/implicitly-closed-li/output.json | 12 +++- test/parser/samples/nbsp/output.json | 2 +- test/parser/samples/raw-mustaches/output.json | 19 +++++- test/parser/samples/refs/output.json | 3 +- .../samples/script-comment-only/output.json | 9 ++- .../output.json | 65 ++++++++++--------- .../script-comment-trailing/output.json | 65 ++++++++++--------- test/parser/samples/script/output.json | 65 ++++++++++--------- .../samples/self-closing-element/output.json | 3 +- .../parser/samples/self-reference/output.json | 2 +- .../space-between-mustaches/output.json | 17 +++-- .../samples/textarea-children/output.json | 2 +- .../transition-intro-no-params/output.json | 2 +- .../samples/transition-intro/output.json | 16 ++--- .../whitespace-leading-trailing/output.json | 9 ++- test/parser/samples/yield/output.json | 29 +++++---- test/parser/update.js | 13 ++++ 45 files changed, 392 insertions(+), 271 deletions(-) create mode 100644 test/parser/update.js diff --git a/src/parse/index.ts b/src/parse/index.ts index f50da4b911..21a503d22a 100644 --- a/src/parse/index.ts +++ b/src/parse/index.ts @@ -77,10 +77,18 @@ export class Parser { this.error('Unexpected end of input'); } - // trim unnecessary whitespace - // stripWhitespace(this.html.children); - // this.html.start = this.html.children[0] && this.html.children.start; - // this.html.end = this.html.children[this.html.children.length] && this.html.children[this.html.children.length].end; + if (this.html.children.length) { + let start = this.html.children[0] && this.html.children[0].start; + while (/\s/.test(template[start])) start += 1; + + let end = this.html.children[this.html.children.length - 1] && this.html.children[this.html.children.length - 1].end; + while (/\s/.test(template[end - 1])) end -= 1; + + this.html.start = start; + this.html.end = end; + } else { + this.html.start = this.html.end = null; + } } current() { diff --git a/test/parser/index.js b/test/parser/index.js index 76ef8a7b19..6bdd1b6376 100644 --- a/test/parser/index.js +++ b/test/parser/index.js @@ -2,7 +2,7 @@ import assert from 'assert'; import fs from 'fs'; import { svelte } from '../helpers.js'; -describe.skip('parse', () => { +describe('parse', () => { fs.readdirSync('test/parser/samples').forEach(dir => { if (dir[0] === '.') return; diff --git a/test/parser/samples/attribute-dynamic-boolean/output.json b/test/parser/samples/attribute-dynamic-boolean/output.json index c4e1417c10..af1635a55d 100644 --- a/test/parser/samples/attribute-dynamic-boolean/output.json +++ b/test/parser/samples/attribute-dynamic-boolean/output.json @@ -1,4 +1,5 @@ { + "hash": 3179574701, "html": { "start": 0, "end": 45, @@ -21,9 +22,9 @@ "end": 32, "type": "MustacheTag", "expression": { + "type": "Identifier", "start": 22, "end": 30, - "type": "Identifier", "name": "readonly" } } @@ -36,4 +37,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/attribute-dynamic-reserved/output.json b/test/parser/samples/attribute-dynamic-reserved/output.json index a097655e2a..aef0e5cb63 100644 --- a/test/parser/samples/attribute-dynamic-reserved/output.json +++ b/test/parser/samples/attribute-dynamic-reserved/output.json @@ -1,5 +1,5 @@ { - "hash": 3305933215, + "hash": 2788845841, "html": { "start": 0, "end": 29, diff --git a/test/parser/samples/attribute-dynamic/output.json b/test/parser/samples/attribute-dynamic/output.json index 2f1cc44454..79ef81065f 100644 --- a/test/parser/samples/attribute-dynamic/output.json +++ b/test/parser/samples/attribute-dynamic/output.json @@ -1,4 +1,5 @@ { + "hash": 804348386, "html": { "start": 0, "end": 46, @@ -27,9 +28,9 @@ "end": 28, "type": "MustacheTag", "expression": { + "type": "Identifier", "start": 21, "end": 26, - "type": "Identifier", "name": "color" } }, @@ -48,9 +49,9 @@ "end": 40, "type": "MustacheTag", "expression": { + "type": "Identifier", "start": 33, "end": 38, - "type": "Identifier", "name": "color" } } @@ -60,4 +61,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/attribute-escaped/output.json b/test/parser/samples/attribute-escaped/output.json index 4dcc1f561b..974084bcdd 100644 --- a/test/parser/samples/attribute-escaped/output.json +++ b/test/parser/samples/attribute-escaped/output.json @@ -1,4 +1,5 @@ { + "hash": 1563956934, "html": { "start": 0, "end": 41, @@ -31,4 +32,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/attribute-multiple/output.json b/test/parser/samples/attribute-multiple/output.json index 30112ec629..81af977b51 100644 --- a/test/parser/samples/attribute-multiple/output.json +++ b/test/parser/samples/attribute-multiple/output.json @@ -1,4 +1,5 @@ { + "hash": 507039402, "html": { "start": 0, "end": 28, @@ -45,4 +46,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/attribute-shorthand/output.json b/test/parser/samples/attribute-shorthand/output.json index 979a8820ad..b6578c13eb 100644 --- a/test/parser/samples/attribute-shorthand/output.json +++ b/test/parser/samples/attribute-shorthand/output.json @@ -1,5 +1,5 @@ { - "hash": 4120363214, + "hash": 1705925892, "html": { "start": 0, "end": 10, @@ -18,9 +18,9 @@ "name": "id", "value": [ { + "type": "AttributeShorthand", "start": 6, "end": 8, - "type": "AttributeShorthand", "expression": { "type": "Identifier", "start": 6, diff --git a/test/parser/samples/attribute-static-boolean/output.json b/test/parser/samples/attribute-static-boolean/output.json index 5a7f79bee3..21429893fd 100644 --- a/test/parser/samples/attribute-static-boolean/output.json +++ b/test/parser/samples/attribute-static-boolean/output.json @@ -1,4 +1,5 @@ { + "hash": 606864228, "html": { "start": 0, "end": 30, @@ -24,4 +25,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/attribute-static/output.json b/test/parser/samples/attribute-static/output.json index 5cc13ffabf..394f95f458 100644 --- a/test/parser/samples/attribute-static/output.json +++ b/test/parser/samples/attribute-static/output.json @@ -1,4 +1,5 @@ { + "hash": 1493227373, "html": { "start": 0, "end": 23, @@ -31,4 +32,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/attribute-unquoted/output.json b/test/parser/samples/attribute-unquoted/output.json index c2a788b0a7..474d925b2e 100644 --- a/test/parser/samples/attribute-unquoted/output.json +++ b/test/parser/samples/attribute-unquoted/output.json @@ -1,4 +1,5 @@ { + "hash": 3488539025, "html": { "start": 0, "end": 21, @@ -31,4 +32,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/binding-shorthand/output.json b/test/parser/samples/binding-shorthand/output.json index ba22c66d33..8a7b615cf4 100644 --- a/test/parser/samples/binding-shorthand/output.json +++ b/test/parser/samples/binding-shorthand/output.json @@ -1,4 +1,5 @@ { + "hash": 3088875001, "html": { "start": 0, "end": 18, @@ -29,4 +30,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/binding/output.json b/test/parser/samples/binding/output.json index f307779950..74f2059f59 100644 --- a/test/parser/samples/binding/output.json +++ b/test/parser/samples/binding/output.json @@ -1,4 +1,5 @@ { + "hash": 1937205193, "html": { "start": 0, "end": 25, @@ -16,9 +17,9 @@ "type": "Binding", "name": "value", "value": { + "type": "Identifier", "start": 19, "end": 23, - "type": "Identifier", "name": "name" } } @@ -29,4 +30,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/comment/output.json b/test/parser/samples/comment/output.json index 635c0fc2e0..e77c968b6b 100644 --- a/test/parser/samples/comment/output.json +++ b/test/parser/samples/comment/output.json @@ -1,4 +1,5 @@ { + "hash": 3294612990, "html": { "start": 0, "end": 18, @@ -14,4 +15,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/convert-entities-in-element/output.json b/test/parser/samples/convert-entities-in-element/output.json index 4f39e826e7..cb3e50ec3b 100644 --- a/test/parser/samples/convert-entities-in-element/output.json +++ b/test/parser/samples/convert-entities-in-element/output.json @@ -1,4 +1,5 @@ { + "hash": 2365862121, "html": { "start": 0, "end": 24, @@ -23,4 +24,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/convert-entities/output.json b/test/parser/samples/convert-entities/output.json index f5124865c8..479bae3064 100644 --- a/test/parser/samples/convert-entities/output.json +++ b/test/parser/samples/convert-entities/output.json @@ -1,4 +1,5 @@ { + "hash": 156753432, "html": { "start": 0, "end": 17, @@ -14,4 +15,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/css/output.json b/test/parser/samples/css/output.json index 72c2a139db..4650ccea46 100644 --- a/test/parser/samples/css/output.json +++ b/test/parser/samples/css/output.json @@ -1,4 +1,5 @@ { + "hash": 1147407419, "html": { "start": 0, "end": 14, @@ -18,6 +19,12 @@ "data": "foo" } ] + }, + { + "start": 14, + "end": 16, + "type": "Text", + "data": "\n\n" } ] }, @@ -25,65 +32,65 @@ "start": 16, "end": 56, "attributes": [], - "content": { - "start": 23, - "end": 48, - "styles": "\n\tdiv {\n\t\tcolor: red;\n\t}\n" - }, "children": [ { "type": "Rule", - "start": 25, - "end": 47, "selector": { "type": "SelectorList", - "start": 25, - "end": 28, "children": [ { "type": "Selector", - "start": 25, - "end": 28, "children": [ { "type": "TypeSelector", + "name": "div", "start": 25, - "end": 28, - "name": "div" + "end": 28 } - ] + ], + "start": 25, + "end": 28 } - ] + ], + "start": 25, + "end": 28 }, "block": { "type": "Block", - "start": 29, - "end": 47, "children": [ { "type": "Declaration", - "start": 33, - "end": 43, "important": false, "property": "color", "value": { "type": "Value", - "start": 39, - "end": 43, "children": [ { "type": "Identifier", + "name": "red", "start": 40, - "end": 43, - "name": "red" + "end": 43 } - ] - } + ], + "start": 39, + "end": 43 + }, + "start": 33, + "end": 43 } - ] - } + ], + "start": 29, + "end": 47 + }, + "start": 25, + "end": 47 } - ] + ], + "content": { + "start": 23, + "end": 48, + "styles": "\n\tdiv {\n\t\tcolor: red;\n\t}\n" + } }, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/each-block-else/output.json b/test/parser/samples/each-block-else/output.json index 8d82d5a677..0dadad5f65 100644 --- a/test/parser/samples/each-block-else/output.json +++ b/test/parser/samples/each-block-else/output.json @@ -1,4 +1,5 @@ { + "hash": 3238289871, "html": { "start": 0, "end": 84, @@ -9,12 +10,11 @@ "end": 84, "type": "EachBlock", "expression": { + "type": "Identifier", "start": 8, "end": 15, - "type": "Identifier", "name": "animals" }, - "context": "animal", "children": [ { "start": 29, @@ -28,40 +28,41 @@ "end": 42, "type": "MustacheTag", "expression": { + "type": "Identifier", "start": 34, "end": 40, - "type": "Identifier", "name": "animal" } } ] } ], + "context": "animal", "else": { + "start": 55, + "end": 75, + "type": "ElseBlock", "children": [ { + "start": 57, + "end": 74, + "type": "Element", + "name": "p", "attributes": [], "children": [ { - "data": "no animals", - "end": 70, "start": 60, - "type": "Text" + "end": 70, + "type": "Text", + "data": "no animals" } - ], - "end": 74, - "name": "p", - "start": 57, - "type": "Element" + ] } - ], - "end": 75, - "start": 55, - "type": "ElseBlock" + ] } } ] }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/each-block-indexed/output.json b/test/parser/samples/each-block-indexed/output.json index 46c4ac34eb..fc8954d6ad 100644 --- a/test/parser/samples/each-block-indexed/output.json +++ b/test/parser/samples/each-block-indexed/output.json @@ -1,4 +1,5 @@ { + "hash": 2841674990, "html": { "start": 0, "end": 66, @@ -9,13 +10,11 @@ "end": 66, "type": "EachBlock", "expression": { + "type": "Identifier", "start": 8, "end": 15, - "type": "Identifier", "name": "animals" }, - "context": "animal", - "index": "i", "children": [ { "start": 32, @@ -29,9 +28,9 @@ "end": 40, "type": "MustacheTag", "expression": { + "type": "Identifier", "start": 37, "end": 38, - "type": "Identifier", "name": "i" } }, @@ -46,18 +45,20 @@ "end": 52, "type": "MustacheTag", "expression": { + "type": "Identifier", "start": 44, "end": 50, - "type": "Identifier", "name": "animal" } } ] } - ] + ], + "context": "animal", + "index": "i" } ] }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/each-block-keyed/output.json b/test/parser/samples/each-block-keyed/output.json index 3ace8016ec..1a16afb82b 100644 --- a/test/parser/samples/each-block-keyed/output.json +++ b/test/parser/samples/each-block-keyed/output.json @@ -1,4 +1,5 @@ { + "hash": 2025411181, "html": { "start": 0, "end": 54, @@ -9,13 +10,11 @@ "end": 54, "type": "EachBlock", "expression": { + "type": "Identifier", "start": 8, "end": 13, - "type": "Identifier", "name": "todos" }, - "context": "todo", - "key": "id", "children": [ { "start": 29, @@ -29,18 +28,20 @@ "end": 40, "type": "MustacheTag", "expression": { + "type": "Identifier", "start": 34, "end": 38, - "type": "Identifier", "name": "todo" } } ] } - ] + ], + "context": "todo", + "key": "id" } ] }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/each-block/output.json b/test/parser/samples/each-block/output.json index d0534c3206..e549faca39 100644 --- a/test/parser/samples/each-block/output.json +++ b/test/parser/samples/each-block/output.json @@ -1,4 +1,5 @@ { + "hash": 220340986, "html": { "start": 0, "end": 56, @@ -9,12 +10,11 @@ "end": 56, "type": "EachBlock", "expression": { + "type": "Identifier", "start": 8, "end": 15, - "type": "Identifier", "name": "animals" }, - "context": "animal", "children": [ { "start": 29, @@ -28,18 +28,19 @@ "end": 42, "type": "MustacheTag", "expression": { + "type": "Identifier", "start": 34, "end": 40, - "type": "Identifier", "name": "animal" } } ] } - ] + ], + "context": "animal" } ] }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/element-with-mustache/output.json b/test/parser/samples/element-with-mustache/output.json index 131b081edc..fd6799e192 100644 --- a/test/parser/samples/element-with-mustache/output.json +++ b/test/parser/samples/element-with-mustache/output.json @@ -1,4 +1,5 @@ { + "hash": 1265376132, "html": { "start": 0, "end": 24, @@ -22,9 +23,9 @@ "end": 18, "type": "MustacheTag", "expression": { + "type": "Identifier", "start": 12, "end": 16, - "type": "Identifier", "name": "name" } }, @@ -40,4 +41,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/element-with-text/output.json b/test/parser/samples/element-with-text/output.json index a93a083da1..22cae35547 100644 --- a/test/parser/samples/element-with-text/output.json +++ b/test/parser/samples/element-with-text/output.json @@ -1,4 +1,5 @@ { + "hash": 611274658, "html": { "start": 0, "end": 17, @@ -23,4 +24,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/elements/output.json b/test/parser/samples/elements/output.json index 79608f9132..7b4e6bffe1 100644 --- a/test/parser/samples/elements/output.json +++ b/test/parser/samples/elements/output.json @@ -1,23 +1,28 @@ { - "html": { - "start": 0, - "end": 15, - "type": "Fragment", - "children": [{ - "attributes": [{ - "end": 14, - "name": "html", - "start": 10, - "type": "Attribute", - "value": true - }], - "children": [], - "end": 15, - "name": "!doctype", - "start": 0, - "type": "Element" - }] - }, - "css": null, - "js": null -} + "hash": 825536165, + "html": { + "start": 0, + "end": 15, + "type": "Fragment", + "children": [ + { + "start": 0, + "end": 15, + "type": "Element", + "name": "!doctype", + "attributes": [ + { + "start": 10, + "end": 14, + "type": "Attribute", + "name": "html", + "value": true + } + ], + "children": [] + } + ] + }, + "css": null, + "js": null +} \ No newline at end of file diff --git a/test/parser/samples/event-handler/output.json b/test/parser/samples/event-handler/output.json index 1a1f27d3d9..2b5844bb1b 100644 --- a/test/parser/samples/event-handler/output.json +++ b/test/parser/samples/event-handler/output.json @@ -1,4 +1,5 @@ { + "hash": 4260626221, "html": { "start": 0, "end": 101, @@ -16,48 +17,48 @@ "type": "EventHandler", "name": "click", "expression": { + "type": "CallExpression", "start": 18, "end": 44, - "type": "CallExpression", "callee": { + "type": "Identifier", "start": 18, "end": 21, - "type": "Identifier", "name": "set" }, "arguments": [ { + "type": "ObjectExpression", "start": 22, "end": 43, - "type": "ObjectExpression", "properties": [ { + "type": "Property", "start": 24, "end": 41, - "type": "Property", - "kind": "init", - "computed": false, "method": false, "shorthand": false, + "computed": false, "key": { + "type": "Identifier", "start": 24, "end": 31, - "type": "Identifier", "name": "visible" }, "value": { + "type": "UnaryExpression", "start": 33, "end": 41, - "type": "UnaryExpression", "operator": "!", "prefix": true, "argument": { + "type": "Identifier", "start": 34, "end": 41, - "type": "Identifier", "name": "visible" } - } + }, + "kind": "init" } ] } @@ -67,10 +68,10 @@ ], "children": [ { - "data": "toggle", "start": 46, "end": 52, - "type": "Text" + "type": "Text", + "data": "toggle" } ] }, @@ -85,10 +86,10 @@ "end": 101, "type": "IfBlock", "expression": { - "end": 76, - "name": "visible", + "type": "Identifier", "start": 69, - "type": "Identifier" + "end": 76, + "name": "visible" }, "children": [ { @@ -99,10 +100,10 @@ "attributes": [], "children": [ { - "data": "hello!", - "end": 89, "start": 83, - "type": "Text" + "end": 89, + "type": "Text", + "data": "hello!" } ] } @@ -112,4 +113,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/if-block-else/output.json b/test/parser/samples/if-block-else/output.json index db3923559b..af2c611220 100644 --- a/test/parser/samples/if-block-else/output.json +++ b/test/parser/samples/if-block-else/output.json @@ -1,4 +1,5 @@ { + "hash": 3134964533, "html": { "start": 0, "end": 56, @@ -9,9 +10,9 @@ "end": 56, "type": "IfBlock", "expression": { + "type": "Identifier", "start": 6, "end": 9, - "type": "Identifier", "name": "foo" }, "children": [ @@ -58,4 +59,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/if-block-elseif/output.json b/test/parser/samples/if-block-elseif/output.json index 743758a970..a2d61f2464 100644 --- a/test/parser/samples/if-block-elseif/output.json +++ b/test/parser/samples/if-block-elseif/output.json @@ -1,4 +1,5 @@ { + "hash": 985817334, "html": { "start": 0, "end": 93, @@ -9,20 +10,20 @@ "end": 93, "type": "IfBlock", "expression": { + "type": "BinaryExpression", "start": 6, "end": 12, - "type": "BinaryExpression", - "operator": ">", "left": { + "type": "Identifier", "start": 6, "end": 7, - "type": "Identifier", "name": "x" }, + "operator": ">", "right": { + "type": "Literal", "start": 10, "end": 12, - "type": "Literal", "value": 10, "raw": "10" } @@ -55,20 +56,20 @@ "type": "IfBlock", "elseif": true, "expression": { + "type": "BinaryExpression", "start": 53, "end": 58, - "type": "BinaryExpression", - "operator": "<", "left": { + "type": "Identifier", "start": 53, "end": 54, - "type": "Identifier", "name": "x" }, + "operator": "<", "right": { + "type": "Literal", "start": 57, "end": 58, - "type": "Literal", "value": 5, "raw": "5" } @@ -98,4 +99,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/if-block/output.json b/test/parser/samples/if-block/output.json index e1019ba1d7..d523d41596 100644 --- a/test/parser/samples/if-block/output.json +++ b/test/parser/samples/if-block/output.json @@ -1,4 +1,5 @@ { + "hash": 2374871934, "html": { "start": 0, "end": 21, @@ -9,9 +10,9 @@ "end": 21, "type": "IfBlock", "expression": { + "type": "Identifier", "start": 6, "end": 9, - "type": "Identifier", "name": "foo" }, "children": [ @@ -27,4 +28,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/implicitly-closed-li/output.json b/test/parser/samples/implicitly-closed-li/output.json index 3263fa8e40..f2aca52f68 100644 --- a/test/parser/samples/implicitly-closed-li/output.json +++ b/test/parser/samples/implicitly-closed-li/output.json @@ -1,5 +1,5 @@ { - "hash": 3806276940, + "hash": 126082492, "html": { "start": 0, "end": 31, @@ -12,6 +12,12 @@ "name": "ul", "attributes": [], "children": [ + { + "start": 4, + "end": 6, + "type": "Text", + "data": "\n\t" + }, { "start": 6, "end": 13, @@ -23,7 +29,7 @@ "start": 10, "end": 13, "type": "Text", - "data": "a" + "data": "a\n\t" } ] }, @@ -38,7 +44,7 @@ "start": 17, "end": 20, "type": "Text", - "data": "b" + "data": "b\n\t" } ] }, diff --git a/test/parser/samples/nbsp/output.json b/test/parser/samples/nbsp/output.json index d8cbb594f6..8b7d487f16 100644 --- a/test/parser/samples/nbsp/output.json +++ b/test/parser/samples/nbsp/output.json @@ -1,5 +1,5 @@ { - "hash": 2678229240, + "hash": 4049070444, "html": { "start": 0, "end": 19, diff --git a/test/parser/samples/raw-mustaches/output.json b/test/parser/samples/raw-mustaches/output.json index 4acedf34ea..e4a1b91c6c 100644 --- a/test/parser/samples/raw-mustaches/output.json +++ b/test/parser/samples/raw-mustaches/output.json @@ -1,4 +1,5 @@ { + "hash": 183399343, "html": { "start": 0, "end": 30, @@ -11,14 +12,20 @@ "name": "p", "attributes": [], "children": [ + { + "start": 3, + "end": 4, + "type": "Text", + "data": " " + }, { "start": 4, "end": 14, "type": "RawMustacheTag", "expression": { + "type": "Identifier", "start": 7, "end": 11, - "type": "Identifier", "name": "raw1" } }, @@ -33,11 +40,17 @@ "end": 25, "type": "RawMustacheTag", "expression": { + "type": "Identifier", "start": 18, "end": 22, - "type": "Identifier", "name": "raw2" } + }, + { + "start": 25, + "end": 26, + "type": "Text", + "data": " " } ] } @@ -45,4 +58,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/refs/output.json b/test/parser/samples/refs/output.json index c158de0848..37761abaff 100644 --- a/test/parser/samples/refs/output.json +++ b/test/parser/samples/refs/output.json @@ -1,4 +1,5 @@ { + "hash": 850398275, "html": { "start": 0, "end": 25, @@ -23,4 +24,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/script-comment-only/output.json b/test/parser/samples/script-comment-only/output.json index 0e8e7877df..1dcc6fe1f4 100644 --- a/test/parser/samples/script-comment-only/output.json +++ b/test/parser/samples/script-comment-only/output.json @@ -1,4 +1,5 @@ { + "hash": 3451341610, "html": { "start": 0, "end": 11, @@ -11,9 +12,15 @@ "name": "div", "attributes": [], "children": [] + }, + { + "start": 11, + "end": 13, + "type": "Text", + "data": "\n\n" } ] }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/script-comment-trailing-multiline/output.json b/test/parser/samples/script-comment-trailing-multiline/output.json index f97eb78052..4319919ee5 100644 --- a/test/parser/samples/script-comment-trailing-multiline/output.json +++ b/test/parser/samples/script-comment-trailing-multiline/output.json @@ -1,4 +1,5 @@ { + "hash": 1378757574, "html": { "start": 0, "end": 24, @@ -22,9 +23,9 @@ "end": 18, "type": "MustacheTag", "expression": { + "type": "Identifier", "start": 12, "end": 16, - "type": "Identifier", "name": "name" } }, @@ -35,6 +36,12 @@ "data": "!" } ] + }, + { + "start": 24, + "end": 26, + "type": "Text", + "data": "\n\n" } ] }, @@ -49,73 +56,73 @@ "end": 134, "body": [ { + "type": "ExportDefaultDeclaration", + "start": 36, + "end": 95, "declaration": { + "type": "ObjectExpression", "start": 51, "end": 94, - "type": "ObjectExpression", "properties": [ { + "type": "Property", "start": 55, "end": 91, - "type": "Property", + "method": false, + "shorthand": false, "computed": false, "key": { + "type": "Identifier", "start": 55, "end": 59, - "type": "Identifier", "name": "data" }, - "kind": "init", - "method": false, - "shorthand": false, "value": { + "type": "ArrowFunctionExpression", "start": 61, "end": 91, - "type": "ArrowFunctionExpression", + "id": null, + "generator": false, + "expression": true, "async": false, + "params": [], "body": { + "type": "ObjectExpression", "start": 68, "end": 90, - "type": "ObjectExpression", "properties": [ { + "type": "Property", "start": 73, "end": 86, - "type": "Property", + "method": false, + "shorthand": false, "computed": false, "key": { + "type": "Identifier", "start": 73, "end": 77, - "type": "Identifier", "name": "name" }, - "kind": "init", - "method": false, - "shorthand": false, "value": { + "type": "Literal", "start": 79, "end": 86, - "type": "Literal", - "raw": "'world'", - "value": "world" - } + "value": "world", + "raw": "'world'" + }, + "kind": "init" } ] - }, - "expression": true, - "generator": false, - "id": null, - "params": [] - } + } + }, + "kind": "init" } ] - }, - "end": 95, - "start": 36, - "type": "ExportDefaultDeclaration" + } } ], "sourceType": "module" } } -} +} \ No newline at end of file diff --git a/test/parser/samples/script-comment-trailing/output.json b/test/parser/samples/script-comment-trailing/output.json index e531599fea..2977d6a7fa 100644 --- a/test/parser/samples/script-comment-trailing/output.json +++ b/test/parser/samples/script-comment-trailing/output.json @@ -1,4 +1,5 @@ { + "hash": 619854804, "html": { "start": 0, "end": 24, @@ -22,9 +23,9 @@ "end": 18, "type": "MustacheTag", "expression": { + "type": "Identifier", "start": 12, "end": 16, - "type": "Identifier", "name": "name" } }, @@ -35,6 +36,12 @@ "data": "!" } ] + }, + { + "start": 24, + "end": 26, + "type": "Text", + "data": "\n\n" } ] }, @@ -49,73 +56,73 @@ "end": 123, "body": [ { + "type": "ExportDefaultDeclaration", + "start": 36, + "end": 95, "declaration": { + "type": "ObjectExpression", "start": 51, "end": 94, - "type": "ObjectExpression", "properties": [ { + "type": "Property", "start": 55, "end": 91, - "type": "Property", + "method": false, + "shorthand": false, "computed": false, "key": { + "type": "Identifier", "start": 55, "end": 59, - "type": "Identifier", "name": "data" }, - "kind": "init", - "method": false, - "shorthand": false, "value": { + "type": "ArrowFunctionExpression", "start": 61, "end": 91, - "type": "ArrowFunctionExpression", + "id": null, + "generator": false, + "expression": true, "async": false, + "params": [], "body": { + "type": "ObjectExpression", "start": 68, "end": 90, - "type": "ObjectExpression", "properties": [ { + "type": "Property", "start": 73, "end": 86, - "type": "Property", + "method": false, + "shorthand": false, "computed": false, "key": { + "type": "Identifier", "start": 73, "end": 77, - "type": "Identifier", "name": "name" }, - "kind": "init", - "method": false, - "shorthand": false, "value": { + "type": "Literal", "start": 79, "end": 86, - "type": "Literal", - "raw": "'world'", - "value": "world" - } + "value": "world", + "raw": "'world'" + }, + "kind": "init" } ] - }, - "expression": true, - "generator": false, - "id": null, - "params": [] - } + } + }, + "kind": "init" } ] - }, - "end": 95, - "start": 36, - "type": "ExportDefaultDeclaration" + } } ], "sourceType": "module" } } -} +} \ No newline at end of file diff --git a/test/parser/samples/script/output.json b/test/parser/samples/script/output.json index a6af78759f..5c8acef657 100644 --- a/test/parser/samples/script/output.json +++ b/test/parser/samples/script/output.json @@ -1,4 +1,5 @@ { + "hash": 388108696, "html": { "start": 0, "end": 24, @@ -22,9 +23,9 @@ "end": 18, "type": "MustacheTag", "expression": { + "type": "Identifier", "start": 12, "end": 16, - "type": "Identifier", "name": "name" } }, @@ -35,6 +36,12 @@ "data": "!" } ] + }, + { + "start": 24, + "end": 26, + "type": "Text", + "data": "\n\n" } ] }, @@ -49,73 +56,73 @@ "end": 96, "body": [ { + "type": "ExportDefaultDeclaration", + "start": 36, + "end": 95, "declaration": { + "type": "ObjectExpression", "start": 51, "end": 94, - "type": "ObjectExpression", "properties": [ { + "type": "Property", "start": 55, "end": 91, - "type": "Property", + "method": false, + "shorthand": false, "computed": false, "key": { + "type": "Identifier", "start": 55, "end": 59, - "type": "Identifier", "name": "data" }, - "kind": "init", - "method": false, - "shorthand": false, "value": { + "type": "ArrowFunctionExpression", "start": 61, "end": 91, - "type": "ArrowFunctionExpression", + "id": null, + "generator": false, + "expression": true, "async": false, + "params": [], "body": { + "type": "ObjectExpression", "start": 68, "end": 90, - "type": "ObjectExpression", "properties": [ { + "type": "Property", "start": 73, "end": 86, - "type": "Property", + "method": false, + "shorthand": false, "computed": false, "key": { + "type": "Identifier", "start": 73, "end": 77, - "type": "Identifier", "name": "name" }, - "kind": "init", - "method": false, - "shorthand": false, "value": { + "type": "Literal", "start": 79, "end": 86, - "type": "Literal", - "raw": "'world'", - "value": "world" - } + "value": "world", + "raw": "'world'" + }, + "kind": "init" } ] - }, - "expression": true, - "generator": false, - "id": null, - "params": [] - } + } + }, + "kind": "init" } ] - }, - "end": 95, - "start": 36, - "type": "ExportDefaultDeclaration" + } } ], "sourceType": "module" } } -} +} \ No newline at end of file diff --git a/test/parser/samples/self-closing-element/output.json b/test/parser/samples/self-closing-element/output.json index 5cba18b6a0..80c1ef5bde 100644 --- a/test/parser/samples/self-closing-element/output.json +++ b/test/parser/samples/self-closing-element/output.json @@ -1,4 +1,5 @@ { + "hash": 4200201687, "html": { "start": 0, "end": 6, @@ -16,4 +17,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/self-reference/output.json b/test/parser/samples/self-reference/output.json index fd5c1543e4..f9c788bd2f 100644 --- a/test/parser/samples/self-reference/output.json +++ b/test/parser/samples/self-reference/output.json @@ -1,5 +1,5 @@ { - "hash": 1792372370, + "hash": 216762188, "html": { "start": 0, "end": 57, diff --git a/test/parser/samples/space-between-mustaches/output.json b/test/parser/samples/space-between-mustaches/output.json index 03a01a64c4..854608fb29 100644 --- a/test/parser/samples/space-between-mustaches/output.json +++ b/test/parser/samples/space-between-mustaches/output.json @@ -1,4 +1,5 @@ { + "hash": 1185019088, "html": { "start": 0, "end": 30, @@ -11,14 +12,20 @@ "name": "p", "attributes": [], "children": [ + { + "start": 3, + "end": 4, + "type": "Text", + "data": " " + }, { "start": 4, "end": 9, "type": "MustacheTag", "expression": { + "type": "Identifier", "start": 6, "end": 7, - "type": "Identifier", "name": "a" } }, @@ -33,9 +40,9 @@ "end": 15, "type": "MustacheTag", "expression": { + "type": "Identifier", "start": 12, "end": 13, - "type": "Identifier", "name": "b" } }, @@ -50,9 +57,9 @@ "end": 23, "type": "MustacheTag", "expression": { + "type": "Identifier", "start": 20, "end": 21, - "type": "Identifier", "name": "c" } }, @@ -60,7 +67,7 @@ "start": 23, "end": 26, "type": "Text", - "data": " :" + "data": " : " } ] } @@ -68,4 +75,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/textarea-children/output.json b/test/parser/samples/textarea-children/output.json index 4b67ac108a..d4ea6f04bb 100644 --- a/test/parser/samples/textarea-children/output.json +++ b/test/parser/samples/textarea-children/output.json @@ -1,5 +1,5 @@ { - "hash": 3618147195, + "hash": 2992234421, "html": { "start": 0, "end": 63, diff --git a/test/parser/samples/transition-intro-no-params/output.json b/test/parser/samples/transition-intro-no-params/output.json index ae1f76a3bc..cca469ca3e 100644 --- a/test/parser/samples/transition-intro-no-params/output.json +++ b/test/parser/samples/transition-intro-no-params/output.json @@ -1,5 +1,5 @@ { - "hash": 1535528483, + "hash": 503236647, "html": { "start": 0, "end": 27, diff --git a/test/parser/samples/transition-intro/output.json b/test/parser/samples/transition-intro/output.json index 3f73ef3ce1..54ec4da93d 100644 --- a/test/parser/samples/transition-intro/output.json +++ b/test/parser/samples/transition-intro/output.json @@ -1,5 +1,5 @@ { - "hash": 3160753914, + "hash": 3731674194, "html": { "start": 0, "end": 43, @@ -19,18 +19,17 @@ "intro": true, "outro": false, "expression": { - "start": 15, - "end": 27, "type": "ObjectExpression", + "start": 15, + "end": 27, "properties": [ { + "type": "Property", "start": 16, "end": 26, - "type": "Property", "method": false, - "computed": false, "shorthand": false, - "kind": "init", + "computed": false, "key": { "type": "Identifier", "start": 16, @@ -38,12 +37,13 @@ "name": "opacity" }, "value": { + "type": "Literal", "start": 25, "end": 26, - "type": "Literal", "value": 0, "raw": "0" - } + }, + "kind": "init" } ] } diff --git a/test/parser/samples/whitespace-leading-trailing/output.json b/test/parser/samples/whitespace-leading-trailing/output.json index 796829a365..c057bd1f1e 100644 --- a/test/parser/samples/whitespace-leading-trailing/output.json +++ b/test/parser/samples/whitespace-leading-trailing/output.json @@ -1,9 +1,16 @@ { + "hash": 424837432, "html": { "start": 6, "end": 36, "type": "Fragment", "children": [ + { + "start": 0, + "end": 6, + "type": "Text", + "data": "\n\n\t\t\t\t" + }, { "start": 6, "end": 36, @@ -23,4 +30,4 @@ }, "css": null, "js": null -} +} \ No newline at end of file diff --git a/test/parser/samples/yield/output.json b/test/parser/samples/yield/output.json index 227da6561f..2f98abe91f 100644 --- a/test/parser/samples/yield/output.json +++ b/test/parser/samples/yield/output.json @@ -1,14 +1,17 @@ { - "html": { - "start": 0, - "end": 9, - "type": "Fragment", - "children": [ - { - "start": 0, - "end": 9, - "type": "YieldTag" - } - ] - } -} + "hash": 3659433152, + "html": { + "start": 0, + "end": 9, + "type": "Fragment", + "children": [ + { + "start": 0, + "end": 9, + "type": "YieldTag" + } + ] + }, + "css": null, + "js": null +} \ No newline at end of file diff --git a/test/parser/update.js b/test/parser/update.js new file mode 100644 index 0000000000..7c8e89ab76 --- /dev/null +++ b/test/parser/update.js @@ -0,0 +1,13 @@ +// this file will replace all the expected.js and expected-bundle.js files with +// their _actual equivalents. Only use it when you're sure that you haven't +// broken anything! +const fs = require("fs"); +const glob = require("glob"); + +glob.sync("samples/*/_actual.json", { cwd: __dirname }).forEach(file => { + const actual = fs.readFileSync(`${__dirname}/${file}`, "utf-8"); + fs.writeFileSync( + `${__dirname}/${file.replace("_actual", "output")}`, + actual + ); +}); From 94166f60d83aff01a745b962f653bf51dab44183 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 25 Jun 2017 17:19:29 -0400 Subject: [PATCH 5/5] remove unused code --- src/parse/index.ts | 1 - src/parse/utils/stripWhitespace.ts | 52 ------------------------------ 2 files changed, 53 deletions(-) delete mode 100644 src/parse/utils/stripWhitespace.ts diff --git a/src/parse/index.ts b/src/parse/index.ts index 21a503d22a..514e074fd4 100644 --- a/src/parse/index.ts +++ b/src/parse/index.ts @@ -4,7 +4,6 @@ import { whitespace } from '../utils/patterns'; import { trimStart, trimEnd } from '../utils/trim'; import getCodeFrame from '../utils/getCodeFrame'; import hash from './utils/hash'; -import stripWhitespace from './utils/stripWhitespace'; import { Node, Parsed } from '../interfaces'; import CompileError from '../utils/CompileError'; diff --git a/src/parse/utils/stripWhitespace.ts b/src/parse/utils/stripWhitespace.ts deleted file mode 100644 index 3b1402ce60..0000000000 --- a/src/parse/utils/stripWhitespace.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { trimStart, trimEnd } from '../../utils/trim'; -import { Node } from '../../interfaces'; - -export default function stripWhitespace(nodes: Node[]) { - while (nodes.length) { - const firstChild = nodes[0]; - - if (firstChild.type !== 'Text') break; - - const length = firstChild.data.length; - firstChild.data = trimStart(firstChild.data); - - if (firstChild.data === '') { - nodes.shift(); - } else { - break; - } - } - - while (nodes.length) { - const lastChild = nodes[nodes.length - 1]; - - if (lastChild.type !== 'Text') break; - - const length = lastChild.data.length; - lastChild.data = trimEnd(lastChild.data); - - if (lastChild.data === '') { - nodes.pop(); - } else { - break; - } - } -} - - -// function stripWhitespace(element) { -// if (element.children.length) { -// const firstChild = element.children[0]; -// const lastChild = element.children[element.children.length - 1]; - -// if (firstChild.type === 'Text') { -// firstChild.data = trimStart(firstChild.data); -// if (!firstChild.data) element.children.shift(); -// } - -// if (lastChild.type === 'Text') { -// lastChild.data = trimEnd(lastChild.data); -// if (!lastChild.data) element.children.pop(); -// } -// } -// } \ No newline at end of file