[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/10secondsofcode/pure-virtual-dom/master/diff.js [Back]  [Original]

const CHANGE_TYPE_TEXT = Symbol('text')
const CHANGE_TYPE_PROP = Symbol('props')
const CHANGE_TYPE_REPLACE = Symbol('replace')

function checkChangeType(newNode, oldNode) {
  if (typeof newNode !== typeof oldNode || newNode.tagName !== oldNode.tagName) {
    return CHANGE_TYPE_REPLACE;
  }

  if (typeof newNode === 'string') {
    if (newNode !== oldNode) {
      return CHANGE_TYPE_TEXT;
    }
    return;
  }

  const propsChanged = Reflect
    .ownKeys(newNode.props)
    .reduce(
      (prev, name) => prev || (oldNode.props[name] !== newNode.props[name]), 
      false
    );

  if (propsChanged) {
    return CHANGE_TYPE_PROP;
  }
  return;
}

/**
 * 
 * @param {HTMLElement} $node 
 * @param {Object} removedAttrs 
 * @param {Object} newAttrWithVals 
 */
function replaceAttribute($node, removedAttrs, newAttrs) {
  if (!$node) {
    return
  }

  Reflect.ownKeys(removedAttrs)
    .forEach(attr => $node.removeAttribute(attr))
  Reflect.ownKeys(newAttrs)
    .forEach(attr => $node.setAttribute(attr, newAttrs[attr]))
}

function updateEl($parent, newNode, oldNode, index = 0) {
  let changeType = null;

  if (!oldNode) {
    $parent.appendChild(newNode.render());
  } else if (!newNode) {
    $parent.removeChild($parent.childNodes[index]);
  } else if (changeType = checkChangeType(newNode, oldNode)) {
    if (changeType === CHANGE_TYPE_TEXT) {
      $parent.replaceChild(
        document.createTextNode(newNode),
        $parent.childNodes[index]
      );
    } else if (changeType === CHANGE_TYPE_REPLACE) {
      $parent.replaceChild(newNode.render(), $parent.childNodes[index]);
    } else if (changeType === CHANGE_TYPE_PROP) {
      replaceAttribute($parent.childNodes[index], oldNode.props, newNode.props)
    }
  } else if (newNode.tagName) {
    const newLength = newNode.children.length;
    const oldLength = oldNode.children.length;
    for (let i = 0; i < newLength || i < oldLength; ++i) {
      updateEl(
        $parent.childNodes[index],
        newNode.children[i],
        oldNode.children[i],
        i
      );
    }
  }
}

Web Proxy Viewer  |  New URL  |  Original Page