<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <meta http-equiv="X-UA-Compatible" content="IE=edge">  <meta name="viewport" content="width=device-width, initial-scale=1.0">  <title>Document</title></head><body>  <script>    let oldVnode = {      value: 0,      children: [         {          value: 1,          children: [          {            value: 1,            elm: []          },          {            value: 2,            elm: []          },         ],          elm: [ 1, 2]        },        {          value: 2,          children: [            {              value: 1,              elm: []            }          ],          elm: [1]        },        {          value: 3,          children: [],          elm: []        }      ],      elm: [ 1, 2, 3 ]    }    let vnode = {      value: 0,      children: [         {          value: 2,          children: [ { value: 3 } ],        },        {          value: 3,          children: [ { value: 1 }, { value: 2 } ],        },        {          value: 5,          children: [ { value: 1 }, { value: 2 }, { value: 3 }],        }      ],    }    console.log( patch( oldVnode, vnode ) )    function patch( oldVnode, vnode ) {            sameVnode( oldVnode, vnode ) ?             patchVnode( oldVnode, vnode ) : createElm( vnode )      return vnode    }    function createElm( vnode ) {      let elm = vnode.elm = []      const children = vnode.children || []      for( let i =0 ; i < children.length; i++ ) {        let child = children[i]                createElm( child )                elm.push( child.value )      }    }    function sameVnode( oldVnode, vnode ) {      return oldVnode.value === vnode.value    }    function patchVnode( oldVnode, vnode ) {      let oldChildren = oldVnode.children && oldVnode.children.length      let children = vnode.children && vnode.children.length      if ( oldChildren && children  ) {        updateChildren(oldVnode.elm, oldVnode.children, vnode.children )        vnode.elm = oldVnode.elm      }else if ( oldChildren ) {        vnode.elm = []      }else if ( children ) {        createElm( vnode )      }    }    function updateChildren( oldElm, oldChildren, children ) {      let newStartIndex = 0      let newStart = children[ newStartIndex ]      let oldStartIndex = 0      let oldStart = oldChildren[ oldStartIndex ]      let newEndIndex = children.length - 1      let newEnd = children[ newEndIndex ]      let oldEndIndex = oldChildren.length - 1      let oldEnd = oldChildren[ oldEndIndex ]      while( oldStartIndex <= oldEndIndex && newStartIndex <= newEndIndex ) {        if ( !oldStart ) {          oldStart = oldChildren[ ++oldStartIndex ]        }else if ( !oldEnd ) {          oldEnd = oldChildren[ --oldEndIndex ]        }else if ( sameVnode( oldStart, newStart ) ) {          patchVnode( oldStart, newStart )          oldStart = oldChildren[ ++oldStartIndex ]          newStart = children[ ++newStartIndex ]        }else if ( sameVnode( oldEnd, newEnd ) ) {          patchVnode( oldEnd, newEnd )          oldEnd = oldChildren[ --oldEndIndex ]          newEnd = children[ --newEndIndex ]        }else if ( sameVnode( oldStart, newEnd ) ) {          patchVnode( oldStart, newEnd )                    moveArray( oldElm, oldStart.value, oldEnd.value, false )          oldStart = oldChildren[ ++oldStartIndex ]          newEnd = children[ --newEndIndex ]        }else if ( sameVnode( oldEnd, newStart ) ) {          patchVnode( oldEnd, newStart )                    moveArray( oldElm, oldEnd.value, oldStart.value, true  )          oldEnd = oldChildren[ --oldEndIndex ]          newStart = children[ ++newStartIndex ]        }else {          let startIndex = oldStartIndex          while( startIndex <= oldEndIndex ) {            let oldNode = oldChildren[ startIndex ]            if ( sameVnode( oldNode, newStart )  ) {              patchVnode( oldNode, newStart )              oldChildren[ startIndex ] = undefined                            moveArray( oldElm, oldNode.value, oldStart.value, true  )              break            }            startIndex++          }          if ( startIndex > oldEndIndex ) {            createElm( newStart )            oldElm.splice( oldElm.indexOf( oldStart ), 0, newStart.value )          }          newStart = children[ ++newStartIndex ]        }      }      if ( oldStartIndex > oldEndIndex ) {        for(; newStartIndex <= newEndIndex ;  ) {          newStart = children[ newStartIndex++ ]          createElm( newStart )          children[ newEndIndex + 1 ] ?           oldElm.splice( oldElm.indexOf( children[ newEndIndex + 1 ].value ), 0, newStart.value ) :           oldElm.push( newStart.value )                  }      }else {        for( ; oldStartIndex <= oldEndIndex ; ) {          oldStart = oldChildren[ oldStartIndex++ ]          oldStart && oldElm.splice( oldElm.indexOf( oldStart ), 1 )        }      }    }    function moveArray( array, source, target, forward ) {      const sourceIndex = array.indexOf( source )      const targetIndex = array.indexOf( target )      let [ targetItem ] = array.splice( sourceIndex, 1 )      array.splice( targetIndex + ( forward ? 0 : 1 ), 0, targetItem )    }      </script></body></html>