Skip to content

Commit 11451ed

Browse files
committed
create element stack, then resolve to strings
1 parent 8767d17 commit 11451ed

File tree

2 files changed

+34
-22
lines changed

2 files changed

+34
-22
lines changed

src/vhtml.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,29 @@ let map = {'&':'amp','<':'lt','>':'gt','"':'quot',"'":'apos'};
66

77
let sanitized = {};
88

9+
function Element(name, attrs, stack) {
10+
this.type = typeof name === 'function' ? name.name : name;
11+
this.props = attrs || {};
12+
this.toString = _h.bind(this, name, stack);
13+
}
14+
915
/** Hyperscript reviver that constructs a sanitized HTML string. */
1016
export default function h(name, attrs) {
1117
let stack=[];
1218
for (let i=arguments.length; i-- > 2; ) {
1319
stack.push(arguments[i]);
1420
}
1521

22+
return new Element(name, attrs, stack);
23+
}
24+
25+
function _h(name, stack) {
26+
let attrs = this.props;
27+
1628
// Sortof component support!
1729
if (typeof name==='function') {
18-
(attrs || (attrs = {})).children = stack.reverse();
19-
return name(attrs);
20-
// return name(attrs, stack.reverse());
30+
attrs.children = stack.reverse();
31+
return String(name(attrs));
2132
}
2233

2334
let s = `<${name}`;
@@ -37,7 +48,8 @@ export default function h(name, attrs) {
3748
for (let i=child.length; i--; ) stack.push(child[i]);
3849
}
3950
else {
40-
s += sanitized[child]===true ? child : esc(child);
51+
let resolved = String(child);
52+
s += sanitized[resolved]===true ? resolved : esc(resolved);
4153
}
4254
}
4355
}

test/vhtml.js

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { expect } from 'chai';
66
describe('vhtml', () => {
77
it('should stringify html', () => {
88
let items = ['one', 'two', 'three'];
9-
expect(
9+
expect(String(
1010
<div class="foo">
1111
<h1>Hi!</h1>
1212
<p>Here is a list of {items.length} items:</p>
@@ -16,38 +16,38 @@ describe('vhtml', () => {
1616
)) }
1717
</ul>
1818
</div>
19-
).to.equal(
19+
)).to.equal(
2020
`<div class="foo"><h1>Hi!</h1><p>Here is a list of 3 items:</p><ul><li>one</li><li>two</li><li>three</li></ul></div>`
2121
);
2222
});
2323

2424
it('should sanitize children', () => {
25-
expect(
25+
expect(String(
2626
<div>
2727
{ `<strong>blocked</strong>` }
2828
<em>allowed</em>
2929
</div>
30-
).to.equal(
30+
)).to.equal(
3131
`<div>&lt;strong&gt;blocked&lt;/strong&gt;<em>allowed</em></div>`
3232
);
3333
});
3434

3535
it('should sanitize attributes', () => {
36-
expect(
36+
expect(String(
3737
<div onclick={`&<>"'`} />
38-
).to.equal(
38+
)).to.equal(
3939
`<div onclick="&amp;&lt;&gt;&quot;&apos;"></div>`
4040
);
4141
});
4242

4343
it('should flatten children', () => {
44-
expect(
44+
expect(String(
4545
<div>
4646
{[['a','b']]}
4747
<c>d</c>
4848
{['e',['f'],[['g']]]}
4949
</div>
50-
).to.equal(
50+
)).to.equal(
5151
`<div>ab<c>d</c>efg</div>`
5252
);
5353
});
@@ -62,7 +62,7 @@ describe('vhtml', () => {
6262
</li>
6363
);
6464

65-
expect(
65+
expect(String(
6666
<div class="foo">
6767
<h1>Hi!</h1>
6868
<ul>
@@ -73,7 +73,7 @@ describe('vhtml', () => {
7373
)) }
7474
</ul>
7575
</div>
76-
).to.equal(
76+
)).to.equal(
7777
`<div class="foo"><h1>Hi!</h1><ul><li id="0"><h4>one</h4>This is item one!</li><li id="1"><h4>two</h4>This is item two!</li></ul></div>`
7878
);
7979
});
@@ -87,7 +87,7 @@ describe('vhtml', () => {
8787
</li>
8888
);
8989

90-
expect(
90+
expect(String(
9191
<div class="foo">
9292
<h1>Hi!</h1>
9393
<ul>
@@ -98,7 +98,7 @@ describe('vhtml', () => {
9898
)) }
9999
</ul>
100100
</div>
101-
).to.equal(
101+
)).to.equal(
102102
`<div class="foo"><h1>Hi!</h1><ul><li><h4></h4></li><li><h4></h4></li></ul></div>`
103103
);
104104
});
@@ -113,7 +113,7 @@ describe('vhtml', () => {
113113
</li>
114114
);
115115

116-
expect(
116+
expect(String(
117117
<div class="foo">
118118
<h1>Hi!</h1>
119119
<ul>
@@ -124,13 +124,13 @@ describe('vhtml', () => {
124124
)) }
125125
</ul>
126126
</div>
127-
).to.equal(
127+
)).to.equal(
128128
`<div class="foo"><h1>Hi!</h1><ul><li><h4></h4>This is item one!</li><li><h4></h4>This is item two!</li></ul></div>`
129129
);
130130
});
131131

132132
it('should support empty (void) tags', () => {
133-
expect(
133+
expect(String(
134134
<div>
135135
<area />
136136
<base />
@@ -153,15 +153,15 @@ describe('vhtml', () => {
153153
<span />
154154
<p />
155155
</div>
156-
).to.equal(
156+
)).to.equal(
157157
`<div><area><base><br><col><command><embed><hr><img><input><keygen><link><meta><param><source><track><wbr><div></div><span></span><p></p></div>`
158158
);
159159
});
160160

161161
it('should handle className as class', () => {
162-
expect(
162+
expect(String(
163163
<div className="my-class" />
164-
).to.equal(
164+
)).to.equal(
165165
'<div class="my-class"></div>'
166166
);
167167
});

0 commit comments

Comments
 (0)