92 lines
3.0 KiB
Kotlin
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
|
|
}
|
|
}
|
|
|
|
}
|