export function unmount (vnode, parentDom?) { if (isInvalid(vnode)) { return } const vtype = vnode.vtype // Bitwise operators for better performance // see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators const dom = vtype & VType.Composite ? vnode.component.dom : vnode.dom if ((vtype & (VType.Composite | VType.Stateless)) > 0) { options.beforeUnmount(vnode) vnode.destroy() } else if ((vtype & VType.Node) > 0) { const { props, children, ref } = vnode unmountChildren(children) for (const propName in props) { if (isAttrAnEvent(propName)) { detachEvent(dom, propName, props[propName]) } } if (ref !== null) { Ref.detach(vnode, ref, dom) } } if (!isNullOrUndef(parentDom) && !isNullOrUndef(dom)) { parentDom.removeChild(dom) } // vnode.dom = null }
vnode.forEach((child) => { if (!isInvalid(child)) { const childNode = createElement(child, isSvg, parentContext, parentComponent) if (childNode) { domNode.appendChild(childNode) } } })
function isSameVNode (a, b) { if (isInvalid(a) || isInvalid(b)) { return false } return a.type === b.type && a.key === b.key }
return children.map(fn) }, forEach ( children: Array<VirtualChildren | any>, fn: IterateFn, ctx: any ): void { if (isNullOrUndef(children)) { return } children = Children.toArray(children) if (ctx && ctx !== children) { fn = fn.bind(ctx) } for (let i = 0, len = children.length; i < len; i++) { const child = isInvalid(children[i]) ? null : children[i] fn(child, i, children) } }, count (children: Array<VirtualChildren | any>): number { children = Children.toArray(children) return children.length }, only (children: Array<VirtualChildren | any>): VirtualChildren | any { children = Children.toArray(children) if (children.length !== 1) { throw new Error('Children.only() expects only one child.') } return children[0] },
function renderVNodeToString (vnode, parent, context, isSvg?: boolean) { if (isInvalid(vnode)) { return '' } const { type, props, children } = vnode if (isVText(vnode)) { return encodeEntities(vnode.text) } else if (isVNode(vnode)) { let renderedString = `<${type}` let html if (!isNullOrUndef(props)) { for (let prop in props) { const value = props[prop] if (skipAttributes[prop]) { continue } if (prop === 'dangerouslySetInnerHTML') { html = value.__html } else if (prop === 'style') { const styleStr = renderStylesToString(value) renderedString += styleStr ? ` style="${renderStylesToString(value)}"` : '' } else if (prop === 'class' || prop === 'className') { renderedString += ` class="${isString(value) ? value : hashToClassName(value)}"` } else if (prop === 'defaultValue') { if (!props.value) { renderedString += ` value="${encodeEntities(value)}"` } } else if (prop === 'defaultChecked') { if (!props.checked) { renderedString += ` checked="${value}"` } } else if (isSvg && prop.match(/^xlink\:?(.+)/)) { prop = prop.toLowerCase().replace(/^xlink\:?(.+)/, 'xlink:$1') renderedString += ` ${prop}="${encodeEntities(value)}"` } else { if (isString(value)) { renderedString += ` ${prop}="${encodeEntities(value)}"` } else if (isNumber(value)) { renderedString += ` ${prop}="${value}"` } else if (value === true) { renderedString += ` ${prop}` } } } } if (isVoidElements[type]) { renderedString += `/>` } else { renderedString += `>` if (html) { renderedString += html } else if (!isInvalid(children)) { if (isString(children)) { renderedString += children === '' ? ' ' : encodeEntities(children) } else if (isNumber(children)) { renderedString += children + '' } else if (isArray(children)) { for (let i = 0, len = children.length; i < len; i++) { const child = children[i] if (isString(child)) { renderedString += child === '' ? ' ' : encodeEntities(child) } else if (isNumber(child)) { renderedString += child } else if (!isInvalid(child)) { isSvg = type === 'svg' ? true : type === 'foreignObject' ? false : isSvg renderedString += renderVNodeToString( child, vnode, context, isSvg ) } } } else { isSvg = type === 'svg' ? true : type === 'foreignObject' ? false : isSvg renderedString += renderVNodeToString(children, vnode, context, isSvg) } } if (!isVoidElements[type]) { renderedString += `</${type}>` } } return renderedString } else if (isComposite(vnode)) { const instance = new type(props, context) instance._disable = true instance.props = props instance.context = context if (isFunction(instance.componentWillMount)) { instance.componentWillMount() } const rendered = instance.render() if (isFunction(instance.getChildContext)) { context = extend(clone(context), instance.getChildContext()) } return renderVNodeToString(rendered, vnode, context, isSvg) } else if (isStateless(vnode)) { const rendered = type(props, context) return renderVNodeToString(rendered, vnode, context, isSvg) } }