Files
kotlin-komponent/src/main/kotlin/nl/astraeus/komp/DomDiff.kt
2018-09-19 15:23:49 +02:00

92 lines
3.0 KiB
Kotlin

package nl.astraeus.komp
import org.w3c.dom.Node
import org.w3c.dom.get
/**
* User: rnentjes
* Date: 10-9-17
* Time: 13:33
*/
object DomDiffer {
fun replaceDiff(oldElement: KompElement, newElement: KompElement, element: Node): Node {
if (oldElement.isKomponent() && newElement.isKomponent()) {
if (oldElement.equals(newElement)) {
newElement.komponent?.update()
return newElement.komponent?.element ?: newElement.komponent?.create()?.create()
?: throw IllegalStateException("Unable to create new element!")
} else {
return Komponent.replaceNode(newElement, element)
}
} else if (!oldElement.isKomponent() && newElement.isKomponent()) {
return Komponent.replaceNode(newElement, element)
} else if (!oldElement.equals(newElement)) {
return Komponent.replaceNode(newElement, element)
} else {
if (oldElement.children == null && newElement.children != null) {
for (index in 0 until newElement.children.size) {
Komponent.appendElement(element, newElement.children[index])
}
} else if (oldElement.children != null && newElement.children == null) {
while (element.firstChild != null) {
if (Komponent.logReplaceEvent) {
console.log("Remove", element.firstChild)
}
element.removeChild(element.firstChild!!)
}
} else if (oldElement.children != null && newElement.children != null) {
if (oldElement.children.size > newElement.children.size) {
val toRemove = oldElement.children.size - newElement.children.size
var removed = 0
var index = 0
while (index < newElement.children.size) {
val childNode = element.childNodes[index]
if (childNode == null) {
println("Warn childNode is null!")
} else {
if ((!oldElement.children[index + removed].equals(newElement.children[index])) && removed < toRemove) {
if (Komponent.logReplaceEvent) {
console.log("Remove", oldElement.children[index + removed], newElement.children[index])
}
element.removeChild(childNode)
removed++
} else {
replaceDiff(oldElement.children[index + removed], newElement.children[index], childNode)
index++
}
}
}
while (removed < toRemove) {
element.lastChild?.also {
Komponent.removeElement(it)
}
removed++
}
} else {
for (index in 0 until newElement.children.size) {
val childNode = element.childNodes[index]
if (childNode == null) {
Komponent.appendElement(element, newElement.children[index])
} else {
replaceDiff(oldElement.children[index], newElement.children[index], childNode)
}
}
}
}
return element
}
}
}