elm/runtime/HotSwap.js
2014-03-12 02:23:25 -05:00

42 lines
1.4 KiB
JavaScript

(function() {
// Returns boolean indicating if the swap was successful.
// Requires that the two signal graphs have exactly the same
// structure.
ElmRuntime.swap = function(from, to) {
function similar(nodeOld,nodeNew) {
var idOkay = nodeOld.id === nodeNew.id;
var lengthOkay = nodeOld.kids.length === nodeNew.kids.length;
return idOkay && lengthOkay;
}
function swap(nodeOld,nodeNew) {
nodeNew.value = nodeOld.value;
return true;
}
var canSwap = depthFirstTraversals(similar, from.inputs, to.inputs);
if (canSwap) { depthFirstTraversals(swap, from.inputs, to.inputs); }
from.node.parentNode.replaceChild(to.node, from.node);
return canSwap;
}
// Returns false if the node operation f ever fails.
function depthFirstTraversals(f, queueOld, queueNew) {
if (queueOld.length !== queueNew.length) return false;
queueOld = queueOld.slice(0);
queueNew = queueNew.slice(0);
var seen = [];
while (queueOld.length > 0 && queueNew.length > 0) {
var nodeOld = queueOld.pop();
var nodeNew = queueNew.pop();
if (seen.indexOf(nodeOld.id) < 0) {
if (!f(nodeOld, nodeNew)) return false;
queueOld = queueOld.concat(nodeOld.kids);
queueNew = queueNew.concat(nodeNew.kids);
seen.push(nodeOld.id);
}
}
return true;
}
}());