Skip to content

Commit 2001cac

Browse files
marvinhagemeisterdevelopit
authored andcommitted
Join adjacent text nodes (#109)
* Join adjacent text nodes in pretty mode * Refactor pretty printing of adjacent text nodes
1 parent 359f041 commit 2001cac

File tree

3 files changed

+114
-2
lines changed

3 files changed

+114
-2
lines changed

src/index.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,13 +200,37 @@ function renderToString(vnode, context, opts, inner, isSvgMode, selectValue) {
200200
}
201201
else if (props && getChildren(children = [], props.children).length) {
202202
let hasLarge = pretty && ~s.indexOf('\n');
203+
let lastWasText = false;
204+
203205
for (let i=0; i<children.length; i++) {
204206
let child = children[i];
207+
205208
if (child!=null && child!==false) {
206209
let childSvgMode = nodeName==='svg' ? true : nodeName==='foreignObject' ? false : isSvgMode,
207210
ret = renderToString(child, context, opts, true, childSvgMode, selectValue);
211+
208212
if (pretty && !hasLarge && isLargeString(ret)) hasLarge = true;
209-
if (ret) pieces.push(ret);
213+
214+
// Skip if we received an empty string
215+
if (ret) {
216+
if (pretty) {
217+
let isText = ret.length > 0 && ret[0]!='<';
218+
219+
// We merge adjacent text nodes, otherwise each piece would be printed
220+
// on a new line.
221+
if (lastWasText && isText) {
222+
pieces[pieces.length -1] += ret;
223+
}
224+
else {
225+
pieces.push(ret);
226+
}
227+
228+
lastWasText = isText;
229+
}
230+
else {
231+
pieces.push(ret);
232+
}
233+
}
210234
}
211235
}
212236
if (pretty && hasLarge) {

test/jsx.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import sinonChai from 'sinon-chai';
55
chai.use(sinonChai);
66

77
// tag to remove leading whitespace from tagged template literal
8-
function dedent([str]) {
8+
export function dedent([str]) {
99
return str.split( '\n'+str.match(/^\n*(\s+)/)[1] ).join('\n').replace(/(^\n+|\n+\s*$)/g, '');
1010
}
1111

test/pretty.js

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { render } from '../src/jsx';
33
import { h, Fragment } from 'preact';
44
import chai, { expect } from 'chai';
55
import sinonChai from 'sinon-chai';
6+
import { dedent } from './jsx';
67
chai.use(sinonChai);
78

89
describe('pretty', () => {
@@ -96,4 +97,91 @@ describe('pretty', () => {
9697
</div>
9798
)).to.equal(`<div>\n\t<div>A</div>\n\t<div>B</div>\n</div>`);
9899
});
100+
101+
it('should join adjacent text nodes', () => {
102+
expect(prettyRender(
103+
<div>hello{' '} <b /></div>
104+
)).to.equal(dedent`
105+
<div>
106+
hello
107+
<b></b>
108+
</div>
109+
`);
110+
111+
expect(prettyRender(
112+
<div>hello{' '} <b />{'a'}{'b'}</div>
113+
)).to.equal(dedent`
114+
<div>
115+
hello
116+
<b></b>
117+
ab
118+
</div>
119+
`);
120+
});
121+
122+
it('should join adjacent text nodeswith Fragments', () => {
123+
expect(prettyRender(
124+
<div><Fragment>foo</Fragment>bar{' '} <b /></div>
125+
)).to.equal(dedent`
126+
<div>
127+
foobar
128+
<b></b>
129+
</div>
130+
`);
131+
});
132+
133+
it('should collapse whitespace', () => {
134+
expect(prettyRender(
135+
<p>a<a>b</a></p>
136+
)).to.equal(dedent`
137+
<p>
138+
a
139+
<a>b</a>
140+
</p>
141+
`);
142+
143+
expect(prettyRender(
144+
<p>
145+
a{' '}
146+
<a>b</a>
147+
</p>
148+
)).to.equal(dedent`
149+
<p>
150+
a
151+
<a>b</a>
152+
</p>
153+
`);
154+
155+
expect(prettyRender(
156+
<p>
157+
a{''}
158+
<a>b</a>
159+
</p>
160+
)).to.equal(dedent`
161+
<p>
162+
a
163+
<a>b</a>
164+
</p>
165+
`);
166+
167+
expect(prettyRender(
168+
<p>a <a>b</a></p>
169+
)).to.equal(dedent`
170+
<p>
171+
a\
172+
<a>b</a>
173+
</p>
174+
`);
175+
176+
expect(prettyRender(<a> b </a>)).to.equal(dedent`
177+
<a> b </a>
178+
`);
179+
180+
expect(prettyRender(<p><b /> a </p>)).to.equal(dedent`
181+
<p>
182+
<b></b>
183+
\ a\
184+
</p>
185+
`);
186+
});
99187
});

0 commit comments

Comments
 (0)