Skip to content

Instantly share code, notes, and snippets.

@asolove
Last active March 11, 2017 02:52
Show Gist options
  • Save asolove/2399aa6069aa2fe687fc926ec0c82d74 to your computer and use it in GitHub Desktop.
Save asolove/2399aa6069aa2fe687fc926ec0c82d74 to your computer and use it in GitHub Desktop.
preact/src/h.js
import { VNode } from './vnode';
import options from './options';
// a single empty array shared among all child-less nodes to prevent having to allocate one array each
const EMPTY_CHILDREN = [];
export function h(nodeName, attributes) {
let children = // deleted code to calculate children
let p = new VNode(nodeName, attributes || undefined, children || EMPTY_CHILDREN);
// if a "vnode hook" is defined, pass every created VNode to it
if (options.vnode) options.vnode(p);
return p;
}
// stack of children or arrays of children left to process
const stack = [];
let children, lastSimple, child, simple, i;
// Children can be passed as extra arguments to `h`
for (i=arguments.length; i-- > 2; ) {
stack.push(arguments[i]);
}
// They can also be passed in the `attributes` parameter, but should not be used as actual html attributes
if (attributes && attributes.children) {
if (!stack.length) stack.push(attributes.children);
delete attributes.children;
}
// Loop until we have flattened and normalized all children
while (stack.length) {
// if the stack item is an array, just push all its elements onto the stack
if ((child = stack.pop()) instanceof Array) {
for (i=child.length; i--; ) stack.push(child[i]);
}
// Now with each individual child, coerce it to something we can render:
else if (child!=null && child!==true && child!==false) {
if (typeof child=='number') child = String(child);
simple = typeof child=='string';
if (simple && lastSimple) {
children[children.length-1] += child;
}
else {
(children || (children = [])).push(child);
lastSimple = simple;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment