80 lines
1.7 KiB
TypeScript
Raw Normal View History

2017-06-20 13:46:49 +00:00
export class Diff {
2017-06-26 01:57:29 +00:00
static childNodes(aRoot: Node, bRoot: Node) {
2017-06-21 16:44:20 +00:00
let aChild = [...aRoot.childNodes]
let bChild = [...bRoot.childNodes]
let numNodes = Math.max(aChild.length, bChild.length)
for(let i = 0; i < numNodes; i++) {
2017-06-26 01:57:29 +00:00
let a = aChild[i]
2017-06-21 16:44:20 +00:00
if(i >= bChild.length) {
aRoot.removeChild(a)
continue
}
2017-06-26 01:57:29 +00:00
let b = bChild[i]
2017-06-21 16:44:20 +00:00
if(i >= aChild.length) {
aRoot.appendChild(b)
continue
}
if(a.nodeName !== b.nodeName || a.nodeType !== b.nodeType) {
aRoot.replaceChild(b, a)
continue
}
2017-06-26 01:57:29 +00:00
if(a.nodeType === Node.TEXT_NODE) {
a.textContent = b.textContent
continue
}
2017-06-21 16:44:20 +00:00
if(a.nodeType === Node.ELEMENT_NODE) {
2017-06-26 01:57:29 +00:00
let elemA = a as HTMLElement
let elemB = b as HTMLElement
if(elemA.tagName === "IFRAME") {
2017-06-24 00:31:49 +00:00
continue
}
2017-06-21 16:44:20 +00:00
let removeAttributes: Attr[] = []
2017-06-26 01:57:29 +00:00
for(let x = 0; x < elemA.attributes.length; x++) {
let attrib = elemA.attributes[x]
2017-06-21 16:44:20 +00:00
if(attrib.specified) {
2017-06-26 01:57:29 +00:00
if(!elemB.hasAttribute(attrib.name)) {
2017-06-21 16:44:20 +00:00
removeAttributes.push(attrib)
}
}
}
for(let attr of removeAttributes) {
2017-06-26 01:57:29 +00:00
elemA.removeAttributeNode(attr)
2017-06-21 16:44:20 +00:00
}
2017-06-26 01:57:29 +00:00
for(let x = 0; x < elemB.attributes.length; x++) {
let attrib = elemB.attributes[x]
2017-06-21 16:44:20 +00:00
if(attrib.specified) {
2017-06-26 01:57:29 +00:00
elemA.setAttribute(attrib.name, elemB.getAttribute(attrib.name))
2017-06-21 16:44:20 +00:00
}
}
2017-06-24 00:10:04 +00:00
// Special case: Apply state of input elements
2017-06-26 01:57:29 +00:00
if(elemA !== document.activeElement && elemA instanceof HTMLInputElement && elemB instanceof HTMLInputElement) {
elemA.value = elemB.value
2017-06-24 00:10:04 +00:00
}
2017-06-21 16:44:20 +00:00
}
Diff.childNodes(a, b)
}
}
static innerHTML(aRoot: HTMLElement, html: string) {
let bRoot = document.createElement("main")
bRoot.innerHTML = html
2017-06-24 00:10:04 +00:00
2017-06-21 16:44:20 +00:00
Diff.childNodes(aRoot, bRoot)
2017-06-20 13:46:49 +00:00
}
}