mostly-dom
Version:
A virtual-dom for TypeScript
84 lines • 4.12 kB
JavaScript
import { addVNodes } from './addVNodes';
import { createElement } from './createElement';
import { patchVNode } from './patchVNode';
import { removeVNodes } from './removeVNodes';
import { vNodesAreEqual } from './helpers';
export function updateChildren(parentElement, formerChildren, children, moduleCallbacks, insertedVNodeQueue) {
// indexes
var formerStartIndex = 0;
var startIndex = 0;
var formerEndIndex = formerChildren.length - 1;
var endIndex = children.length - 1;
// VNodes
var formerStartVNode = formerChildren[formerStartIndex];
var startVNode = children[startIndex];
var formerEndVNode = formerChildren[formerEndIndex];
var endVNode = children[endIndex];
// an object mapping keys to indexes in formerChildren array
var mappedKeyToFormerIndex;
while (formerStartIndex <= formerEndIndex && startIndex <= endIndex) {
if (!formerStartVNode)
formerStartVNode = formerChildren[++formerStartIndex];
else if (!formerEndVNode)
formerEndVNode = formerChildren[--formerEndIndex];
else if (vNodesAreEqual(formerStartVNode, startVNode)) {
patchVNode(formerStartVNode, startVNode, moduleCallbacks, insertedVNodeQueue);
formerStartVNode = formerChildren[++formerStartIndex];
startVNode = children[++startIndex];
}
else if (vNodesAreEqual(formerEndVNode, endVNode)) {
patchVNode(formerEndVNode, endVNode, moduleCallbacks, insertedVNodeQueue);
formerEndVNode = formerChildren[--formerEndIndex];
endVNode = children[--endIndex];
}
else if (vNodesAreEqual(formerStartVNode, endVNode)) {
patchVNode(formerStartVNode, endVNode, moduleCallbacks, insertedVNodeQueue);
parentElement.insertBefore(formerStartVNode.element, formerEndVNode.element.nextSibling);
formerStartVNode = formerChildren[++formerStartIndex];
endVNode = children[--endIndex];
}
else if (vNodesAreEqual(formerEndVNode, startVNode)) {
patchVNode(formerEndVNode, startVNode, moduleCallbacks, insertedVNodeQueue);
parentElement.insertBefore(formerEndVNode.element, formerStartVNode.element);
formerEndVNode = formerChildren[--formerEndIndex];
startVNode = children[++startIndex];
}
else {
if (!mappedKeyToFormerIndex)
mappedKeyToFormerIndex =
mapKeyToFormerIndex(formerChildren, formerStartIndex, formerEndIndex);
var formerIndexKey = mappedKeyToFormerIndex[startVNode.key];
if (!formerIndexKey) { // new element
var element = createElement(startVNode, moduleCallbacks, insertedVNodeQueue).element;
parentElement.insertBefore(element, formerStartVNode.element);
startVNode = children[++startIndex];
}
else {
var reorderableVNode = formerChildren[formerIndexKey];
patchVNode(reorderableVNode, startVNode, moduleCallbacks, insertedVNodeQueue);
// WARNING: hack for performance optimization
formerChildren[formerIndexKey] = void 0;
parentElement.insertBefore(reorderableVNode.element, formerStartVNode.element);
startVNode = children[++startIndex];
}
}
}
if (formerStartIndex > formerEndIndex) {
var referenceNode = children[endIndex + 1] ? children[endIndex + 1].element : null;
addVNodes(parentElement, referenceNode, children, startIndex, endIndex, moduleCallbacks, insertedVNodeQueue);
}
else if (startIndex > endIndex)
removeVNodes(parentElement, formerChildren, formerStartIndex, formerEndIndex, moduleCallbacks);
}
function mapKeyToFormerIndex(children, startIndex, endIndex) {
var index = startIndex;
var map = {};
var key;
for (; index <= endIndex; ++index) {
key = children[index].key;
if (key)
map[key] = index;
}
return map;
}
//# sourceMappingURL=updateChildren.js.map