diff --git a/lib/parse.js b/lib/parse.js index 67dd8b3..436cdce 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -63,10 +63,21 @@ module.exports = function parse(html, options) { level--; if (!inComponent && nextChar !== '<' && nextChar) { // trailing text node - arr[level].children.push({ - type: 'text', - content: html.slice(start, html.indexOf('<', start)) - }); + // if we're at the root, push a base text node. otherwise add as + // a child to the current node. + parent = level === -1 ? result : arr[level].children; + + // calculate correct end of the content slice in case there's + // no tag after the text node. + var end = html.indexOf('<', start); + var content = html.slice(start, end === -1 ? undefined : end); + // if a node is nothing but whitespace, no need to add it. + if (!/^\s*$/.test(content)) { + parent.push({ + type: 'text', + content: content + }); + } } } }); diff --git a/test/parse.js b/test/parse.js index 8e9f101..9369673 100644 --- a/test/parse.js +++ b/test/parse.js @@ -292,6 +292,80 @@ test('parse', function (t) { { type: 'text', content: ' 10 ' }, ] }], 'should not give voidElements children'); + + html = '
\n'; + parsed = HTML.parse(html); + t.deepEqual(parsed, [{ + type: 'tag', + name: 'div', + attrs: {}, + voidElement: false, + children: [] + }], 'should not explode on trailing whitespace'); + + html = '
Hi
There '; + parsed = HTML.parse(html); + t.deepEqual(parsed, [{ + type: 'tag', + name: 'div', + attrs: {}, + voidElement: false, + children: [ + { type: 'text', content: 'Hi' } + ] + },{ + type: 'text', content: ' There ' + }], 'should handle trailing text nodes at the top-level'); + + html = '
Hi
There something else '; + parsed = HTML.parse(html); + t.deepEqual(parsed, [{ + type: 'tag', + name: 'div', + attrs: {}, + voidElement: false, + children: [ + { type: 'text', content: 'Hi' } + ] + },{ + type: 'text', content: ' There ' + },{ + type: 'tag', + name: 'span', + attrs: {}, + voidElement: false, + children: [ + { type: 'text', content: 'something' } + ] + },{ + type: 'tag', + name: 'a', + attrs: {}, + voidElement: false, + children: [] + },{ + type: 'text', content: 'else ' + }], 'should handle text nodes in the middle of tags at the top-level'); + + html = '
Hi
\n\n There \t '; + parsed = HTML.parse(html); + t.deepEqual(parsed, [{ + type: 'tag', + name: 'div', + attrs: {}, + voidElement: false, + children: [ + { type: 'text', content: 'Hi' } + ] + },{ + type: 'tag', + name: 'span', + attrs: {}, + voidElement: false, + children: [ + { type: 'text', content: 'There' } + ] + }], 'should remove text nodes that are nothing but whitespace'); t.end(); });