Remove replace option
This commit is contained in:
@@ -5,7 +5,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = "nl.astraeus"
|
||||
version = "0.2.6-SNAPSHOT"
|
||||
version = "0.3.0-SNAPSHOT"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
||||
@@ -3,7 +3,6 @@ package nl.astraeus.komp
|
||||
import kotlinx.browser.document
|
||||
import kotlinx.html.*
|
||||
import org.w3c.dom.*
|
||||
import org.w3c.dom.css.CSSStyleDeclaration
|
||||
import org.w3c.dom.events.Event
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
@@ -15,14 +14,11 @@ inline fun HTMLElement.setKompEvent(name: String, noinline callback: (Event) ->
|
||||
}
|
||||
addEventListener(eventName, callback, null)
|
||||
|
||||
if (Komponent.updateStrategy == UpdateStrategy.DOM_DIFF) {
|
||||
//asDynamic()[name] = callback
|
||||
val events: MutableList<String> = (asDynamic()[EVENT_PROPERTY] as? MutableList<String>) ?: mutableListOf()
|
||||
val events: MutableList<String> = (asDynamic()[EVENT_PROPERTY] as? MutableList<String>) ?: mutableListOf()
|
||||
|
||||
events.add(eventName)
|
||||
asDynamic()[EVENT_PROPERTY] = events
|
||||
asDynamic()["event-$eventName"] = callback
|
||||
}
|
||||
events.add(eventName)
|
||||
asDynamic()[EVENT_PROPERTY] = events
|
||||
asDynamic()["event-$eventName"] = callback
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
@@ -35,41 +31,16 @@ inline fun HTMLElement.removeKompEvent(name: String) {
|
||||
|
||||
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()
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
events.remove(eventName)
|
||||
asDynamic()["event-$eventName"] = null
|
||||
}
|
||||
|
||||
interface HtmlConsumer : TagConsumer<HTMLElement> {
|
||||
fun append(node: Node)
|
||||
}
|
||||
|
||||
fun HTMLElement.setStyles(cssStyle: CSSStyleDeclaration) {
|
||||
for (index in 0 until cssStyle.length) {
|
||||
val propertyName = cssStyle.item(index)
|
||||
|
||||
style.setProperty(propertyName, cssStyle.getPropertyValue(propertyName))
|
||||
}
|
||||
}
|
||||
|
||||
class HtmlBuilder(
|
||||
val komponent: Komponent,
|
||||
val document: Document,
|
||||
@@ -121,80 +92,23 @@ class HtmlBuilder(
|
||||
|
||||
val element = path.last()
|
||||
|
||||
if (Komponent.updateStrategy == UpdateStrategy.DOM_DIFF) {
|
||||
for (index in 0 until element.childNodes.length) {
|
||||
val child = element.childNodes[index]
|
||||
if (child is HTMLElement) {
|
||||
hash = hash * 37 + child.getKompHash()
|
||||
} else {
|
||||
hash = hash * 37 + (child?.textContent?.hashCode() ?: 0)
|
||||
}
|
||||
for (index in 0 until element.childNodes.length) {
|
||||
val child = element.childNodes[index]
|
||||
if (child is HTMLElement) {
|
||||
hash = hash * 37 + child.getKompHash()
|
||||
} else {
|
||||
hash = hash * 37 + (child?.textContent?.hashCode() ?: 0)
|
||||
}
|
||||
}
|
||||
|
||||
for ((key, value) in tag.attributesEntries) {
|
||||
if (key == "class") {
|
||||
val classes = value.split(Regex("\\s+"))
|
||||
val classNames = StringBuilder()
|
||||
element.setAttribute(key, value)
|
||||
|
||||
for (cls in classes) {
|
||||
val cssStyle = komponent.declaredStyles[cls]
|
||||
|
||||
if (cssStyle != null) {
|
||||
if (Komponent.updateStrategy == UpdateStrategy.DOM_DIFF) {
|
||||
hash = hash * 37 + cssStyle.hashCode()
|
||||
}
|
||||
|
||||
if (cls.endsWith(":hover")) {
|
||||
val oldOnMouseOver = element.onmouseover
|
||||
val oldOnMouseOut = element.onmouseout
|
||||
|
||||
element.onmouseover = {
|
||||
element.setStyles(cssStyle)
|
||||
|
||||
oldOnMouseOver?.invoke(it)
|
||||
}
|
||||
element.onmouseout = {
|
||||
cls.split(':').firstOrNull()?.let {
|
||||
komponent.declaredStyles[it]?.let { cssStyle ->
|
||||
element.setStyles(cssStyle)
|
||||
}
|
||||
}
|
||||
|
||||
oldOnMouseOut?.invoke(it)
|
||||
}
|
||||
} else {
|
||||
element.setStyles(cssStyle)
|
||||
}
|
||||
} else {
|
||||
if (Komponent.updateStrategy == UpdateStrategy.DOM_DIFF) {
|
||||
hash = hash * 37 + cls.hashCode()
|
||||
}
|
||||
|
||||
classNames.append(cls)
|
||||
classNames.append(" ")
|
||||
}
|
||||
}
|
||||
|
||||
element.className = classNames.toString()
|
||||
|
||||
if (Komponent.updateStrategy == UpdateStrategy.DOM_DIFF) {
|
||||
val key_value = "${key}-${classNames}"
|
||||
hash = hash * 37 + key_value.hashCode()
|
||||
}
|
||||
} else {
|
||||
element.setAttribute(key, value)
|
||||
|
||||
if (Komponent.updateStrategy == UpdateStrategy.DOM_DIFF) {
|
||||
val key_value = "${key}-${value}"
|
||||
hash = hash * 37 + key_value.hashCode()
|
||||
}
|
||||
}
|
||||
val key_value = "${key}-${value}"
|
||||
hash = hash * 37 + key_value.hashCode()
|
||||
}
|
||||
|
||||
if (Komponent.updateStrategy == UpdateStrategy.DOM_DIFF) {
|
||||
element.setKompHash(baseHash * 53 + hash)
|
||||
}
|
||||
element.setKompHash(baseHash * 53 + hash)
|
||||
lastLeaved = path.removeAt(path.lastIndex)
|
||||
}
|
||||
|
||||
|
||||
@@ -34,19 +34,7 @@ class StateDelegate<T>(
|
||||
inline fun <reified T> Komponent.state(initialValue: T): StateDelegate<T> = StateDelegate(this, initialValue)
|
||||
|
||||
fun HtmlConsumer.include(component: Komponent) {
|
||||
if (Komponent.updateStrategy == UpdateStrategy.REPLACE) {
|
||||
if (component.element != null) {
|
||||
component.update()
|
||||
} else {
|
||||
component.refresh()
|
||||
}
|
||||
|
||||
component.element?.also {
|
||||
append(it)
|
||||
}
|
||||
} else {
|
||||
append(component.create())
|
||||
}
|
||||
append(component.create())
|
||||
}
|
||||
|
||||
class DummyKomponent: Komponent() {
|
||||
@@ -57,11 +45,6 @@ class DummyKomponent: Komponent() {
|
||||
}
|
||||
}
|
||||
|
||||
enum class UpdateStrategy {
|
||||
REPLACE,
|
||||
DOM_DIFF
|
||||
}
|
||||
|
||||
abstract class Komponent {
|
||||
private var createIndex = getNextCreateIndex()
|
||||
private var dirty: Boolean = true
|
||||
@@ -121,39 +104,15 @@ abstract class Komponent {
|
||||
val newElement = create()
|
||||
|
||||
if (oldElement != null) {
|
||||
element = if (updateStrategy == UpdateStrategy.REPLACE) {
|
||||
if (logReplaceEvent) {
|
||||
console.log("Replacing", oldElement, newElement)
|
||||
}
|
||||
oldElement.parentNode?.replaceChild(newElement, oldElement)
|
||||
newElement
|
||||
} else {
|
||||
if (logReplaceEvent) {
|
||||
console.log("DomDiffing", oldElement, newElement)
|
||||
}
|
||||
DiffPatch.updateNode(oldElement, newElement)
|
||||
if (logReplaceEvent) {
|
||||
console.log("DomDiffing", oldElement, newElement)
|
||||
}
|
||||
element = DiffPatch.updateNode(oldElement, newElement)
|
||||
}
|
||||
|
||||
dirty = false
|
||||
}
|
||||
|
||||
@JsName("remove")
|
||||
fun remove() {
|
||||
check(updateStrategy == UpdateStrategy.REPLACE) {
|
||||
"remote only works with UpdateStrategy.REPLACE"
|
||||
}
|
||||
element?.let {
|
||||
val parent = it.parentElement ?: throw IllegalArgumentException("Element has no parent!?")
|
||||
|
||||
if (logReplaceEvent) {
|
||||
console.log("Remove", it)
|
||||
}
|
||||
|
||||
parent.removeChild(it)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var nextCreateIndex: Int = 1
|
||||
private var updateCallback: Int? = null
|
||||
@@ -161,7 +120,6 @@ abstract class Komponent {
|
||||
|
||||
var logRenderEvent = false
|
||||
var logReplaceEvent = false
|
||||
var updateStrategy = UpdateStrategy.DOM_DIFF
|
||||
|
||||
fun create(parent: HTMLElement, component: Komponent, insertAsFirst: Boolean = false) {
|
||||
val element = component.create()
|
||||
|
||||
Reference in New Issue
Block a user