function build (dom, vnode) {
  let out = dom,
    nodeName = vnode.nodeName

  if (typeof nodeName === 'function' && !nodeName.prototype.render) {
    vnode = buildFunctionalComponent(vnode)
    nodeName = vnode.nodeName
  }

  if (typeof nodeName === 'function') {
    return buildComponentFromVNode(dom, vnode)
  }

  if (typeof vnode === 'string') {
    if (dom) {
      if (dom.nodeType === 3) {
        dom[TEXT_CONTENT] = vnode
        return dom
      } else if (dom.nodeType === 1) {
        recycler.collect(dom)
      }
    }
    return document.createTextNode(vnode)
  }

  if (nodeName === null || nodeName === undefined) {
    nodeName = 'x-undefined-element'
  }

  if (!dom) {
    out = recycler.create(nodeName)
  } else if (dom.nodeName.toLowerCase() !== nodeName) {
    out = recycler.create(nodeName)
    appendChildren(out, toArray(dom.childNodes))
    // reclaim element nodes
    if (dom.nodeType === 1) recycler.collect(dom)
  }

  // apply attributes
  let old = getNodeAttributes(out) || EMPTY,
    attrs = vnode.attributes || EMPTY

  // removed attributes
  if (old !== EMPTY) {
    for (let name in old) {
      if (hop.call(old, name)) {
        let o = attrs[name]
        if (o === undefined || o === null) {
          setAccessor(out, name, null, old[name])
        }
      }
    }
  }

  // new & updated attributes
  if (attrs !== EMPTY) {
    for (let name in attrs) {
      if (hop.call(attrs, name)) {
        let value = attrs[name]
        if (value !== undefined && value !== null) {
          let prev = getAccessor(out, name, old[name])
          if (value !== prev) {
            setAccessor(out, name, value, prev)
          }
        }
      }
    }
  }


  let children = toArray(out.childNodes)
  let keyed = {}
  for (let i = children.length; i--;) {
    let t = children[i].nodeType
    let key
    if (t === 3) {
      key = t.key
    } else if (t === 1) {
      key = children[i].getAttribute('key')
    } else {
      continue
    }
    if (key) keyed[key] = children.splice(i, 1)[0]
  }
  let newChildren = []

  if (vnode.children) {
    for (let i = 0, vlen = vnode.children.length; i < vlen; i++) {
      let vchild = vnode.children[i]
      // if (isFunctionalComponent(vchild)) {
      // 	vchild = buildFunctionalComponent(vchild);
      // }
      let attrs = vchild.attributes,
        key, child
      if (attrs) {
        key = attrs.key
        child = key && keyed[key]
      }

      // attempt to pluck a node of the same type from the existing children
      if (!child) {
        let len = children.length
        if (children.length) {
          for (let j = 0; j < len; j++) {
            if (isSameNodeType(children[j], vchild)) {
              child = children.splice(j, 1)[0]
              break
            }
          }
        }
      }

      // morph the matched/found/created DOM child to match vchild (deep)
      newChildren.push(build(child, vchild))
    }
  }

  // apply the constructed/enhanced ordered list to the parent
  for (let i = 0, len = newChildren.length; i < len; i++) {
    // we're intentionally re-referencing out.childNodes here as it is a live NodeList
    if (out.childNodes[i] !== newChildren[i]) {
      let child = newChildren[i],
        c = child._component,
        next = out.childNodes[i + 1]
      if (c) deepHook(c, 'componentWillMount')
      if (next) {
        out.insertBefore(child, next)
      } else {
        out.appendChild(child)
      }
      if (c) deepHook(c, 'componentDidMount')
    }
  }

  // remove orphaned children
  for (let i = 0, len = children.length; i < len; i++) {
    let child = children[i],
      c = child._component
    if (c) hook(c, 'componentWillUnmount')
    child.parentNode.removeChild(child)
    if (c) {
      hook(c, 'componentDidUnmount')
      componentRecycler.collect(c)
    } else if (child.nodeType === 1) {
      recycler.collect(child)
    }
  }

  return out
}
/** Apply differences in a given vnode (and it's deep children) to a real DOM Node.
 *    @param {Element} [dom=null]        A DOM node to mutate into the shape of the `vnode`
 *    @param {VNode} vnode            A VNode (with descendants forming a tree) representing the desired DOM structure
 *    @returns {Element} dom            The created/mutated element
 *    @private
 */
