This commit is contained in:
2021-07-11 13:29:34 +02:00
parent 48708580ca
commit dac465a161
10 changed files with 169 additions and 75 deletions

View File

@@ -5,7 +5,7 @@ plugins {
} }
group = "nl.astraeus" group = "nl.astraeus"
version = "0.4.1" version = "0.5.2"
repositories { repositories {
mavenCentral() mavenCentral()

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="komp:commonMain" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.type="sourceSet" external.system.module.version="0.4.1" type="JAVA_MODULE" version="4"> <module external.linked.project.id="komp:commonMain" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.type="sourceSet" external.system.module.version="0.5.1" type="JAVA_MODULE" version="4">
<component name="FacetManager"> <component name="FacetManager">
<facet type="kotlin-language" name="Kotlin"> <facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="Common (experimental) " allPlatforms="JS []/JVM [1.6]/Native []/Native [general]" useProjectSettings="false" isTestModule="false" externalProjectId="komp" pureKotlinSourceFolders="$MODULE_DIR$/src/jsMain/kotlin;/home/rnentjes/Development/komp/komp/build/externals/komp-js-legacy/src;/home/rnentjes/Development/komp/komp/build/externals/komp-js-ir/src;/home/rnentjes/Development/komp/komp/src/jsTest/kotlin"> <configuration version="3" platform="Common (experimental) " allPlatforms="JS []/JVM [1.8]/Native []/Native [general]" useProjectSettings="false" isTestModule="false" externalProjectId="komp" pureKotlinSourceFolders="$MODULE_DIR$/src/jsMain/kotlin;/home/rnentjes/Development/komp/komp/build/externals/komp-js-legacy/src;/home/rnentjes/Development/komp/komp/build/externals/komp-js-ir/src;/home/rnentjes/Development/komp/komp/src/jsTest/kotlin">
<newMppModelJpsModuleKind>SOURCE_SET_HOLDER</newMppModelJpsModuleKind> <newMppModelJpsModuleKind>SOURCE_SET_HOLDER</newMppModelJpsModuleKind>
<compilerSettings /> <compilerSettings />
<compilerArguments> <compilerArguments>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="komp:commonTest" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.type="sourceSet" external.system.module.version="0.4.1" type="JAVA_MODULE" version="4"> <module external.linked.project.id="komp:commonTest" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.type="sourceSet" external.system.module.version="0.5.1" type="JAVA_MODULE" version="4">
<component name="FacetManager"> <component name="FacetManager">
<facet type="kotlin-language" name="Kotlin"> <facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="Common (experimental) " allPlatforms="JS []/JVM [1.6]/Native []/Native [general]" useProjectSettings="false" isTestModule="true" externalProjectId="komp" pureKotlinSourceFolders="$MODULE_DIR$/src/jsMain/kotlin;/home/rnentjes/Development/komp/komp/build/externals/komp-js-legacy/src;/home/rnentjes/Development/komp/komp/build/externals/komp-js-ir/src;/home/rnentjes/Development/komp/komp/src/jsTest/kotlin"> <configuration version="3" platform="Common (experimental) " allPlatforms="JS []/JVM [1.8]/Native []/Native [general]" useProjectSettings="false" isTestModule="true" externalProjectId="komp" pureKotlinSourceFolders="$MODULE_DIR$/src/jsMain/kotlin;/home/rnentjes/Development/komp/komp/build/externals/komp-js-legacy/src;/home/rnentjes/Development/komp/komp/build/externals/komp-js-ir/src;/home/rnentjes/Development/komp/komp/src/jsTest/kotlin">
<newMppModelJpsModuleKind>SOURCE_SET_HOLDER</newMppModelJpsModuleKind> <newMppModelJpsModuleKind>SOURCE_SET_HOLDER</newMppModelJpsModuleKind>
<externalSystemTestTasks> <externalSystemTestTasks>
<externalSystemTestTask>jsLegacyBrowserTest|komp:jsTest|jsLegacy</externalSystemTestTask> <externalSystemTestTask>jsLegacyBrowserTest|komp:jsTest|jsLegacy</externalSystemTestTask>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="komp" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.version="0.4.1" type="JAVA_MODULE" version="4"> <module external.linked.project.id="komp" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.version="0.5.1" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true"> <component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">

View File

@@ -73,6 +73,12 @@
<element id="module-output" name="komp.jsMain" /> <element id="module-output" name="komp.jsMain" />
</root> </root>
</artifact> </artifact>
<artifact type="jar" name="komp-jslegacy-0.5.1">
<output-path>$PROJECT_DIR$/build/libs</output-path>
<root id="archive" name="komp-jslegacy-0.5.1.jar">
<element id="module-output" name="komp.jsMain" />
</root>
</artifact>
</component> </component>
<component name="CheckStyle-IDEA"> <component name="CheckStyle-IDEA">
<option name="configuration"> <option name="configuration">

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="komp:jsMain" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.type="sourceSet" external.system.module.version="0.4.1" type="JAVA_MODULE" version="4"> <module external.linked.project.id="komp:jsMain" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.type="sourceSet" external.system.module.version="0.5.1" type="JAVA_MODULE" version="4">
<component name="FacetManager"> <component name="FacetManager">
<facet type="kotlin-language" name="Kotlin"> <facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="JavaScript " allPlatforms="JS []" useProjectSettings="false" isTestModule="false" externalProjectId="komp" pureKotlinSourceFolders="$MODULE_DIR$/src/jsMain/kotlin;/home/rnentjes/Development/komp/komp/build/externals/komp-js-legacy/src;/home/rnentjes/Development/komp/komp/build/externals/komp-js-ir/src;/home/rnentjes/Development/komp/komp/src/jsTest/kotlin"> <configuration version="3" platform="JavaScript " allPlatforms="JS []" useProjectSettings="false" isTestModule="false" externalProjectId="komp" pureKotlinSourceFolders="$MODULE_DIR$/src/jsMain/kotlin;/home/rnentjes/Development/komp/komp/build/externals/komp-js-legacy/src;/home/rnentjes/Development/komp/komp/build/externals/komp-js-ir/src;/home/rnentjes/Development/komp/komp/src/jsTest/kotlin">

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="komp:jsTest" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.type="sourceSet" external.system.module.version="0.4.1" type="JAVA_MODULE" version="4"> <module external.linked.project.id="komp:jsTest" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.type="sourceSet" external.system.module.version="0.5.1" type="JAVA_MODULE" version="4">
<component name="FacetManager"> <component name="FacetManager">
<facet type="kotlin-language" name="Kotlin"> <facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="JavaScript " allPlatforms="JS []" useProjectSettings="false" isTestModule="true" externalProjectId="komp" pureKotlinSourceFolders="$MODULE_DIR$/src/jsMain/kotlin;/home/rnentjes/Development/komp/komp/build/externals/komp-js-legacy/src;/home/rnentjes/Development/komp/komp/build/externals/komp-js-ir/src;/home/rnentjes/Development/komp/komp/src/jsTest/kotlin"> <configuration version="3" platform="JavaScript " allPlatforms="JS []" useProjectSettings="false" isTestModule="true" externalProjectId="komp" pureKotlinSourceFolders="$MODULE_DIR$/src/jsMain/kotlin;/home/rnentjes/Development/komp/komp/build/externals/komp-js-legacy/src;/home/rnentjes/Development/komp/komp/build/externals/komp-js-ir/src;/home/rnentjes/Development/komp/komp/src/jsTest/kotlin">

View File

@@ -9,6 +9,7 @@ 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
@@ -20,6 +21,7 @@ private var currentElement: Element? = null
interface HtmlConsumer : TagConsumer<Element> { interface HtmlConsumer : TagConsumer<Element> {
fun append(node: Element) fun append(node: Element)
fun include(komponent: Komponent) fun include(komponent: Komponent)
fun debug(block: HtmlConsumer.() -> Unit)
} }
fun Int.asSpaces(): String { fun Int.asSpaces(): String {
@@ -30,7 +32,8 @@ fun Int.asSpaces(): String {
return result.toString() return result.toString()
} }
fun FlowOrMetaDataOrPhrasingContent.currentElement(): Element = (currentElement as? Element) ?: error("No current element defined!") fun FlowOrMetaDataOrPhrasingContent.currentElement(): Element =
currentElement ?: error("No current element defined!")
fun Element.printTree(indent: Int = 0): String { fun Element.printTree(indent: Int = 0): String {
val result = StringBuilder() val result = StringBuilder()
@@ -83,15 +86,25 @@ fun Element.printTree(indent: Int = 0): String {
return result.toString() return result.toString()
} }
fun Element.clearKompAttributes() { private fun Element.clearKompAttributes() {
this.asDynamic()["komp-attributes"] = mutableListOf<String>() val attributes = this.asDynamic()["komp-attributes"] as MutableSet<String>?
if (attributes == null) {
this.asDynamic()["komp-attributes"] = mutableSetOf<String>()
} else {
attributes.clear()
}
if (this is HTMLInputElement) {
this.checked = false
}
} }
fun Element.getKompAttributes(): MutableList<String> { private fun Element.getKompAttributes(): MutableSet<String> {
var result: MutableList<String>? = this.asDynamic()["komp-attributes"] as MutableList<String>? var result: MutableSet<String>? = this.asDynamic()["komp-attributes"] as MutableSet<String>?
if (result == null) { if (result == null) {
result = mutableListOf() result = mutableSetOf()
this.asDynamic()["komp-attributes"] = result this.asDynamic()["komp-attributes"] = result
} }
@@ -99,28 +112,43 @@ fun Element.getKompAttributes(): MutableList<String> {
return result return result
} }
fun Element.setKompAttribute(name: String, value: String) { private fun Element.setKompAttribute(name: String, value: String) {
val setAttrs: MutableList<String> = getKompAttributes() val setAttrs: MutableSet<String> = getKompAttributes()
setAttrs.add(name) setAttrs.add(name)
if (this.getAttribute(name) != value) { if (this is HTMLInputElement) {
if (Komponent.logReplaceEvent) { when (name) {
console.log("Setting attribute [$name,$value] on $this (old: ${this.getAttribute(name)})") "checked" -> {
} this.checked = value == "checked"
}
"value" -> {
this.value = value
}
else -> {
setAttribute(name, value)
}
}
} else if (this.getAttribute(name) != value) {
setAttribute(name, value) setAttribute(name, value)
} }
} }
fun Element.clearKompEvents() { private fun Element.clearKompEvents() {
for ((name, event) in getKompEvents()) { for ((name, event) in getKompEvents()) {
currentElement?.removeEventListener(name, event) currentElement?.removeEventListener(name, event)
} }
this.asDynamic()["komp-events"] = mutableMapOf<String, (Event) -> Unit>() val events = this.asDynamic()["komp-events"] as MutableMap<String, (Event) -> Unit>?
if (events == null) {
this.asDynamic()["komp-events"] = mutableMapOf<String, (Event) -> Unit>()
} else {
events.clear()
}
} }
fun Element.setKompEvent(name: String, event: (Event) -> Unit) { private fun Element.setKompEvent(name: String, event: (Event) -> Unit) {
val eventName: String = if (name.startsWith("on")) { val eventName: String = if (name.startsWith("on")) {
name.substring(2) name.substring(2)
} else { } else {
@@ -138,23 +166,19 @@ fun Element.setKompEvent(name: String, event: (Event) -> Unit) {
this.asDynamic()["komp-events"] = events this.asDynamic()["komp-events"] = events
if (Komponent.logReplaceEvent) {
console.log("Setting events [$eventName] on $this")
}
this.addEventListener(eventName, event) this.addEventListener(eventName, event)
} }
fun Element.getKompEvents(): MutableMap<String, (Event) -> Unit> { private fun Element.getKompEvents(): MutableMap<String, (Event) -> Unit> {
return this.asDynamic()["komp-events"] ?: mutableMapOf() return this.asDynamic()["komp-events"] ?: mutableMapOf()
} }
data class ElementIndex( private data class ElementIndex(
val parent: Node, val parent: Node,
var childIndex: Int var childIndex: Int
) )
fun ArrayList<ElementIndex>.currentParent(): Node { private fun ArrayList<ElementIndex>.currentParent(): Node {
this.lastOrNull()?.let { this.lastOrNull()?.let {
return it.parent return it.parent
} }
@@ -162,7 +186,7 @@ fun ArrayList<ElementIndex>.currentParent(): Node {
throw IllegalStateException("currentParent should never be null!") throw IllegalStateException("currentParent should never be null!")
} }
fun ArrayList<ElementIndex>.currentElement(): Node? { private fun ArrayList<ElementIndex>.currentElement(): Node? {
this.lastOrNull()?.let { this.lastOrNull()?.let {
return it.parent.childNodes[it.childIndex] return it.parent.childNodes[it.childIndex]
} }
@@ -170,21 +194,21 @@ fun ArrayList<ElementIndex>.currentElement(): Node? {
return null return null
} }
fun ArrayList<ElementIndex>.nextElement() { private fun ArrayList<ElementIndex>.nextElement() {
this.lastOrNull()?.let { this.lastOrNull()?.let {
it.childIndex++ it.childIndex++
} }
} }
fun ArrayList<ElementIndex>.pop() { private fun ArrayList<ElementIndex>.pop() {
this.removeLast() this.removeLast()
} }
fun ArrayList<ElementIndex>.push(element: Node) { private fun ArrayList<ElementIndex>.push(element: Node) {
this.add(ElementIndex(element, 0)) this.add(ElementIndex(element, 0))
} }
fun ArrayList<ElementIndex>.replace(new: Node) { private fun ArrayList<ElementIndex>.replace(new: Node) {
if (this.currentElement() != null) { if (this.currentElement() != null) {
this.currentElement()?.parentElement?.replaceChild(new, this.currentElement()!!) this.currentElement()?.parentElement?.replaceChild(new, this.currentElement()!!)
} else { } else {
@@ -192,22 +216,22 @@ fun ArrayList<ElementIndex>.replace(new: Node) {
} }
} }
fun Node.asElement() = this as? HTMLElement private fun Node.asElement() = this as? HTMLElement
class HtmlBuilder( class HtmlBuilder(
val parent: Element, val parent: Element,
var childIndex: Int = 0 var childIndex: Int = 0
) : HtmlConsumer { ) : HtmlConsumer {
private var currentPosition = arrayListOf<ElementIndex>() private var currentPosition = arrayListOf<ElementIndex>()
private var inDebug = false
var currentNode: Node? = null var currentNode: Node? = null
var root: Element? = null var root: Element? = null
val currentAttributes: MutableMap<String, String> = mutableMapOf()
init { init {
currentPosition.add(ElementIndex(parent, childIndex)) currentPosition.add(ElementIndex(parent, childIndex))
} }
constructor(position: ElementIndex) : this(position.parent as Element, position.childIndex)
override fun include(komponent: Komponent) { override fun include(komponent: Komponent) {
komponent.create( komponent.create(
currentPosition.last().parent as Element, currentPosition.last().parent as Element,
@@ -221,8 +245,18 @@ class HtmlBuilder(
currentPosition.nextElement() currentPosition.nextElement()
} }
override fun debug(block: HtmlConsumer.() -> Unit) {
inDebug = true
try {
block.invoke(this)
} finally {
inDebug = false
}
}
fun logReplace(msg: String) { fun logReplace(msg: String) {
if (Komponent.logReplaceEvent) { if (Komponent.logReplaceEvent && inDebug) {
console.log(msg) console.log(msg)
} }
} }
@@ -251,9 +285,9 @@ class HtmlBuilder(
//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) as Element document.createElementNS(tag.namespace, tag.tagName)
} else { } else {
document.createElement(tag.tagName) as Element document.createElement(tag.tagName)
} }
currentPosition.replace(currentNode!!) currentPosition.replace(currentNode!!)
@@ -273,7 +307,7 @@ class HtmlBuilder(
currentElement?.clearKompEvents() currentElement?.clearKompEvents()
for (entry in tag.attributesEntries) { for (entry in tag.attributesEntries) {
currentElement!!.setKompAttribute(entry.key, entry.value) currentElement!!.setKompAttribute(entry.key.lowercase(), entry.value)
} }
} }
@@ -294,13 +328,14 @@ class HtmlBuilder(
} }
override fun onTagAttributeChange(tag: Tag, attribute: String, value: String?) { override fun onTagAttributeChange(tag: Tag, attribute: String, value: String?) {
//logReplace"onTagAttributeChange, ${tag.tagName} [$attribute, $value]") logReplace("onTagAttributeChange, ${tag.tagName} [$attribute, $value]")
checkTag(tag) checkTag(tag)
if (value == null) { if (value == null) {
currentElement?.removeAttribute(attribute) currentElement?.removeAttribute(attribute.lowercase())
} else { } else {
currentElement?.setKompAttribute(attribute, value) currentElement?.setKompAttribute(attribute.lowercase(), value)
} }
} }
@@ -309,37 +344,46 @@ class HtmlBuilder(
checkTag(tag) checkTag(tag)
currentElement?.setKompEvent(event, value) currentElement?.setKompEvent(event.lowercase(), value)
} }
override fun onTagEnd(tag: Tag) { override fun onTagEnd(tag: Tag) {
//logReplace"onTagEnd: ${tag.tagName}, $currentElement")
//logReplace"onTagEnd: ${tag.tagName}, $currentPosition")
while (currentPosition.currentElement() != null) { while (currentPosition.currentElement() != null) {
currentPosition.currentElement()?.let { currentPosition.currentElement()?.let {
//logReplace"Removing $it")
it.parentElement?.removeChild(it) it.parentElement?.removeChild(it)
} }
} }
checkTag(tag) checkTag(tag)
//logReplace"onTagEnd, pre-pop: $currentPosition")
currentPosition.pop() currentPosition.pop()
//logReplace"onTagEnd, post-pop: $currentPosition")
val setAttrs: List<String> = currentElement.asDynamic()["komp-attributes"] ?: listOf() val setAttrs: List<String> = currentElement.asDynamic()["komp-attributes"] ?: listOf()
// remove attributes that where not set // remove attributes that where not set
if (currentElement?.hasAttributes() == true) { val element = currentElement
for (index in 0 until (currentElement?.attributes?.length ?: 0)) { if (element?.hasAttributes() == true) {
val attr = currentElement?.attributes?.get(index) for (index in 0 until element.attributes.length) {
val attr = element.attributes[index]
if (attr != null) { if (attr != null) {
if (element is HTMLElement && attr.name == "data-has-focus" && "true" == attr.value) {
element.focus()
}
if (!setAttrs.contains(attr.name)) { if (!setAttrs.contains(attr.name)) {
currentElement?.removeAttribute(attr.name) if (element is HTMLInputElement) {
if (attr.name == "checkbox") {
element.checked = false
} else if (attr.name == "value") {
element.value = ""
}
} else {
if (Komponent.logReplaceEvent) {
console.log("Clear attribute [${attr.name}] on $element)")
}
element.removeAttribute(attr.name)
}
} }
} }
} }
@@ -360,8 +404,10 @@ class HtmlBuilder(
} }
//logReplace"Tag content: $content") //logReplace"Tag content: $content")
if (
if (currentElement?.textContent != content.toString()) { currentElement?.nodeType != Node.TEXT_NODE ||
currentElement?.textContent != content.toString()
) {
currentElement?.textContent = content.toString() currentElement?.textContent = content.toString()
} }
@@ -376,7 +422,7 @@ class HtmlBuilder(
} }
val s = document.createElement("span") as HTMLSpanElement val s = document.createElement("span") as HTMLSpanElement
s.innerText = entity.text s.innerHTML = entity.text
currentPosition.replace( currentPosition.replace(
s.childNodes.asList().firstOrNull() ?: document.createTextNode(entity.text) s.childNodes.asList().firstOrNull() ?: document.createTextNode(entity.text)
) )

View File

@@ -1,7 +1,6 @@
package nl.astraeus.komp package nl.astraeus.komp
import kotlinx.browser.window import kotlinx.browser.window
import kotlinx.html.div
import org.w3c.dom.Element import org.w3c.dom.Element
import org.w3c.dom.HTMLElement import org.w3c.dom.HTMLElement
import org.w3c.dom.Node import org.w3c.dom.Node
@@ -29,14 +28,6 @@ class StateDelegate<T>(
inline fun <reified T> Komponent.state(initialValue: T): StateDelegate<T> = StateDelegate(this, initialValue) inline fun <reified T> Komponent.state(initialValue: T): StateDelegate<T> = StateDelegate(this, initialValue)
class DummyKomponent : Komponent() {
override fun HtmlBuilder.render() {
div {
+"dummy"
}
}
}
enum class UnsafeMode { enum class UnsafeMode {
UNSAFE_ALLOWED, UNSAFE_ALLOWED,
UNSAFE_DISABLED, UNSAFE_DISABLED,
@@ -50,12 +41,15 @@ abstract class Komponent {
var element: Node? = null var element: Node? = null
val declaredStyles: MutableMap<String, CSSStyleDeclaration> = HashMap() val declaredStyles: MutableMap<String, CSSStyleDeclaration> = HashMap()
open fun create(parent: Element, childIndex: Int = 0) { open fun create(parent: Element, childIndex: Int? = null) {
//parent.parentElement?.child val builder = HtmlBuilder(
val builder = HtmlBuilder(parent, childIndex) parent,
childIndex ?: parent.childElementCount
)
builder.render() builder.render()
element = builder.root element = builder.root
onAfterUpdate()
} }
abstract fun HtmlBuilder.render() abstract fun HtmlBuilder.render()
@@ -63,7 +57,7 @@ abstract class Komponent {
/** /**
* This method is called after the Komponent is updated * This method is called after the Komponent is updated
* *
* note: it's not called at first render * note: it's also called at first render
*/ */
open fun onAfterUpdate() {} open fun onAfterUpdate() {}
@@ -173,7 +167,7 @@ abstract class Komponent {
} }
} }
} else { } else {
console.log("Komponent element is null", next) console.log("Komponent element is null", next, element)
} }
} }
} }

View File

@@ -2,6 +2,7 @@ package nl.astraeus.komp
import kotlinx.browser.document import kotlinx.browser.document
import kotlinx.html.div import kotlinx.html.div
import kotlinx.html.i
import kotlinx.html.id import kotlinx.html.id
import kotlinx.html.js.onClickFunction import kotlinx.html.js.onClickFunction
import kotlinx.html.p import kotlinx.html.p
@@ -103,8 +104,55 @@ class SimpleKomponent : Komponent() {
} }
class ReplaceKomponent : Komponent() {
var includeSpan = true
override fun HtmlBuilder.render() {
div {
+"Child 2"
div {
if (includeSpan) {
span {
i("fas fa-eye") {
+"span1"
}
}
span {
i("fas fa-eye") {
+"span2"
}
}
span {
i("fas fa-eye") {
+"span3"
}
}
}
}
}
}
}
class TestUpdate { class TestUpdate {
@Test
fun testUpdateWithEmpty() {
val div = document.createElement("div") as HTMLDivElement
val rk = ReplaceKomponent()
Komponent.logRenderEvent = true
Komponent.create(div, rk)
println("ReplaceKomponent: ${div.printTree()}")
rk.includeSpan = false
rk.requestImmediateUpdate()
println("ReplaceKomponent: ${div.printTree()}")
}
@Test @Test
fun testSimpleKomponent() { fun testSimpleKomponent() {
val sk = SimpleKomponent() val sk = SimpleKomponent()