diff --git a/src/hyperscript/h.ts b/src/hyperscript/h.ts index af397cb..ebcc60a 100644 --- a/src/hyperscript/h.ts +++ b/src/hyperscript/h.ts @@ -4,14 +4,14 @@ import { isPrimitive, isString } from '../helpers' export const h: HyperscriptFn = function(): VNode { const tagName: string | ComponentFn = arguments[0] // required - const childrenOrText: HyperscriptChildren = arguments[2] // optional + const childrenOrText: HyperscriptChildren = slice(2, arguments) // optional - let props: VNodeProps = {} - let children: ArrayLike | undefined + let props: VNodeProps = {} + let children: Array | undefined let text: string | undefined if (childrenOrText) { - props = arguments[1] + props = arguments[1] || {} if (isArrayLike(childrenOrText)) children = flattenArrayLike(childrenOrText) as Array else if (isPrimitive(childrenOrText)) text = String(childrenOrText) @@ -21,11 +21,20 @@ export const h: HyperscriptFn = function(): VNode { if (isArrayLike(childrenOrTextOrProps)) children = flattenArrayLike(childrenOrTextOrProps) as Array else if (isPrimitive(childrenOrTextOrProps)) text = String(childrenOrTextOrProps) - else props = childrenOrTextOrProps + else props = childrenOrTextOrProps || {} } if (typeof tagName === 'function') { - return tagName(props, Array.isArray(children) ? children : text ? [ text ] : []) + const childVNodes = Array.isArray(children) + ? children + : text ? [ MostlyVNode.createText(text) ] : [] + const computedVNode = tagName(props, childVNodes) + + if (Array.isArray(computedVNode.children)) { + computedVNode.children = sanitizeChildren(computedVNode.children, computedVNode) + } + + return computedVNode } const isSvg = tagName === 'svg' @@ -41,6 +50,15 @@ export const h: HyperscriptFn = function(): VNode { return vNode } +function slice(from: number, arrLike: ArrayLike): Array | null { + const arr = [] as Array + for (let i = from; i < arrLike.length; ++i) arr.push(arrLike[i]) + + if (arr.length === 0) return null + + return arr +} + function isArrayLike(x: any): x is ArrayLike { const typeOf = typeof x @@ -61,7 +79,7 @@ function forEach(fn: (value: A) => void, list: ArrayLike): void { } function sanitizeChildren(childrenOrText: Array, parent: VNode): Array { - childrenOrText = childrenOrText.filter(Boolean) // remove possible null values + childrenOrText = childrenOrText.filter((x) => x !== null) // remove possible null values const childCount: number = childrenOrText.length const children: Array = Array(childCount) @@ -69,12 +87,13 @@ function sanitizeChildren(childrenOrText: Array, parent: VNode): Array + children[i].parent = parent } return children