Fixes
This commit is contained in:
@@ -5,7 +5,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "nl.astraeus"
|
group = "nl.astraeus"
|
||||||
version = "0.4.1"
|
version = "0.5.2"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
2
komp.iml
2
komp.iml
@@ -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$">
|
||||||
|
|||||||
6
komp.ipr
6
komp.ipr
@@ -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">
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user