diff --git a/html/compose-compiler-integration/src/jsTest/kotlin/AnonymousObjectsInComposable.kt b/html/compose-compiler-integration/src/jsTest/kotlin/AnonymousObjectsInComposable.kt index 0bd10d56b02..75b4bdbd59b 100644 --- a/html/compose-compiler-integration/src/jsTest/kotlin/AnonymousObjectsInComposable.kt +++ b/html/compose-compiler-integration/src/jsTest/kotlin/AnonymousObjectsInComposable.kt @@ -18,7 +18,7 @@ class AnonymousObjectsInComposable { content.Abc() } - assertEquals("<div>Abc</div>", document.body!!.firstElementChild!!.outerHTML) + assertEquals("<div>Abc</div>", document.body!!.lastElementChild!!.outerHTML) } @Test @@ -30,7 +30,7 @@ class AnonymousObjectsInComposable { HasLocalClassWithComposable() } - assertEquals("<div>Abc2</div>", document.body!!.firstElementChild!!.outerHTML) + assertEquals("<div>Abc2</div>", document.body!!.lastElementChild!!.outerHTML) } @Test @@ -41,7 +41,7 @@ class AnonymousObjectsInComposable { TestConstructor { return@TestConstructor 111 }.otherComposable!!.invoke() } - assertEquals("<div>Abc223-111</div>", document.body!!.firstElementChild!!.outerHTML) + assertEquals("<div>Abc223-111</div>", document.body!!.lastElementChild!!.outerHTML) } } diff --git a/html/compose-compiler-integration/src/jsTest/kotlin/ComposableLambdaCalls.kt b/html/compose-compiler-integration/src/jsTest/kotlin/ComposableLambdaCalls.kt index 4522dbc1b6f..21d686d4cb0 100644 --- a/html/compose-compiler-integration/src/jsTest/kotlin/ComposableLambdaCalls.kt +++ b/html/compose-compiler-integration/src/jsTest/kotlin/ComposableLambdaCalls.kt @@ -25,7 +25,7 @@ class ComposableLambdaCalls { } } - assertEquals("<div>SomeText</div>", document.body!!.firstElementChild!!.outerHTML) + assertEquals("<div>SomeText</div>", document.body!!.lastElementChild!!.outerHTML) } @Test @@ -36,7 +36,7 @@ class ComposableLambdaCalls { } } - assertEquals("<div>Text1</div>", document.body!!.firstElementChild!!.outerHTML) + assertEquals("<div>Text1</div>", document.body!!.lastElementChild!!.outerHTML) } @Test @@ -51,7 +51,7 @@ class ComposableLambdaCalls { } } - assertEquals("<div>TextA</div>", document.body!!.firstElementChild!!.outerHTML) + assertEquals("<div>TextA</div>", document.body!!.lastElementChild!!.outerHTML) } @Test @@ -64,7 +64,7 @@ class ComposableLambdaCalls { } } - assertEquals("<div></div>", document.body!!.firstElementChild!!.outerHTML) + assertEquals("<div></div>", document.body!!.lastElementChild!!.outerHTML) } @Test @@ -84,7 +84,7 @@ class ComposableLambdaCalls { } } - assertEquals("<div></div>", document.body!!.firstElementChild!!.outerHTML) + assertEquals("<div></div>", document.body!!.lastElementChild!!.outerHTML) assertEquals(false, someIntInvoked, message = "someInt() should never be invoked as `l` is null") } @@ -107,7 +107,7 @@ class ComposableLambdaCalls { } } - assertEquals("<div>Text10</div>", document.body!!.firstElementChild!!.outerHTML) + assertEquals("<div>Text10</div>", document.body!!.lastElementChild!!.outerHTML) assertEquals(true, someIntInvoked) } @@ -123,7 +123,7 @@ class ComposableLambdaCalls { } } - assertEquals("<div>Text-SomeText</div>", document.body!!.firstElementChild!!.outerHTML) + assertEquals("<div>Text-SomeText</div>", document.body!!.lastElementChild!!.outerHTML) } @Test @@ -136,6 +136,6 @@ class ComposableLambdaCalls { } } - assertEquals("<div>SuperText</div>", document.body!!.firstElementChild!!.outerHTML) + assertEquals("<div>SuperText</div>", document.body!!.lastElementChild!!.outerHTML) } } diff --git a/html/internal-html-core-runtime/src/jsMain/kotlin/org/jetbrains/compose/web/internal/runtime/DomApplier.kt b/html/internal-html-core-runtime/src/jsMain/kotlin/org/jetbrains/compose/web/internal/runtime/DomApplier.kt index 16a3ce7be48..8a0de4ab491 100644 --- a/html/internal-html-core-runtime/src/jsMain/kotlin/org/jetbrains/compose/web/internal/runtime/DomApplier.kt +++ b/html/internal-html-core-runtime/src/jsMain/kotlin/org/jetbrains/compose/web/internal/runtime/DomApplier.kt @@ -29,7 +29,7 @@ class DomApplier( override fun onClear() { // or current.node.clear()?; in all examples it calls 'clear' on the root - root.node.clear() + root.clear() } } @@ -41,19 +41,25 @@ interface NamedEventListener : EventListener { @ComposeWebInternalApi open class DomNodeWrapper(open val node: Node) { + private val knownNodes: MutableList<DomNodeWrapper> = mutableListOf<DomNodeWrapper>() fun insert(index: Int, nodeWrapper: DomNodeWrapper) { - val length = node.childNodes.length + val length = knownNodes.size if (index < length) { - node.insertBefore(nodeWrapper.node, node.childNodes[index]!!) + val nodeOnIndex = knownNodes[index] + knownNodes.add(index, nodeWrapper) + node.insertBefore(nodeWrapper.node, nodeOnIndex.node) } else { + knownNodes.add(nodeWrapper) + node.appendChild(nodeWrapper.node) } } fun remove(index: Int, count: Int) { repeat(count) { - node.removeChild(node.childNodes[index]!!) + val nodeToRemove = knownNodes.removeAt(index) + node.removeChild(nodeToRemove.node) } } @@ -67,8 +73,20 @@ open class DomNodeWrapper(open val node: Node) { val fromIndex = if (from > to) from + i else from val toIndex = if (from > to) to + i else to + count - 2 - val child = node.removeChild(node.childNodes[fromIndex]!!) - node.insertBefore(child, node.childNodes[toIndex]!!) + val nodeOnIndex = knownNodes[toIndex] + + val nodeToMove = knownNodes.removeAt(fromIndex) + node.removeChild(nodeToMove.node) + + knownNodes.add(toIndex, nodeToMove) + node.insertBefore(nodeToMove.node, nodeOnIndex.node) } } -} \ No newline at end of file + + internal fun clear() { + knownNodes.forEach { + node.removeChild(it.node) + } + knownNodes.clear() + } +}