diff --git a/build.gradle.kts b/build.gradle.kts index 9c7ba05..d53dfef 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,7 +11,7 @@ plugins { } group = "nl.astraeus" -version = "1.2.9" +version = "1.2.10" repositories { mavenCentral() diff --git a/src/jsMain/kotlin/nl/astraeus/komp/ElementExtentions.kt b/src/jsMain/kotlin/nl/astraeus/komp/ElementExtentions.kt index 87a36b4..6573a9c 100644 --- a/src/jsMain/kotlin/nl/astraeus/komp/ElementExtentions.kt +++ b/src/jsMain/kotlin/nl/astraeus/komp/ElementExtentions.kt @@ -40,14 +40,6 @@ fun Element.printTree(indent: Int = 0): String { } result.append(") {") 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) { childNodes[index]?.let { if (it is Element) { @@ -65,55 +57,52 @@ fun Element.printTree(indent: Int = 0): String { return result.toString() } -internal fun Element.setKompAttribute(attributeName: String, value: String?) { - //val attributeName = name.lowercase() - if (value == null || value.isBlank()) { - if (this is HTMLInputElement) { - when (attributeName) { - "checked" -> { - checked = false - } - "class" -> { - className = "" - } - "value" -> { - this.value = "" - } - else -> { - removeAttribute(attributeName) - } +internal fun Element.setKompAttribute(attributeName: String, value: String) { + if (this is HTMLInputElement) { + when (attributeName) { + "checked" -> { + checked = "checked" == value } - } else { - removeAttribute(attributeName) - } - } else { - if (this is HTMLInputElement) { - when (attributeName) { - "checked" -> { - checked = "checked" == value - } - "class" -> { - className = value - } - "value" -> { - this.value = value - } - else -> { - setAttribute(attributeName, value) - } + + "class" -> { + className = value + } + + "value" -> { + this.value = value + } + + else -> { + setAttribute(attributeName, value) } - } else if (this.getAttribute(attributeName) != value) { - setAttribute(attributeName, value) } + } else if (this.getAttribute(attributeName) != value) { + setAttribute(attributeName, value) } } -internal fun Element.clearKompEvents() { - val events = getKompEvents() - for ((name, event) in getKompEvents()) { - removeEventListener(name, event) +internal fun Element.clearKompAttribute(attributeName: String) { + if (this is HTMLInputElement) { + when (attributeName) { + "checked" -> { + checked = false + } + + "class" -> { + className = "" + } + + "value" -> { + this.value = "" + } + + else -> { + removeAttribute(attributeName) + } + } + } else { + removeAttribute(attributeName) } - events.clear() } internal fun Element.setKompEvent(name: String, event: (Event) -> Unit) { @@ -123,22 +112,9 @@ internal fun Element.setKompEvent(name: String, event: (Event) -> Unit) { name } - getKompEvents()[eventName] = event - this.addEventListener(eventName, event) } -internal fun Element.getKompEvents(): MutableMap Unit> { - var map = this.asDynamic()["komp-events"] as? MutableMap Unit> - - if (map == null) { - map = mutableMapOf() - this.asDynamic()["komp-events"] = map - } - - return map -} - internal fun Element.findElementIndex(): Int { val childNodes = parentElement?.children if (childNodes != null) { diff --git a/src/jsMain/kotlin/nl/astraeus/komp/ElementIndex.kt b/src/jsMain/kotlin/nl/astraeus/komp/ElementIndex.kt index ea34fc8..2019b3d 100644 --- a/src/jsMain/kotlin/nl/astraeus/komp/ElementIndex.kt +++ b/src/jsMain/kotlin/nl/astraeus/komp/ElementIndex.kt @@ -6,7 +6,6 @@ import org.w3c.dom.get data class ElementIndex( val parent: Node, var childIndex: Int, - var setAttr: MutableSet = mutableSetOf() ) { override fun toString(): String { return "${parent.nodeName}[$childIndex]" @@ -39,7 +38,6 @@ fun ArrayList.currentPosition(): ElementIndex? { fun ArrayList.nextElement() { this.lastOrNull()?.let { - it.setAttr.clear() it.childIndex++ } } diff --git a/src/jsMain/kotlin/nl/astraeus/komp/HtmlBuilder.kt b/src/jsMain/kotlin/nl/astraeus/komp/HtmlBuilder.kt index 16e9b66..75d8781 100644 --- a/src/jsMain/kotlin/nl/astraeus/komp/HtmlBuilder.kt +++ b/src/jsMain/kotlin/nl/astraeus/komp/HtmlBuilder.kt @@ -57,12 +57,6 @@ class HtmlBuilder( } } else { // current element should become parent -/* - val ce = komponent.element - if (ce != null) { - append(ce as Element) - } -*/ komponent.create( currentPosition.last().parent as Element, currentPosition.last().childIndex @@ -100,39 +94,26 @@ class HtmlBuilder( "onTagStart, [${tag.tagName}, ${tag.namespace ?: ""}], currentPosition: $currentPosition" } - currentNode = currentPosition.currentElement() + currentNode = if (tag.namespace != null) { + document.createElementNS(tag.namespace, tag.tagName) + } else { + document.createElement(tag.tagName) + } if (currentNode == null) { logReplace { "onTagStart, currentNode1: $currentNode" } - currentNode = if (tag.namespace != null) { - document.createElementNS(tag.namespace, tag.tagName) - } else { - document.createElement(tag.tagName) - } logReplace { "onTagStart, currentElement1.1: $currentNode" } currentPosition.currentParent().appendChild(currentNode!!) - } else if ( - !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, replace: ${currentNode?.asElement()?.tagName} -> ${tag.tagName}" - } + } else { + logReplace { + "onTagStart, currentElement, namespace: ${currentNode?.asElement()?.namespaceURI} -> ${tag.namespace}" + } + logReplace { + "onTagStart, currentElement, replace: ${currentNode?.asElement()?.tagName} -> ${tag.tagName}" + } - currentNode = if (tag.namespace != null) { - document.createElementNS(tag.namespace, tag.tagName) - } else { - document.createElement(tag.tagName) - } - - currentPosition.replace(currentNode!!) + currentPosition.replace(currentNode!!) } currentElement = currentNode as? Element ?: currentElement @@ -144,15 +125,8 @@ class HtmlBuilder( firstTag = false } - currentElement?.clearKompEvents() - - // if currentElement = checkbox make sure it's cleared - (currentElement as? HTMLInputElement)?.checked = false - - currentPosition.lastOrNull()?.setAttr?.clear() for (entry in tag.attributesEntries) { - currentElement!!.setKompAttribute(entry.key, entry.value) - currentPosition.lastOrNull()?.setAttr?.add(entry.key) + currentElement?.setKompAttribute(entry.key, entry.value) } } @@ -181,11 +155,10 @@ class HtmlBuilder( checkTag("onTagAttributeChange", tag) } - currentElement?.setKompAttribute(attribute, value) if (value == null || value.isEmpty()) { - currentPosition.currentPosition()?.setAttr?.remove(attribute) + currentElement?.clearKompAttribute(attribute) } else { - currentPosition.currentPosition()?.setAttr?.add(attribute) + currentElement?.setKompAttribute(attribute, value) } } @@ -222,25 +195,6 @@ class HtmlBuilder( checkTag("onTagEnd", tag) } - if (currentElement != null) { - val setAttrs: Set = currentPosition.currentPosition()?.setAttr ?: setOf() - - // remove attributes that where not set - val element = currentElement - if (element?.hasAttributes() == true) { - for (index in 0 until element.attributes.length) { - val attribute = element.attributes[index] - if (attribute?.name != null) { - val attr = attribute.name - - if (!setAttrs.contains(attr)) { - element.setKompAttribute(attr, null) - } - } - } - } - } - currentPosition.pop() currentNode = currentPosition.currentElement() diff --git a/src/jsTest/kotlin/nl/astraeus/komp/TestClassUpdate.kt b/src/jsTest/kotlin/nl/astraeus/komp/TestClassUpdate.kt index 6e1d894..20aab87 100644 --- a/src/jsTest/kotlin/nl/astraeus/komp/TestClassUpdate.kt +++ b/src/jsTest/kotlin/nl/astraeus/komp/TestClassUpdate.kt @@ -38,7 +38,7 @@ class TestClassUpdate { Komponent.create(div, classComponent) // Verify initial state - should have the class - val contentDiv = div.querySelector("div") + var contentDiv = div.querySelector("div") println("[DEBUG_LOG] Initial DOM: ${div.printTree()}") assertTrue(contentDiv?.classList?.contains("test-class") ?: false, "Div should have the class initially") @@ -47,6 +47,7 @@ class TestClassUpdate { classComponent.requestImmediateUpdate() // Verify the class was removed + contentDiv = div.querySelector("div") println("[DEBUG_LOG] After class removal: ${div.printTree()}") assertFalse(contentDiv?.classList?.contains("test-class") ?: true, "Class should be removed after update") @@ -55,6 +56,7 @@ class TestClassUpdate { classComponent.requestImmediateUpdate() // Verify the class was added back + contentDiv = div.querySelector("div") println("[DEBUG_LOG] After class added back: ${div.printTree()}") assertTrue(contentDiv?.classList?.contains("test-class") ?: false, "Class should be added back") @@ -63,6 +65,7 @@ class TestClassUpdate { classComponent.requestImmediateUpdate() // Verify the class was changed + contentDiv = div.querySelector("div") println("[DEBUG_LOG] After class name change: ${div.printTree()}") assertFalse(contentDiv?.classList?.contains("test-class") ?: true, "Old class should be removed") assertTrue(contentDiv?.classList?.contains("new-class") ?: false, "New class should be added") diff --git a/src/jsTest/kotlin/nl/astraeus/komp/TestInsert.kt b/src/jsTest/kotlin/nl/astraeus/komp/TestInsert.kt index 208523f..7dd299a 100644 --- a/src/jsTest/kotlin/nl/astraeus/komp/TestInsert.kt +++ b/src/jsTest/kotlin/nl/astraeus/komp/TestInsert.kt @@ -77,9 +77,9 @@ class TestInsert { tableComponent.addRow("First Row") // Verify the row was added - val rowsAfterFirstInsert = table.querySelectorAll("tr") - assertEquals(1, rowsAfterFirstInsert.length, "Table should have one row after insertion") - val firstRowCell = table.querySelector("tr td") + val rowsAfterFirstInsert = div.querySelector("table")?.querySelectorAll("tr") + assertEquals(1, rowsAfterFirstInsert?.length, "Table should have one row after insertion") + val firstRowCell = div.querySelector("table")?.querySelector("tr td") assertNotNull(firstRowCell, "First row cell should exist") assertEquals("First Row", firstRowCell.textContent, "Row content should match") @@ -87,12 +87,12 @@ class TestInsert { tableComponent.addRow("Second Row") // Verify both rows are present - val rowsAfterSecondInsert = table.querySelectorAll("tr") - assertEquals(2, rowsAfterSecondInsert.length, "Table should have two rows after second insertion") - val allCells = table.querySelectorAll("tr td") - assertEquals(2, allCells.length, "Table should have two cells") - assertEquals("First Row", allCells.item(0)?.textContent, "First row content should match") - assertEquals("Second Row", allCells.item(1)?.textContent, "Second row content should match") + val rowsAfterSecondInsert = div.querySelector("table")?.querySelectorAll("tr") + assertEquals(2, rowsAfterSecondInsert?.length, "Table should have two rows after second insertion") + val allCells = div.querySelector("table")?.querySelectorAll("tr td") + assertEquals(2, allCells?.length, "Table should have two cells") + assertEquals("First Row", allCells?.item(0)?.textContent, "First row content should match") + assertEquals("Second Row", allCells?.item(1)?.textContent, "Second row content should match") // Print the DOM tree for debugging println("Table DOM: ${div.printTree()}") diff --git a/src/jsTest/kotlin/nl/astraeus/komp/TestStyleUpdate.kt b/src/jsTest/kotlin/nl/astraeus/komp/TestStyleUpdate.kt index 2ab7c55..9a654b1 100644 --- a/src/jsTest/kotlin/nl/astraeus/komp/TestStyleUpdate.kt +++ b/src/jsTest/kotlin/nl/astraeus/komp/TestStyleUpdate.kt @@ -12,57 +12,68 @@ import kotlin.test.assertNull * Test class for verifying style attribute updates and removals */ class StyleKomponent : Komponent() { - var includeStyle = true - var styleValue = "color: red;" + var includeStyle = true + var styleValue = "color: red;" - override fun HtmlBuilder.render() { - div { - if (includeStyle) { - style = styleValue - } - +"Content" - } + override fun HtmlBuilder.render() { + div { + if (includeStyle) { + style = styleValue + } + +"Content" } + } } class TestStyleUpdate { - @Test - fun testStyleRemoval() { - // Create a test component - val styleComponent = StyleKomponent() - val div = document.createElement("div") as HTMLDivElement + @Test + fun testStyleRemoval() { + // Create a test component + val styleComponent = StyleKomponent() + val div = document.createElement("div") as HTMLDivElement - // Render it - Komponent.create(div, styleComponent) + // Render it + Komponent.create(div, styleComponent) - // Verify initial state - should have the style - val contentDiv = div.querySelector("div") - println("[DEBUG_LOG] Initial DOM: ${div.printTree()}") - assertEquals("color: red;", contentDiv?.getAttribute("style"), "Div should have the style initially") + // Verify initial state - should have the style + var contentDiv = div.querySelector("div") + println("[DEBUG_LOG] Initial DOM: ${div.printTree()}") + assertEquals( + "color: red;", + contentDiv?.getAttribute("style"), + "Div should have the style initially" + ) - // Update to remove the style - styleComponent.includeStyle = false - styleComponent.requestImmediateUpdate() + // Update to remove the style + styleComponent.includeStyle = false + styleComponent.requestImmediateUpdate() - // Verify the style was removed - println("[DEBUG_LOG] After style removal: ${div.printTree()}") - assertNull(contentDiv?.getAttribute("style"), "Style should be removed after update") + // Verify the style was removed + contentDiv = div.querySelector("div") + println("[DEBUG_LOG] After style removal: ${div.printTree()}") + assertNull(contentDiv?.getAttribute("style"), "Style should be removed after update") - // Add the style back - styleComponent.includeStyle = true - styleComponent.requestImmediateUpdate() + // Add the style back + styleComponent.includeStyle = true + styleComponent.requestImmediateUpdate() - // Verify the style was added back - println("[DEBUG_LOG] After style added back: ${div.printTree()}") - assertEquals("color: red;", contentDiv?.getAttribute("style"), "Style should be added back") + // Verify the style was added back + contentDiv = div.querySelector("div") + println("[DEBUG_LOG] After style added back: ${div.printTree()}") + assertEquals("color: red;", contentDiv?.getAttribute("style"), "Style should be added back") - // Change the style value - styleComponent.styleValue = "color: blue;" - styleComponent.requestImmediateUpdate() + // Change the style value + styleComponent.styleValue = "color: blue;" + styleComponent.requestImmediateUpdate() - // Verify the style was changed - println("[DEBUG_LOG] After style value change: ${div.printTree()}") - assertEquals("color: blue;", contentDiv?.getAttribute("style"), "Style should be updated to new value") - } + // Verify the style was changed + contentDiv = div.querySelector("div") + println("[DEBUG_LOG] After style value change: ${div.printTree()}") + assertEquals( + "color: blue;", + contentDiv?.getAttribute("style"), + "Style should be updated to new value" + ) + } } \ No newline at end of file