You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
3.7 KiB
123 lines
3.7 KiB
var toEl = require('./toEl'); |
|
var isStr = require('./isStr'); |
|
var h = require('./h'); |
|
var isNull = require('./isNull'); |
|
var each = require('./each'); |
|
|
|
exports = function(from, to) { |
|
if (isStr(to)) { |
|
to = toEl(to); |
|
} |
|
var morphed = from; |
|
var morphedType = morphed.nodeType; |
|
var toType = to.nodeType; |
|
if (morphedType === toType) { |
|
if (morphedType === ELEMENT_NODE) { |
|
if (morphed.nodeName !== to.nodeName) { |
|
morphed = h(to.nodeName); |
|
moveChildren(from, morphed); |
|
} |
|
} else if (morphedType === TEXT_NODE || morphedType === COMMENT_NODE) { |
|
if (morphed.nodeValue !== to.nodeValue) { |
|
morphed.nodeValue = to.nodeValue; |
|
} |
|
return morphed; |
|
} |
|
} else { |
|
morphed = to; |
|
} |
|
if (morphed !== to) { |
|
morphEl(morphed, to); |
|
} |
|
if (from.parentNode) { |
|
from.parentNode.replaceChild(morphed, from); |
|
} |
|
return morphed; |
|
}; |
|
var ELEMENT_NODE = 1; |
|
var TEXT_NODE = 3; |
|
var COMMENT_NODE = 8; |
|
function morphEl(from, to) { |
|
morphAttrs(from, to); |
|
morphChildren(from, to); |
|
} |
|
function morphAttrs(from, to) { |
|
var attrs = to.attributes; |
|
each(attrs, function(_ref) { |
|
var name = _ref.name, |
|
value = _ref.value; |
|
var fromVal = from.getAttribute(name); |
|
if (fromVal !== value) { |
|
from.setAttribute(name, value); |
|
} |
|
}); |
|
attrs = from.attributes; |
|
var removedAttrNames = []; |
|
each(attrs, function(_ref2) { |
|
var name = _ref2.name; |
|
if (isNull(to.getAttribute(name))) { |
|
removedAttrNames.push(name); |
|
} |
|
}); |
|
each(removedAttrNames, function(name) { |
|
return from.removeAttribute(name); |
|
}); |
|
} |
|
function morphChildren(from, to) { |
|
var curToChild = to.firstChild; |
|
var curFromChild = from.firstChild; |
|
var toNextSibling; |
|
var fromNextSibling; |
|
outer: while (curToChild) { |
|
toNextSibling = curToChild.nextSibling; |
|
while (curFromChild) { |
|
fromNextSibling = curFromChild.nextSibling; |
|
var isCompatible = false; |
|
var curFromType = curFromChild.nodeType; |
|
var curToType = curToChild.nodeType; |
|
if (curFromType === curToType) { |
|
if (curFromType === ELEMENT_NODE) { |
|
if (curFromChild.nodeName === curToChild.nodeName) { |
|
isCompatible = true; |
|
morphEl(curFromChild, curToChild); |
|
} |
|
} else if ( |
|
curFromType === TEXT_NODE || |
|
curFromType === COMMENT_NODE |
|
) { |
|
isCompatible = true; |
|
if (curFromChild.nodeValue !== curToChild.nodeValue) { |
|
curFromChild.nodeValue = curToChild.nodeValue; |
|
} |
|
} |
|
} |
|
if (isCompatible) { |
|
curToChild = toNextSibling; |
|
curFromChild = fromNextSibling; |
|
continue outer; |
|
} |
|
from.removeChild(curFromChild); |
|
curFromChild = fromNextSibling; |
|
} |
|
from.appendChild(curToChild); |
|
curFromChild = fromNextSibling; |
|
curToChild = toNextSibling; |
|
} |
|
if (curFromChild) { |
|
while (curFromChild) { |
|
fromNextSibling = curFromChild.nextSibling; |
|
from.removeChild(curFromChild); |
|
curFromChild = fromNextSibling; |
|
} |
|
} |
|
} |
|
function moveChildren(from, to) { |
|
var curChild = from.firstChild; |
|
while (curChild) { |
|
var nextChild = curChild.nextSibling; |
|
to.appendChild(curChild); |
|
curChild = nextChild; |
|
} |
|
} |
|
|
|
module.exports = exports;
|
|
|