diff --git a/web/core/build.gradle.kts b/web/core/build.gradle.kts index f61f32d4b7..f19297c5ba 100644 --- a/web/core/build.gradle.kts +++ b/web/core/build.gradle.kts @@ -23,14 +23,13 @@ kotlin { val commonMain by getting { dependencies { implementation(compose.runtime) - implementation(kotlin("stdlib-common")) } } val jsMain by getting { dependencies { - implementation(project(":internal-web-core-runtime")) implementation(kotlin("stdlib-js")) + implementation(project(":internal-web-core-runtime")) } } diff --git a/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/elements/ElementScope.kt b/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/elements/ElementScope.kt index 2ec9149ca6..2f59538303 100644 --- a/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/elements/ElementScope.kt +++ b/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/elements/ElementScope.kt @@ -12,10 +12,6 @@ import androidx.compose.runtime.currentComposer import androidx.compose.runtime.remember import org.w3c.dom.Element -interface DOMScope { - val DisposableEffectScope.scopeElement: TElement -} - /** * ElementScope allows adding effects to the Composable representing html element. * Also see a tutorial: https://github.com/JetBrains/compose-jb/tree/master/tutorials/Web/Using_Effects diff --git a/web/core/src/jsTest/kotlin/elements/ElementsTests.kt b/web/core/src/jsTest/kotlin/elements/ElementsTests.kt index 540bab2d1a..d2b006d2cd 100644 --- a/web/core/src/jsTest/kotlin/elements/ElementsTests.kt +++ b/web/core/src/jsTest/kotlin/elements/ElementsTests.kt @@ -6,6 +6,9 @@ package org.jetbrains.compose.web.core.tests.elements import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue import kotlinx.browser.document import org.jetbrains.compose.web.ExperimentalComposeWebApi import org.jetbrains.compose.web.attributes.AttrsScope @@ -136,7 +139,7 @@ class ElementsTests { @Test fun elementBuilderShouldBeCalledOnce() = runTest { var counter = 0 - var flag = false + var flag by mutableStateOf(false) composition { TagElement({ diff --git a/web/internal-web-core-runtime/build.gradle.kts b/web/internal-web-core-runtime/build.gradle.kts index 91a8e54b2e..038a29600d 100644 --- a/web/internal-web-core-runtime/build.gradle.kts +++ b/web/internal-web-core-runtime/build.gradle.kts @@ -21,12 +21,12 @@ kotlin { val commonMain by getting { dependencies { implementation(compose.runtime) - implementation(kotlin("stdlib-common")) } } - val jsMain by getting { + + val jsTest by getting { dependencies { - implementation(kotlin("stdlib-js")) + implementation(kotlin("test-js")) } } } diff --git a/web/internal-web-core-runtime/src/jsMain/kotlin/org/jetbrains/compose/web/dom/DOMSCope.kt b/web/internal-web-core-runtime/src/jsMain/kotlin/org/jetbrains/compose/web/dom/DOMSCope.kt new file mode 100644 index 0000000000..52dd788af2 --- /dev/null +++ b/web/internal-web-core-runtime/src/jsMain/kotlin/org/jetbrains/compose/web/dom/DOMSCope.kt @@ -0,0 +1,13 @@ +/* + * Copyright 2020-2022 JetBrains s.r.o. and respective authors and developers. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. + */ + +package org.jetbrains.compose.web.dom + +import androidx.compose.runtime.DisposableEffectScope +import org.w3c.dom.Element + +interface DOMScope { + val DisposableEffectScope.scopeElement: TElement +} \ No newline at end of file diff --git a/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/RenderComposable.kt b/web/internal-web-core-runtime/src/jsMain/kotlin/org/jetbrains/compose/web/renderComposable.kt similarity index 84% rename from web/core/src/jsMain/kotlin/org/jetbrains/compose/web/RenderComposable.kt rename to web/internal-web-core-runtime/src/jsMain/kotlin/org/jetbrains/compose/web/renderComposable.kt index afed73f8c7..eb44c3859e 100644 --- a/web/core/src/jsMain/kotlin/org/jetbrains/compose/web/RenderComposable.kt +++ b/web/internal-web-core-runtime/src/jsMain/kotlin/org/jetbrains/compose/web/renderComposable.kt @@ -1,21 +1,31 @@ +/* + * Copyright 2020-2022 JetBrains s.r.o. and respective authors and developers. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. + */ + package org.jetbrains.compose.web import androidx.compose.runtime.Composable import androidx.compose.runtime.Composition import androidx.compose.runtime.ControlledComposition -import androidx.compose.runtime.MonotonicFrameClock import androidx.compose.runtime.DefaultMonotonicFrameClock import androidx.compose.runtime.DisposableEffectScope +import androidx.compose.runtime.MonotonicFrameClock import androidx.compose.runtime.Recomposer -import org.jetbrains.compose.web.dom.DOMScope import kotlinx.browser.document import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineStart import kotlinx.coroutines.launch -import org.jetbrains.compose.web.internal.runtime.* +import org.jetbrains.compose.web.dom.DOMScope +import org.jetbrains.compose.web.internal.runtime.ComposeWebInternalApi +import org.jetbrains.compose.web.internal.runtime.DomApplier +import org.jetbrains.compose.web.internal.runtime.DomNodeWrapper +import org.jetbrains.compose.web.internal.runtime.GlobalSnapshotManager +import org.jetbrains.compose.web.internal.runtime.JsMicrotasksDispatcher import org.w3c.dom.Element import org.w3c.dom.HTMLBodyElement import org.w3c.dom.get + /** * Use this method to mount the composition at the certain [root] * @@ -34,6 +44,11 @@ fun renderComposable( val context = monotonicFrameClock + JsMicrotasksDispatcher() val recomposer = Recomposer(context) + + CoroutineScope(context).launch(start = CoroutineStart.UNDISPATCHED) { + recomposer.runRecomposeAndApplyChanges() + } + val composition = ControlledComposition( applier = DomApplier(DomNodeWrapper(root)), parent = recomposer @@ -45,10 +60,6 @@ fun renderComposable( composition.setContent @Composable { content(scope) } - - CoroutineScope(context).launch(start = CoroutineStart.UNDISPATCHED) { - recomposer.runRecomposeAndApplyChanges() - } return composition } diff --git a/web/internal-web-core-runtime/src/jsTest/kotlin/RenderComposableTests.kt b/web/internal-web-core-runtime/src/jsTest/kotlin/RenderComposableTests.kt new file mode 100644 index 0000000000..0a05a04b5d --- /dev/null +++ b/web/internal-web-core-runtime/src/jsTest/kotlin/RenderComposableTests.kt @@ -0,0 +1,24 @@ +import kotlinx.browser.document +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.promise +import org.jetbrains.compose.web.renderComposable +import kotlin.test.Test +import kotlin.test.assertEquals + +/* + * Copyright 2020-2022 JetBrains s.r.o. and respective authors and developers. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. + */ + +class RenderComposableTests { + @Test + fun compCount() = MainScope().promise { + var count = 0 + renderComposable(document.createElement("div")) { + count++ + } + delay(1000) + assertEquals(1, count) + } +} \ No newline at end of file diff --git a/web/test-utils/src/jsMain/kotlin/org/jetbrains/compose/web/testutils/TestUtils.kt b/web/test-utils/src/jsMain/kotlin/org/jetbrains/compose/web/testutils/TestUtils.kt index 7cf4669276..69f3545e98 100644 --- a/web/test-utils/src/jsMain/kotlin/org/jetbrains/compose/web/testutils/TestUtils.kt +++ b/web/test-utils/src/jsMain/kotlin/org/jetbrains/compose/web/testutils/TestUtils.kt @@ -1,25 +1,14 @@ package org.jetbrains.compose.web.testutils import androidx.compose.runtime.Composable -import androidx.compose.runtime.Composition -import androidx.compose.runtime.ControlledComposition import androidx.compose.runtime.MonotonicFrameClock -import androidx.compose.runtime.Recomposer import kotlinx.browser.document import kotlinx.browser.window import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.CoroutineStart import kotlinx.coroutines.MainScope -import kotlinx.coroutines.launch import kotlinx.coroutines.promise import kotlinx.dom.clear -import org.jetbrains.compose.web.internal.runtime.ComposeWebInternalApi -import org.jetbrains.compose.web.internal.runtime.DomApplier -import org.jetbrains.compose.web.internal.runtime.DomNodeWrapper -import org.jetbrains.compose.web.internal.runtime.GlobalSnapshotManager -import org.jetbrains.compose.web.internal.runtime.JsMicrotasksDispatcher import org.jetbrains.compose.web.renderComposable -import org.w3c.dom.Element import org.w3c.dom.HTMLElement import org.w3c.dom.MutationObserver import org.w3c.dom.MutationObserverInit