Apply differences in a given vnode (and it's deep children) to a real DOM Node.
@param {Element} [dom=null]        A DOM node to mutate into the shape of the `vnode`
@param {VNode} vnode            A VNode (with descendants forming a tree) representing the desired DOM structure
@returns {Element} dom            The created/mutated element
@private
Apply differences in a given vnode ( and it ' s deep children ) to a real DOM Node . @param { Element } [ dom = null ] A DOM node to mutate into the shape of the ` vnode ` @param { VNode } vnode A VNode ( with descendants forming a tree ) representing the desired DOM structure @returns { Element } dom The created / mutated element @private
function build (dom, vnode) {
  let out = dom,
    nodeName = vnode.nodeName
  if (typeof nodeName === 'function' && !nodeName.prototype.render) {
    vnode = buildFunctionalComponent(vnode)
    nodeName = vnode.nodeName
  }
  if (typeof nodeName === 'function') {
    return buildComponentFromVNode(dom, vnode)
  }
  if (typeof vnode === 'string') {
    if (dom) {
      if (dom.nodeType === 3) {
        dom[TEXT_CONTENT] = vnode
        return dom
      } else if (dom.nodeType === 1) {
        recycler.collect(dom)
      }
    }
    return document.createTextNode(vnode)
  }
  if (nodeName === null || nodeName === undefined) {
    nodeName = 'x-undefined-element'
  }
  if (!dom) {
    out = recycler.create(nodeName)
  } else if (dom.nodeName.toLowerCase() !== nodeName) {
    out = recycler.create(nodeName)
    appendChildren(out, toArray(dom.childNodes))
    if (dom.nodeType === 1) recycler.collect(dom)
  }
  let old = getNodeAttributes(out) || EMPTY,
    attrs = vnode.attributes || EMPTY
  if (old !== EMPTY) {
    for (let name in old) {
      if (hop.call(old, name)) {
        let o = attrs[name]
        if (o === undefined || o === null) {
          setAccessor(out, name, null, old[name])
        }
      }
    }
  }
  if (attrs !== EMPTY) {
    for (let name in attrs) {
      if (hop.call(attrs, name)) {
        let value = attrs[name]
        if (value !== undefined && value !== null) {
          let prev = getAccessor(out, name, old[name])
          if (value !== prev) {
            setAccessor(out, name, value, prev)
          }
        }
      }
    }
  }
  let children = toArray(out.childNodes)
  let keyed = {}
  for (let i = children.length; i--;) {
    let t = children[i].nodeType
    let key
    if (t === 3) {
      key = t.key
    } else if (t === 1) {
      key = children[i].getAttribute('key')
    } else {
      continue
    }
    if (key) keyed[key] = children.splice(i, 1)[0]
  }
  let newChildren = []
  if (vnode.children) {
    for (let i = 0, vlen = vnode.children.length; i < vlen; i++) {
      let vchild = vnode.children[i]
      let attrs = vchild.attributes,
        key, child
      if (attrs) {
        key = attrs.key
        child = key && keyed[key]
      }
      if (!child) {
        let len = children.length
        if (children.length) {
          for (let j = 0; j < len; j++) {
            if (isSameNodeType(children[j], vchild)) {
              child = children.splice(j, 1)[0]
              break
            }
          }
        }
      }
      newChildren.push(build(child, vchild))
    }
  }
  for (let i = 0, len = newChildren.length; i < len; i++) {
    if (out.childNodes[i] !== newChildren[i]) {
      let child = newChildren[i],
        c = child._component,
        next = out.childNodes[i + 1]
      if (c) deepHook(c, 'componentWillMount')
      if (next) {
        out.insertBefore(child, next)
      } else {
        out.appendChild(child)
      }
      if (c) deepHook(c, 'componentDidMount')
    }
  }
  for (let i = 0, len = children.length; i < len; i++) {
    let child = children[i],
      c = child._component
    if (c) hook(c, 'componentWillUnmount')
    child.parentNode.removeChild(child)
    if (c) {
      hook(c, 'componentDidUnmount')
      componentRecycler.collect(c)
    } else if (child.nodeType === 1) {
      recycler.collect(child)
    }
  }
  return out
}
function build ( dom , vnode ) { let out = dom , nodeName = vnode . nodeName if ( typeof nodeName === 'function' && ! nodeName . prototype . render ) { vnode = buildFunctionalComponent ( vnode ) nodeName = vnode . nodeName } if ( typeof nodeName === 'function' ) { return buildComponentFromVNode ( dom , vnode ) } if ( typeof vnode === 'string' ) { if ( dom ) { if ( dom . nodeType === 3 ) { dom [ TEXT_CONTENT ] = vnode return dom } else if ( dom . nodeType === 1 ) { recycler . collect ( dom ) } } return document . createTextNode ( vnode ) } if ( nodeName === null || nodeName === undefined ) { nodeName = 'x-undefined-element' } if ( ! dom ) { out = recycler . create ( nodeName ) } else if ( dom . nodeName . toLowerCase ( ) !== nodeName ) { out = recycler . create ( nodeName ) appendChildren ( out , toArray ( dom . childNodes ) ) if ( dom . nodeType === 1 ) recycler . collect ( dom ) } let old = getNodeAttributes ( out ) || EMPTY , attrs = vnode . attributes || EMPTY if ( old !== EMPTY ) { for ( let name in old ) { if ( hop . call ( old , name ) ) { let o = attrs [ name ] if ( o === undefined || o === null ) { setAccessor ( out , name , null , old [ name ] ) } } } } if ( attrs !== EMPTY ) { for ( let name in attrs ) { if ( hop . call ( attrs , name ) ) { let value = attrs [ name ] if ( value !== undefined && value !== null ) { let prev = getAccessor ( out , name , old [ name ] ) if ( value !== prev ) { setAccessor ( out , name , value , prev ) } } } } } let children = toArray ( out . childNodes ) let keyed = { } for ( let i = children . length ; i -- ; ) { let t = children [ i ] . nodeType let key if ( t === 3 ) { key = t . key } else if ( t === 1 ) { key = children [ i ] . getAttribute ( 'key' ) } else { continue } if ( key ) keyed [ key ] = children . splice ( i , 1 ) [ 0 ] } let newChildren = [ ] if ( vnode . children ) { for ( let i = 0 , vlen = vnode . children . length ; i < vlen ; i ++ ) { let vchild = vnode . children [ i ] let attrs = vchild . attributes , key , child if ( attrs ) { key = attrs . key child = key && keyed [ key ] } if ( ! child ) { let len = children . length if ( children . length ) { for ( let j = 0 ; j < len ; j ++ ) { if ( isSameNodeType ( children [ j ] , vchild ) ) { child = children . splice ( j , 1 ) [ 0 ] break } } } } newChildren . push ( build ( child , vchild ) ) } } for ( let i = 0 , len = newChildren . length ; i < len ; i ++ ) { if ( out . childNodes [ i ] !== newChildren [ i ] ) { let child = newChildren [ i ] , c = child . _component , next = out . childNodes [ i + 1 ] if ( c ) deepHook ( c , 'componentWillMount' ) if ( next ) { out . insertBefore ( child , next ) } else { out . appendChild ( child ) } if ( c ) deepHook ( c , 'componentDidMount' ) } } for ( let i = 0 , len = children . length ; i < len ; i ++ ) { let child = children [ i ] , c = child . _component if ( c ) hook ( c , 'componentWillUnmount' ) child . parentNode . removeChild ( child ) if ( c ) { hook ( c , 'componentDidUnmount' ) componentRecycler . collect ( c ) } else if ( child . nodeType === 1 ) { recycler . collect ( child ) } } return out }
Apply differences in a given vnode (and it's deep children) to a real DOM Node.
Apply differences in a given vnode ( and it ' s deep children ) to a real DOM Node .
// reclaim element nodes // apply attributes // removed attributes // new & updated attributes // if (isFunctionalComponent(vchild)) { // 	vchild = buildFunctionalComponent(vchild); // } // attempt to pluck a node of the same type from the existing children // morph the matched/found/created DOM child to match vchild (deep) // apply the constructed/enhanced ordered list to the parent // we're intentionally re-referencing out.childNodes here as it is a live NodeList // remove orphaned children