Skip to content

Commit

Permalink
Add support for infinitely nested Arrays of children, while improving…
Browse files Browse the repository at this point in the history
… performance and decreasing library size 🎈 /cc @NekR
  • Loading branch information
developit committed Oct 28, 2016
1 parent 24a3fdf commit f46e762
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 10 deletions.
27 changes: 17 additions & 10 deletions src/vhtml.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,31 @@
let esc = str => String(str).replace(/[&<>"']/g, s=>`&${map[s]};`);
let map = {'&':'amp','<':'lt','>':'gt','"':'quot',"'":'apos'};

// sanitize text children and filter out falsey values
let child = s => truthy(s) ? (sanitized[s]===true ? s : esc(s)) : '';

// check that a value is not false, undefined or null
let truthy = v => v!==false && v!=null;

let sanitized = {};

/** Hyperscript reviver that constructs a sanitized HTML string. */
export default function h(name, attrs, ...children) {
export default function h(name, attrs) {
let s = `<${name}`;
if (attrs) for (let i in attrs) {
if (attrs.hasOwnProperty(i) && truthy(attrs[i])) {
if (attrs[i]!==false && attrs[i]!=null) {
s += ` ${esc(i)}="${esc(attrs[i])}"`;
}
}
s += `>${[].concat(...children).map(child).join('')}</${name}>`;
sanitized[s] = true;
s += '>';
let stack=[];
for (let i=arguments.length; i-- > 2; ) stack.push(arguments[i]);
while (stack.length) {
let child = stack.pop();
if (child) {
if (child.pop) {
for (let i=child.length; i--; ) stack.push(child[i]);
}
else {
s += sanitized[child]===true ? child : esc(child);
}
}
}
sanitized[s += `</${name}>`] = true;
return s;
}

Expand Down
12 changes: 12 additions & 0 deletions test/vhtml.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,16 @@ describe('vhtml', () => {
`<div onclick="&amp;&lt;&gt;&quot;&apos;"></div>`
);
});

it('should flatten children', () => {
expect(
<div>
{[['a','b']]}
<c>d</c>
{['e',['f'],[['g']]]}
</div>
).to.equal(
`<div>ab<c>d</c>efg</div>`
);
});
});

1 comment on commit f46e762

@NekR
Copy link
Collaborator

@NekR NekR commented on f46e762 Oct 28, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, many thanks!

Please sign in to comment.