Skip to content

feat: trim whitespace #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 28 additions & 3 deletions lib/extend.es6
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ export default (options = {}) => {
tree = handleExtendsNodes(tree, options, tree.messages);

const blockNodes = getBlockNodes(tree);
let blockTree;

for (let blockName of Object.keys(blockNodes)) {
let blockNode = blockNodes[blockName];
blockNode.tag = false;
blockNode.content = blockNode.content || [];
blockTree = blockNode.content = blockNode.content || [];
blockNodes[blockName] = blockNode;
trimTree(blockTree);
}

return tree;
Expand All @@ -32,6 +35,26 @@ export default (options = {}) => {

const api = new Api();

function trimTree(tree) {
let firstNode = tree[0];
let lastNode = tree[tree.length - 1];

if (typeof firstNode === 'string') {
tree[0] = firstNode = firstNode.replace(/^\s+/, '');

// make first and last node refer to the same string if they are the same node
if (tree.length === 1) {
lastNode = firstNode;
}
}

if (typeof lastNode === 'string') {
tree[tree.length - 1] = lastNode = lastNode.replace(/\s+$/, '');
}

return tree;
}

function handleExtendsNodes(tree, options, messages) {
api.match.call(applyPluginsToTree(tree, options.plugins), {tag: 'extends'}, extendsNode => {
if (! extendsNode.attrs || ! extendsNode.attrs.src) {
Expand All @@ -42,6 +65,8 @@ function handleExtendsNodes(tree, options, messages) {
const layoutHtml = fs.readFileSync(layoutPath, options.encoding);
let layoutTree = handleExtendsNodes(applyPluginsToTree(parseToPostHtml(layoutHtml), options.plugins), options, messages);

trimTree(layoutTree);

extendsNode.tag = false;
extendsNode.content = mergeExtendsAndLayout(layoutTree, extendsNode);
messages.push({
Expand Down Expand Up @@ -72,11 +97,11 @@ function mergeExtendsAndLayout(layoutTree, extendsNode) {
}

let layoutBlockNode = layoutBlockNodes[layoutBlockName];
layoutBlockNode.content = mergeContent(
layoutBlockNode.content = trimTree(mergeContent(
extendsBlockNode.content,
layoutBlockNode.content,
getBlockType(extendsBlockNode)
);
));

delete extendsBlockNodes[layoutBlockName];
}
Expand Down
7 changes: 7 additions & 0 deletions test/expect/result_trim-whitespace.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
No line breaks <span>are inserted,</span> because "block" and "extend" are control tags... <i>...which can't dictate vertical indentation.</i>

I am indented according to the file which should control it — base.html.



<b>^^^ 3 empty lines above me (and no empty lines below), as per base.html.</b>
17 changes: 17 additions & 0 deletions test/extend.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ let mfs = {
this._files[fullPath] = content;
}
};
const join = require('path').join;
const readSync = require('fs').readFileSync;
const fixture = (file) => {
return readSync(join(__dirname, 'fixtures', `${file}.html`), 'utf8');
};
const result = (file) => {
return readSync(join(__dirname, 'expect', `${file}.html`), 'utf8');
};

const extend = proxyquire('../lib/extend', {
fs: mfs
Expand Down Expand Up @@ -200,6 +208,15 @@ describe('Extend', () => {
'[posthtml-extend] Unexpected block "head"'
);
});

it('should remove all whitespace at the start/end of the first/last text node', () => {
mfs.writeFileSync( './base.html', fixture('base_trim-whitespace'));
mfs.writeFileSync( './layout.html', fixture('layout_trim-whitespace'));

return init(fixture('test_trim-whitespace')).then(html => {
expect(html).toBe(result('result_trim-whitespace'));
});
});
});

describe('Messages', () => {
Expand Down
7 changes: 7 additions & 0 deletions test/fixtures/base_trim-whitespace.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<block name="a"></block> <block name="b"></block> <block name="c"></block> <block name="d"></block>

<block name="e"></block>



<block name="f"></block>
8 changes: 8 additions & 0 deletions test/fixtures/layout_trim-whitespace.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<extends src="base.html">

<block name="f">
<b>^^^ 3 empty lines above me (and no empty lines below), as per base.html.</b>
</block>


</extends>
39 changes: 39 additions & 0 deletions test/fixtures/test_trim-whitespace.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<extends src="layout.html">


<block name="a">

No line breaks

</block>

<block name="b">

<span>are inserted,</span>
</block>

<block name="c">
because "block" and "extend" are control tags...
</block>
<block name="d">
<i>...which can't dictate vertical indentation.</i>



</block>




<block name="e">



I am indented according to the file which should control it — base.html.



</block>


</extends>