Skip to content

Commit

Permalink
create element stack, then resolve to strings
Browse files Browse the repository at this point in the history
  • Loading branch information
nathancahill committed Apr 30, 2017
1 parent a111d56 commit 26c4842
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 22 deletions.
20 changes: 16 additions & 4 deletions src/vhtml.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,29 @@ let DOMAttributeNames = {

let sanitized = {};

function Element(name, attrs, stack) {
this.type = typeof name === 'function' ? name.name : name;
this.props = attrs || {};
this.toString = _h.bind(this, name, stack);
}

/** Hyperscript reviver that constructs a sanitized HTML string. */
export default function h(name, attrs) {
let stack=[];
for (let i=arguments.length; i-- > 2; ) {
stack.push(arguments[i]);
}

return new Element(name, attrs, stack);
}

function _h(name, stack) {
let attrs = this.props;

// Sortof component support!
if (typeof name==='function') {
(attrs || (attrs = {})).children = stack.reverse();
return name(attrs);
// return name(attrs, stack.reverse());
attrs.children = stack.reverse();
return String(name(attrs));
}

let s = `<${name}`;
Expand All @@ -41,7 +52,8 @@ export default function h(name, attrs) {
for (let i=child.length; i--; ) stack.push(child[i]);
}
else {
s += sanitized[child]===true ? child : esc(child);
let resolved = String(child);
s += sanitized[resolved]===true ? resolved : esc(resolved);
}
}
}
Expand Down
36 changes: 18 additions & 18 deletions test/vhtml.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { expect } from 'chai';
describe('vhtml', () => {
it('should stringify html', () => {
let items = ['one', 'two', 'three'];
expect(
expect(String(
<div class="foo">
<h1>Hi!</h1>
<p>Here is a list of {items.length} items:</p>
Expand All @@ -16,38 +16,38 @@ describe('vhtml', () => {
)) }
</ul>
</div>
).to.equal(
)).to.equal(
`<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>`
);
});

it('should sanitize children', () => {
expect(
expect(String(
<div>
{ `<strong>blocked</strong>` }
<em>allowed</em>
</div>
).to.equal(
)).to.equal(
`<div>&lt;strong&gt;blocked&lt;/strong&gt;<em>allowed</em></div>`
);
});

it('should sanitize attributes', () => {
expect(
expect(String(
<div onclick={`&<>"'`} />
).to.equal(
)).to.equal(
`<div onclick="&amp;&lt;&gt;&quot;&apos;"></div>`
);
});

it('should flatten children', () => {
expect(
expect(String(
<div>
{[['a','b']]}
<c>d</c>
{['e',['f'],[['g']]]}
</div>
).to.equal(
)).to.equal(
`<div>ab<c>d</c>efg</div>`
);
});
Expand All @@ -62,7 +62,7 @@ describe('vhtml', () => {
</li>
);

expect(
expect(String(
<div class="foo">
<h1>Hi!</h1>
<ul>
Expand All @@ -73,7 +73,7 @@ describe('vhtml', () => {
)) }
</ul>
</div>
).to.equal(
)).to.equal(
`<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>`
);
});
Expand All @@ -87,7 +87,7 @@ describe('vhtml', () => {
</li>
);

expect(
expect(String(
<div class="foo">
<h1>Hi!</h1>
<ul>
Expand All @@ -98,7 +98,7 @@ describe('vhtml', () => {
)) }
</ul>
</div>
).to.equal(
)).to.equal(
`<div class="foo"><h1>Hi!</h1><ul><li><h4></h4></li><li><h4></h4></li></ul></div>`
);
});
Expand All @@ -113,7 +113,7 @@ describe('vhtml', () => {
</li>
);

expect(
expect(String(
<div class="foo">
<h1>Hi!</h1>
<ul>
Expand All @@ -124,13 +124,13 @@ describe('vhtml', () => {
)) }
</ul>
</div>
).to.equal(
)).to.equal(
`<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>`
);
});

it('should support empty (void) tags', () => {
expect(
expect(String(
<div>
<area />
<base />
Expand All @@ -153,15 +153,15 @@ describe('vhtml', () => {
<span />
<p />
</div>
).to.equal(
)).to.equal(
`<div><area><base><br><col><command><embed><hr><img><input><keygen><link><meta><param><source><track><wbr><div></div><span></span><p></p></div>`
);
});

it('should handle special prop names', () => {
expect(
expect(String(
<div className="my-class" htmlFor="id" />
).to.equal(
)).to.equal(
'<div class="my-class" for="id"></div>'
);
});
Expand Down

0 comments on commit 26c4842

Please sign in to comment.