v. 1.0.3 - Replace i.o. update DOM

Took 45 seconds
This commit is contained in:
2022-02-07 17:37:48 +01:00
parent a30b0e8684
commit 9a1d9ece25
3 changed files with 41 additions and 139 deletions

View File

@@ -40,14 +40,6 @@ fun Element.printTree(indent: Int = 0): String {
} }
result.append(") {") result.append(") {")
result.append("\n") result.append("\n")
for ((name, event) in getKompEvents()) {
result.append(indent.asSpaces())
result.append("on")
result.append(name)
result.append(" -> ")
result.append(event)
result.append("\n")
}
for (index in 0 until childNodes.length) { for (index in 0 until childNodes.length) {
childNodes[index]?.let { childNodes[index]?.let {
if (it is Element) { if (it is Element) {
@@ -65,65 +57,36 @@ fun Element.printTree(indent: Int = 0): String {
return result.toString() return result.toString()
} }
internal fun Element.clearKompAttributes() { internal fun Element.setKompAttribute(name: String, value: String?) {
val attributes = this.asDynamic()["komp-attributes"] as MutableSet<String>? // val setAttrs: MutableSet<String> = getKompAttributes()
// setAttrs.add(name)
//getNewAttributes().add(name)
if (attributes == null) { if (value == null || value.isBlank()) {
this.asDynamic()["komp-attributes"] = mutableSetOf<String>() if (this is HTMLInputElement) {
} else { checked = false
attributes.clear() } else {
} removeAttribute(name)
if (this is HTMLInputElement) {
this.checked = false
}
}
internal fun Element.getKompAttributes(): MutableSet<String> {
var result: MutableSet<String>? = this.asDynamic()["komp-attributes"] as MutableSet<String>?
if (result == null) {
result = mutableSetOf()
this.asDynamic()["komp-attributes"] = result
}
return result
}
internal fun Element.setKompAttribute(name: String, value: String) {
val setAttrs: MutableSet<String> = getKompAttributes()
setAttrs.add(name)
if (this is HTMLInputElement) {
when (name) {
"checked" -> {
this.checked = value == "checked"
}
"value" -> {
this.value = value
}
else -> {
setAttribute(name, value)
}
} }
} else if (this.getAttribute(name) != value) {
setAttribute(name, value)
}
}
internal fun Element.clearKompEvents() {
for ((name, event) in getKompEvents()) {
removeEventListener(name, event)
}
val events = this.asDynamic()["komp-events"] as MutableMap<String, (Event) -> Unit>?
if (events == null) {
this.asDynamic()["komp-events"] = mutableMapOf<String, (Event) -> Unit>()
} else { } else {
events.clear() if (this is HTMLInputElement) {
when (name) {
"checked" -> {
checked = "checked" == value
}
"class" -> {
className = value
}
"value" -> {
this.value = value
}
else -> {
setAttribute(name, value)
}
}
} else if (this.getAttribute(name) != value) {
setAttribute(name, value)
}
} }
} }
@@ -134,24 +97,9 @@ internal fun Element.setKompEvent(name: String, event: (Event) -> Unit) {
name name
} }
val events: MutableMap<String, (Event) -> Unit> = getKompEvents()
events[eventName]?.let {
println("Warn event '$eventName' already defined!")
removeEventListener(eventName, it)
}
events[eventName] = event
this.asDynamic()["komp-events"] = events
this.addEventListener(eventName, event) this.addEventListener(eventName, event)
} }
internal fun Element.getKompEvents(): MutableMap<String, (Event) -> Unit> {
return this.asDynamic()["komp-events"] ?: mutableMapOf()
}
internal fun Element.findElementIndex(): Int { internal fun Element.findElementIndex(): Int {
val childNodes = parentElement?.children val childNodes = parentElement?.children
if (childNodes != null) { if (childNodes != null) {
@@ -163,4 +111,4 @@ internal fun Element.findElementIndex(): Int {
} }
return 0 return 0
} }

View File

@@ -9,7 +9,6 @@ import kotlinx.html.TagConsumer
import kotlinx.html.Unsafe import kotlinx.html.Unsafe
import org.w3c.dom.Element import org.w3c.dom.Element
import org.w3c.dom.HTMLElement import org.w3c.dom.HTMLElement
import org.w3c.dom.HTMLInputElement
import org.w3c.dom.HTMLSpanElement import org.w3c.dom.HTMLSpanElement
import org.w3c.dom.Node import org.w3c.dom.Node
import org.w3c.dom.asList import org.w3c.dom.asList
@@ -143,15 +142,10 @@ class HtmlBuilder(
//logReplace"onTagStart, currentElement1.1: $currentNode") //logReplace"onTagStart, currentElement1.1: $currentNode")
currentPosition.currentParent().appendChild(currentNode!!) currentPosition.currentParent().appendChild(currentNode!!)
} else if ( } else {
!currentNode?.asElement()?.tagName.equals(tag.tagName, true) ||
(
tag.namespace != null &&
!currentNode?.asElement()?.namespaceURI.equals(tag.namespace, true)
)
) {
logReplace("onTagStart, currentElement, namespace: ${currentNode?.asElement()?.namespaceURI} -> ${tag.namespace}") logReplace("onTagStart, currentElement, namespace: ${currentNode?.asElement()?.namespaceURI} -> ${tag.namespace}")
logReplace("onTagStart, currentElement, replace: ${currentNode?.asElement()?.tagName} -> ${tag.tagName}") logReplace("onTagStart, currentElement, replace: ${currentNode?.asElement()?.tagName} -> ${tag.tagName}")
currentNode = if (tag.namespace != null) { currentNode = if (tag.namespace != null) {
document.createElementNS(tag.namespace, tag.tagName) document.createElementNS(tag.namespace, tag.tagName)
} else { } else {
@@ -159,9 +153,6 @@ class HtmlBuilder(
} }
currentPosition.replace(currentNode!!) currentPosition.replace(currentNode!!)
} else {
//logReplace"onTagStart, same node type")
} }
currentElement = currentNode as? Element ?: currentElement currentElement = currentNode as? Element ?: currentElement
@@ -172,11 +163,9 @@ class HtmlBuilder(
root = currentNode as Element root = currentNode as Element
} }
currentElement?.clearKompAttributes()
currentElement?.clearKompEvents()
for (entry in tag.attributesEntries) { for (entry in tag.attributesEntries) {
currentElement!!.setKompAttribute(entry.key.lowercase(), entry.value) val attributeName = entry.key.lowercase()
currentElement!!.setKompAttribute(attributeName, entry.value)
} }
if (tag.namespace != null) { if (tag.namespace != null) {
@@ -186,8 +175,6 @@ class HtmlBuilder(
} }
} }
//logReplace"onTagStart, currentElement2: $currentNode")
currentPosition.push(currentNode!!) currentPosition.push(currentNode!!)
} }
@@ -209,11 +196,9 @@ class HtmlBuilder(
checkTag(tag) checkTag(tag)
} }
if (value == null) { val attributeName = attribute.lowercase()
currentElement?.removeAttribute(attribute.lowercase())
} else { currentElement?.setKompAttribute(attributeName, value)
currentElement?.setKompAttribute(attribute.lowercase(), value)
}
} }
override fun onTagEvent(tag: Tag, event: String, value: (Event) -> Unit) { override fun onTagEvent(tag: Tag, event: String, value: (Event) -> Unit) {
@@ -243,41 +228,6 @@ class HtmlBuilder(
currentPosition.pop() currentPosition.pop()
if (currentElement != null) {
val setAttrs: List<String> = currentElement?.asDynamic()["komp-attributes"] ?: listOf()
// remove attributes that where not set
val element = currentElement
if (element?.hasAttributes() == true) {
for (index in 0 until element.attributes.length) {
val attr = element.attributes[index]
if (attr != null) {
if (element is HTMLElement && attr.name == "data-has-focus" && "true" == attr.value) {
element.focus()
}
if (attr.name != "style" && !setAttrs.contains(attr.name)) {
if (element is HTMLInputElement) {
if (attr.name == "checkbox") {
element.checked = false
} else if (attr.name == "value") {
element.value = ""
} else if (attr.name == "class") {
element.className = ""
}
} else {
if (Komponent.logReplaceEvent) {
console.log("Clear attribute [${attr.name}] on $element)")
}
element.removeAttribute(attr.name)
}
}
}
}
}
}
currentPosition.nextElement() currentPosition.nextElement()
currentElement = currentElement?.parentElement as? HTMLElement currentElement = currentElement?.parentElement as? HTMLElement

View File

@@ -1,9 +1,11 @@
package nl.astraeus.komp package nl.astraeus.komp
import kotlinx.browser.document import kotlinx.browser.document
import kotlinx.html.InputType
import kotlinx.html.div import kotlinx.html.div
import kotlinx.html.i import kotlinx.html.i
import kotlinx.html.id import kotlinx.html.id
import kotlinx.html.input
import kotlinx.html.js.onClickFunction import kotlinx.html.js.onClickFunction
import kotlinx.html.p import kotlinx.html.p
import kotlinx.html.span import kotlinx.html.span
@@ -50,6 +52,10 @@ class SimpleKomponent : Komponent() {
override fun HtmlBuilder.render() { override fun HtmlBuilder.render() {
div("div_class") { div("div_class") {
input(InputType.checkBox) {
name = "helloInput"
checked = hello
}
span { span {
svg { svg {
unsafe { unsafe {
@@ -61,8 +67,6 @@ class SimpleKomponent : Komponent() {
if (hello) { if (hello) {
div { div {
+"Hello" +"Hello"
throw IllegalStateException("Bloe")
} }
} else { } else {
span { span {