Fix events, fix per komponent hash
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,4 @@
|
||||
# Created by .ignore support plugin (hsz.mobi)
|
||||
web/js/generated
|
||||
gradle.propertiesx
|
||||
gradle.properties
|
||||
local.properties
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
|
||||
plugins {
|
||||
kotlin("multiplatform") version "1.4.30"
|
||||
kotlin("multiplatform") version "1.4.32"
|
||||
`maven-publish`
|
||||
}
|
||||
|
||||
group = "nl.astraeus"
|
||||
version = "0.2.5-SNAPSHOT"
|
||||
version = "0.2.6-SNAPSHOT"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
||||
117
komp.ipr
117
komp.ipr
@@ -257,6 +257,10 @@
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/komp.iml" filepath="$PROJECT_DIR$/komp.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/komp.commonMain.iml" filepath="$PROJECT_DIR$/komp.commonMain.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/komp.commonTest.iml" filepath="$PROJECT_DIR$/komp.commonTest.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/komp.jsMain.iml" filepath="$PROJECT_DIR$/komp.jsMain.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/komp.jsTest.iml" filepath="$PROJECT_DIR$/komp.jsTest.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/komp_main.iml" filepath="$PROJECT_DIR$/komp_main.iml" group="komp" />
|
||||
<module fileurl="file://$PROJECT_DIR$/komp_test.iml" filepath="$PROJECT_DIR$/komp_test.iml" group="komp" />
|
||||
</modules>
|
||||
@@ -362,41 +366,130 @@
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
<component name="accountSettings">
|
||||
<option name="activeRegion" value="us-east-1" />
|
||||
<option name="recentlyUsedRegions">
|
||||
<list>
|
||||
<option value="us-east-1" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="libraries-with-intellij-classes">
|
||||
<option name="intellijApiContainingLibraries">
|
||||
<list>
|
||||
<LibraryCoordinatesState>
|
||||
<option name="artifactId" value="ideaIU" />
|
||||
<option name="groupId" value="com.jetbrains.intellij.idea" />
|
||||
</LibraryCoordinatesState>
|
||||
<LibraryCoordinatesState>
|
||||
<option name="artifactId" value="ideaIU" />
|
||||
<option name="groupId" value="com.jetbrains" />
|
||||
</LibraryCoordinatesState>
|
||||
<LibraryCoordinatesState>
|
||||
<option name="artifactId" value="ideaIC" />
|
||||
<option name="groupId" value="com.jetbrains.intellij.idea" />
|
||||
</LibraryCoordinatesState>
|
||||
<LibraryCoordinatesState>
|
||||
<option name="artifactId" value="ideaIC" />
|
||||
<option name="groupId" value="com.jetbrains" />
|
||||
</LibraryCoordinatesState>
|
||||
<LibraryCoordinatesState>
|
||||
<option name="artifactId" value="pycharmPY" />
|
||||
<option name="groupId" value="com.jetbrains.intellij.pycharm" />
|
||||
</LibraryCoordinatesState>
|
||||
<LibraryCoordinatesState>
|
||||
<option name="artifactId" value="pycharmPY" />
|
||||
<option name="groupId" value="com.jetbrains" />
|
||||
</LibraryCoordinatesState>
|
||||
<LibraryCoordinatesState>
|
||||
<option name="artifactId" value="pycharmPC" />
|
||||
<option name="groupId" value="com.jetbrains.intellij.pycharm" />
|
||||
</LibraryCoordinatesState>
|
||||
<LibraryCoordinatesState>
|
||||
<option name="artifactId" value="pycharmPC" />
|
||||
<option name="groupId" value="com.jetbrains" />
|
||||
</LibraryCoordinatesState>
|
||||
<LibraryCoordinatesState>
|
||||
<option name="artifactId" value="clion" />
|
||||
<option name="groupId" value="com.jetbrains.intellij.clion" />
|
||||
</LibraryCoordinatesState>
|
||||
<LibraryCoordinatesState>
|
||||
<option name="artifactId" value="clion" />
|
||||
<option name="groupId" value="com.jetbrains" />
|
||||
</LibraryCoordinatesState>
|
||||
<LibraryCoordinatesState>
|
||||
<option name="artifactId" value="riderRD" />
|
||||
<option name="groupId" value="com.jetbrains.intellij.rider" />
|
||||
</LibraryCoordinatesState>
|
||||
<LibraryCoordinatesState>
|
||||
<option name="artifactId" value="riderRD" />
|
||||
<option name="groupId" value="com.jetbrains" />
|
||||
</LibraryCoordinatesState>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="libraryTable">
|
||||
<library name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-common:1.3.70" type="kotlin.common">
|
||||
<library name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-common:1.4.30" type="kotlin.common">
|
||||
<CLASSES>
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.3.70/3fa8dd6c896d635e78201e5e811545f3846dec04/kotlin-stdlib-common-1.3.70.jar!/" />
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.4.30/bb9a3173350f55732416ee27956ea8f9b81f4dbb/kotlin-stdlib-common-1.4.30.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.3.70/6eefff69d45d17fb1b50591729853e9f6a15d09/kotlin-stdlib-common-1.3.70-sources.jar!/" />
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.4.30/9427471650876e86fdb0dd878f147ff15c57eac0/kotlin-stdlib-common-1.4.30-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-js:1.3.70" type="kotlin.js">
|
||||
<library name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-js:1.4.30" type="kotlin.js">
|
||||
<CLASSES>
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-js/1.3.70/41513becdc85a89799b74028a81c39c364ba3465/kotlin-stdlib-js-1.3.70.jar!/" />
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-js/1.4.30/6c66d1db9c724b087c3a6f37aecffd24d0b14f26/kotlin-stdlib-js-1.4.30.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-js/1.3.70/8b0cd54438c595bb7c2c5e1e4a77a61f0eb39af5/kotlin-stdlib-js-1.3.70-sources.jar!/" />
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-js/1.4.30/5729944dc91bf28689461fe44b9e401fd41a84a7/kotlin-stdlib-js-1.4.30-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Gradle: org.jetbrains.kotlinx:kotlinx-html-common:0.7.1" type="kotlin.common">
|
||||
<library name="Gradle: org.jetbrains.kotlin:kotlin-test-annotations-common:1.4.30" type="kotlin.common">
|
||||
<CLASSES>
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-html-common/0.7.1/26651a49fdc0e6abf8a61182b01d6bb0a6bb427e/kotlinx-html-common-0.7.1.jar!/" />
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test-annotations-common/1.4.30/e77a76b23fc3007baf57a9d3354fdd318fe1fa88/kotlin-test-annotations-common-1.4.30.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-html-common/0.7.1/5aba2eaa4e02d75d6e526900ee69d4e20a0d6d94/kotlinx-html-common-0.7.1-sources.jar!/" />
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test-annotations-common/1.4.30/57512e29ee20defe37d54ce19507d599b0f2113/kotlin-test-annotations-common-1.4.30-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Gradle: org.jetbrains.kotlinx:kotlinx-html-js:0.7.1" type="kotlin.js">
|
||||
<library name="Gradle: org.jetbrains.kotlin:kotlin-test-common:1.4.30" type="kotlin.common">
|
||||
<CLASSES>
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-html-js/0.7.1/f3a744916effcbe728d38e4bfd732f9694d18fa9/kotlinx-html-js-0.7.1.jar!/" />
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test-common/1.4.30/823ed87441680d1334a1f0d23781c0089e16c0a6/kotlin-test-common-1.4.30.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-html-js/0.7.1/435518751d3af45577f8af5f64c4850bc5989af2/kotlinx-html-js-0.7.1-sources.jar!/" />
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test-common/1.4.30/d1818d1bdc457b51289f006884a260b56a55cb77/kotlin-test-common-1.4.30-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Gradle: org.jetbrains.kotlin:kotlin-test-js:1.4.30" type="kotlin.js">
|
||||
<CLASSES>
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test-js/1.4.30/5b1cb1ec31a344f6aa1047d6cae3a268825cb724/kotlin-test-js-1.4.30.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test-js/1.4.30/8e70170db077d3f421c3fb6d24468b3938990f4a/kotlin-test-js-1.4.30-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Gradle: org.jetbrains.kotlinx:kotlinx-html-common:0.7.2" type="kotlin.common">
|
||||
<CLASSES>
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-html-common/0.7.2/7da838083337896b558cab2884c4118709a58769/kotlinx-html-metadata-0.7.2.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-html-common/0.7.2/866bbbfe0a81d49cdf19fd149adafbb938b35be4/kotlinx-html-common-0.7.2-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Gradle: org.jetbrains.kotlinx:kotlinx-html-js:0.7.2" type="kotlin.js">
|
||||
<CLASSES>
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-html-js/0.7.2/baf7e494e549776d0ae3e0ee225804a513f5dc26/kotlinx-html-jslegacy-0.7.2.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-html-js/0.7.2/b09bfd3565058174afa3fd0888743f8b8dca5406/kotlinx-html-js-0.7.2-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
<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-jsLegacy/src;/home/rnentjes/Development/komp/komp/build/externals/komp-jsIr/src;/home/rnentjes/Development/komp/komp/src/jsTest/kotlin;/home/rnentjes/Development/komp/komp/src/commonMain/kotlin">
|
||||
<dependsOnModuleNames>komp:commonTest</dependsOnModuleNames>
|
||||
<sourceSets>
|
||||
<sourceSet>komp.commonTest</sourceSet>
|
||||
<sourceSet>komp.jsMain</sourceSet>
|
||||
<sourceSet>komp.commonTest</sourceSet>
|
||||
<sourceSet>komp.commonMain</sourceSet>
|
||||
</sourceSets>
|
||||
<newMppModelJpsModuleKind>COMPILATION_AND_SOURCE_SET_HOLDER</newMppModelJpsModuleKind>
|
||||
|
||||
@@ -6,7 +6,7 @@ import org.w3c.dom.events.Event
|
||||
const val HASH_VALUE = "komp-hash-value"
|
||||
|
||||
//const val HASH_ATTRIBUTE = "data-komp-hash"
|
||||
const val EVENT_ATTRIBUTE = "data-komp-events"
|
||||
const val EVENT_PROPERTY = "komp-events"
|
||||
|
||||
fun Node.getKompHash(): Int = this.asDynamic()[HASH_VALUE] as? Int? ?: -1
|
||||
|
||||
@@ -32,6 +32,8 @@ object DiffPatch {
|
||||
oldNode is HTMLElement &&
|
||||
newNode is HTMLElement &&
|
||||
oldNode.nodeName == newNode.nodeName &&
|
||||
oldNode.getKompHash() != -1 &&
|
||||
newNode.getKompHash() != -1 &&
|
||||
oldNode.getKompHash() == newNode.getKompHash()
|
||||
)
|
||||
}
|
||||
@@ -81,10 +83,10 @@ object DiffPatch {
|
||||
if (Komponent.logReplaceEvent) {
|
||||
console.log("Update children", oldNode.nodeName, newNode.nodeName)
|
||||
}
|
||||
updateKomponentOnNode(oldNode, newNode)
|
||||
updateChildren(oldNode, newNode)
|
||||
oldNode.setKompHash(newNode.getKompHash())
|
||||
|
||||
updateKomponentOnNode(oldNode, newNode)
|
||||
return oldNode
|
||||
}
|
||||
}
|
||||
@@ -94,7 +96,6 @@ object DiffPatch {
|
||||
}
|
||||
|
||||
oldNode.parentNode?.replaceChild(newNode, oldNode)
|
||||
//replaceNode(oldNode, newNode)
|
||||
return newNode
|
||||
}
|
||||
|
||||
@@ -123,21 +124,8 @@ object DiffPatch {
|
||||
|
||||
if (newNode is HTMLInputElement && oldNode is HTMLInputElement) {
|
||||
oldNode.value = newNode.value
|
||||
oldNode.checked = newNode.checked
|
||||
}
|
||||
|
||||
/*
|
||||
for (index in 0 until newNode.attributes.length) {
|
||||
val attr = newNode.attributes[index]
|
||||
|
||||
if (attr != null) {
|
||||
val oldAttr = oldNode.attributes[attr.name]
|
||||
|
||||
if (oldAttr == null || oldAttr.value != attr.value) {
|
||||
oldNode.setAttribute(attr.name, attr.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
private fun updateChildren(oldNode: HTMLElement, newNode: HTMLElement) {
|
||||
@@ -278,86 +266,32 @@ object DiffPatch {
|
||||
}
|
||||
|
||||
private fun updateEvents(oldNode: HTMLElement, newNode: HTMLElement) {
|
||||
val oldEvents = mutableListOf<String>()
|
||||
oldEvents.addAll((oldNode.getAttribute(EVENT_ATTRIBUTE) ?: "").split(","))
|
||||
|
||||
val newEvents = (newNode.getAttribute(EVENT_ATTRIBUTE) ?: "").split(",")
|
||||
val oldEvents = (oldNode.asDynamic()[EVENT_PROPERTY] as? MutableList<String>) ?: mutableListOf()
|
||||
val newEvents = (newNode.asDynamic()[EVENT_PROPERTY] as? MutableList<String>) ?: mutableListOf()
|
||||
|
||||
if (Komponent.logReplaceEvent) {
|
||||
console.log("Update events", oldNode.getAttribute(EVENT_ATTRIBUTE), newNode.getAttribute(EVENT_ATTRIBUTE))
|
||||
}
|
||||
|
||||
for (event in newEvents) {
|
||||
if (event.isNotBlank()) {
|
||||
val oldNodeEvent = oldNode.asDynamic()["event-$event"]
|
||||
val newNodeEvent = newNode.asDynamic()["event-$event"]
|
||||
if (oldNodeEvent != null) {
|
||||
if (Komponent.logReplaceEvent) {
|
||||
console.log("Remove old event $event")
|
||||
}
|
||||
oldNode.removeEventListener(event, oldNodeEvent as ((Event) -> Unit), null)
|
||||
}
|
||||
if (newNodeEvent != null) {
|
||||
if (Komponent.logReplaceEvent) {
|
||||
console.log("Set event $event on", oldNode)
|
||||
}
|
||||
oldNode.setEvent(event, newNodeEvent as ((Event) -> Unit))
|
||||
}
|
||||
oldEvents.remove(event)
|
||||
}
|
||||
console.log("Update events", oldNode.getAttribute(EVENT_PROPERTY), newNode.getAttribute(EVENT_PROPERTY))
|
||||
}
|
||||
|
||||
for (event in oldEvents) {
|
||||
if (event.isNotBlank()) {
|
||||
val oldNodeEvent = oldNode.asDynamic()["event-$event"]
|
||||
if (oldNodeEvent != null) {
|
||||
oldNode.removeEventListener(event, oldNodeEvent as ((Event) -> Unit), null)
|
||||
oldNode.removeKompEvent(event)
|
||||
}
|
||||
|
||||
for (event in newEvents) {
|
||||
val newNodeEvent = newNode.asDynamic()["event-$event"]
|
||||
|
||||
if (newNodeEvent != null) {
|
||||
if (Komponent.logReplaceEvent) {
|
||||
console.log("Set event $event on", oldNode)
|
||||
}
|
||||
oldNode.setKompEvent(event, newNodeEvent as ((Event) -> Unit))
|
||||
}
|
||||
}
|
||||
|
||||
newNode.getAttribute(EVENT_ATTRIBUTE)?.also {
|
||||
oldNode.setAttribute(EVENT_ATTRIBUTE, it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun replaceNode(oldNode: Node, newNode: Node) {
|
||||
oldNode.parentNode?.also { parent ->
|
||||
val clone = newNode.cloneNode(true)
|
||||
cloneEvents(clone, newNode)
|
||||
parent.replaceChild(clone, oldNode)
|
||||
}
|
||||
}
|
||||
|
||||
private fun cloneEvents(destination: Node, source: Node) {
|
||||
if (source is HTMLElement && destination is HTMLElement) {
|
||||
val events = (source.getAttribute(EVENT_ATTRIBUTE) ?: "").split(",")
|
||||
for (event in events) {
|
||||
if (event.isNotBlank()) {
|
||||
if (Komponent.logReplaceEvent) {
|
||||
console.log("Clone event $event on", source)
|
||||
}
|
||||
|
||||
val foundEvent = source.asDynamic()["event-$event"]
|
||||
if (foundEvent != null) {
|
||||
if (Komponent.logReplaceEvent) {
|
||||
console.log("Clone add eventlistener", foundEvent)
|
||||
}
|
||||
destination.setEvent(event, foundEvent as ((Event) -> Unit))
|
||||
} else {
|
||||
if (Komponent.logReplaceEvent) {
|
||||
console.log("Event not found $event", source)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (index in 0 until source.childNodes.length) {
|
||||
destination.childNodes[index]?.also { destinationChild ->
|
||||
source.childNodes[index]?.also { sourceChild ->
|
||||
cloneEvents(destinationChild, sourceChild)
|
||||
}
|
||||
}
|
||||
if (newEvents.isEmpty()) {
|
||||
oldNode.asDynamic()[EVENT_PROPERTY] = null
|
||||
} else {
|
||||
oldNode.asDynamic()[EVENT_PROPERTY] = newNode.asDynamic()[EVENT_PROPERTY]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,29 +7,57 @@ import org.w3c.dom.css.CSSStyleDeclaration
|
||||
import org.w3c.dom.events.Event
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun HTMLElement.setEvent(name: String, noinline callback: (Event) -> Unit) {
|
||||
inline fun HTMLElement.setKompEvent(name: String, noinline callback: (Event) -> Unit) {
|
||||
val eventName = if (name.startsWith("on")) {
|
||||
name.substring(2)
|
||||
} else {
|
||||
name
|
||||
}
|
||||
addEventListener(eventName, callback, null)
|
||||
|
||||
if (Komponent.updateStrategy == UpdateStrategy.DOM_DIFF) {
|
||||
//asDynamic()[name] = callback
|
||||
val events = getAttribute(EVENT_ATTRIBUTE) ?: ""
|
||||
val events: MutableList<String> = (asDynamic()[EVENT_PROPERTY] as? MutableList<String>) ?: mutableListOf()
|
||||
|
||||
setAttribute(
|
||||
EVENT_ATTRIBUTE,
|
||||
if (events.isBlank()) {
|
||||
eventName
|
||||
} else {
|
||||
"$events,$eventName"
|
||||
}
|
||||
)
|
||||
events.add(eventName)
|
||||
asDynamic()[EVENT_PROPERTY] = events
|
||||
asDynamic()["event-$eventName"] = callback
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun HTMLElement.removeKompEvent(name: String) {
|
||||
val eventName = if (name.startsWith("on")) {
|
||||
name.substring(2)
|
||||
} else {
|
||||
name
|
||||
}
|
||||
|
||||
removeEventListener(eventName, asDynamic()["event-$eventName"] as ((Event) -> Unit), null)
|
||||
|
||||
if (Komponent.updateStrategy == UpdateStrategy.DOM_DIFF) {
|
||||
//asDynamic()[name] = callback
|
||||
val events: MutableList<String> = (asDynamic()[EVENT_PROPERTY] as? MutableList<String>) ?: mutableListOf()
|
||||
|
||||
events.remove(eventName)
|
||||
asDynamic()["event-$eventName"] = null
|
||||
}
|
||||
}
|
||||
|
||||
fun HTMLElement.clearEvents() {
|
||||
if (Komponent.updateStrategy == UpdateStrategy.DOM_DIFF) {
|
||||
//asDynamic()[name] = callback
|
||||
val events = getAttribute(EVENT_PROPERTY) ?: ""
|
||||
|
||||
for (eventName in events.split(",")) {
|
||||
if (eventName.isNotBlank()) {
|
||||
val event: (Event) -> Unit = asDynamic()["event-$eventName"]
|
||||
removeEventListener(eventName, event)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface HtmlConsumer : TagConsumer<HTMLElement> {
|
||||
fun append(node: Node)
|
||||
}
|
||||
@@ -43,8 +71,9 @@ fun HTMLElement.setStyles(cssStyle: CSSStyleDeclaration) {
|
||||
}
|
||||
|
||||
class HtmlBuilder(
|
||||
val komponent: Komponent,
|
||||
val document: Document
|
||||
val komponent: Komponent,
|
||||
val document: Document,
|
||||
val baseHash: Int
|
||||
) : HtmlConsumer {
|
||||
private val path = arrayListOf<HTMLElement>()
|
||||
private var lastLeaved: HTMLElement? = null
|
||||
@@ -80,7 +109,7 @@ class HtmlBuilder(
|
||||
when {
|
||||
path.isEmpty() -> throw IllegalStateException("No current tag")
|
||||
path.last().tagName.toLowerCase() != tag.tagName.toLowerCase() -> throw IllegalStateException("Wrong current tag")
|
||||
else -> path.last().setEvent(event, value)
|
||||
else -> path.last().setKompEvent(event, value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,13 +190,10 @@ class HtmlBuilder(
|
||||
hash = hash * 37 + key_value.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (Komponent.updateStrategy == UpdateStrategy.DOM_DIFF) {
|
||||
element.setKompHash(hash)
|
||||
//element.setAttribute(DiffPatch.HASH_ATTRIBUTE, hash.toString(16))
|
||||
element.setKompHash(baseHash * 53 + hash)
|
||||
}
|
||||
lastLeaved = path.removeAt(path.lastIndex)
|
||||
}
|
||||
@@ -221,7 +247,8 @@ class HtmlBuilder(
|
||||
|
||||
companion object {
|
||||
fun create(content: HtmlBuilder.() -> Unit): HTMLElement {
|
||||
val consumer = HtmlBuilder(DummyKomponent(), document)
|
||||
val komponent = DummyKomponent()
|
||||
val consumer = HtmlBuilder(komponent, document, komponent.hashCode())
|
||||
content.invoke(consumer)
|
||||
return consumer.finalize()
|
||||
}
|
||||
|
||||
@@ -70,8 +70,14 @@ abstract class Komponent {
|
||||
val declaredStyles: MutableMap<String, CSSStyleDeclaration> = HashMap()
|
||||
|
||||
open fun create(): HTMLElement {
|
||||
val consumer = HtmlBuilder(this, document)
|
||||
consumer.render()
|
||||
val consumer = HtmlBuilder(this, document, this.createIndex)
|
||||
try {
|
||||
consumer.render()
|
||||
} catch (e: Throwable) {
|
||||
println("Exception occurred in ${this::class.simpleName}.render() call!")
|
||||
|
||||
throw e
|
||||
}
|
||||
val result = consumer.finalize()
|
||||
|
||||
if (result.id.isBlank()) {
|
||||
@@ -188,9 +194,8 @@ abstract class Komponent {
|
||||
|
||||
todo.forEach { next ->
|
||||
val element = next.element
|
||||
console.log("update element", element)
|
||||
|
||||
if (element is HTMLElement) {
|
||||
console.log("by id", document.getElementById(element.id))
|
||||
if (document.getElementById(element.id) != null) {
|
||||
if (next.dirty) {
|
||||
if (logRenderEvent) {
|
||||
|
||||
Reference in New Issue
Block a user