Inserts `newNode` into `parent` at `index`, optionally replaceing the
current node at `index`. If `newNode` is a DocumentFragment, its childNodes
are inserted and removed from the fragment.
function insertNode(parent, index, newNode, replace) {
  if (!parent.childNodes) {
    parent.childNodes = [];
  }
  var newNodes = [];
  var removedNode = replace ? parent.childNodes[index] : null;
  if (newNode) {
    if (isDocumentFragment(newNode)) {
      if (newNode.childNodes) {
        newNodes = Array.from(newNode.childNodes);
        newNode.childNodes.length = 0;
      }
    } else {
      newNodes = [newNode];
      remove(newNode);
    }
  }
  if (replace) {
    removedNode = parent.childNodes[index];
  }
  Array.prototype.splice.apply(parent.childNodes, [index, replace ? 1 : 0].concat(newNodes));
  newNodes.forEach(function(n) {
    n.parentNode = parent;
  });
  if (removedNode) {
    removedNode.parentNode = undefined;
  }
}