diff --git a/demo/gdml/build.gradle.kts b/demo/gdml/build.gradle.kts index 39c82290..69f56419 100644 --- a/demo/gdml/build.gradle.kts +++ b/demo/gdml/build.gradle.kts @@ -21,7 +21,9 @@ kotlin { useCommonJs() browser { commonWebpackConfig { - cssSupport.enabled = false + cssSupport{ + enabled.set(false) + } } } } diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt index e2d7ad51..5f1d24e1 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt @@ -2,13 +2,13 @@ package space.kscience.visionforge.gdml.demo import kotlinx.css.* import org.w3c.dom.Document -import react.dom.client.createRoot import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.fetch import space.kscience.gdml.GdmlShowCase import space.kscience.visionforge.Application import space.kscience.visionforge.Colors import space.kscience.visionforge.gdml.toVision +import space.kscience.visionforge.react.createRoot import space.kscience.visionforge.react.render import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.ambientLight diff --git a/demo/js-playground/build.gradle.kts b/demo/js-playground/build.gradle.kts index ada5841a..3368c5ef 100644 --- a/demo/js-playground/build.gradle.kts +++ b/demo/js-playground/build.gradle.kts @@ -12,7 +12,9 @@ kotlin{ useCommonJs() browser { commonWebpackConfig { - cssSupport.enabled = false + cssSupport{ + enabled.set(false) + } } } } diff --git a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt b/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt index 2c93d31f..781aa897 100644 --- a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt +++ b/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt @@ -1,6 +1,5 @@ import kotlinx.css.* import org.w3c.dom.Document -import react.dom.client.createRoot import ringui.SmartTabs import ringui.Tab import space.kscience.dataforge.context.Context @@ -11,6 +10,7 @@ import space.kscience.visionforge.Application import space.kscience.visionforge.Colors import space.kscience.visionforge.VisionClient import space.kscience.visionforge.plotly.PlotlyPlugin +import space.kscience.visionforge.react.createRoot import space.kscience.visionforge.react.render import space.kscience.visionforge.ring.ThreeCanvasWithControls import space.kscience.visionforge.ring.ThreeWithControlsPlugin diff --git a/demo/muon-monitor/build.gradle.kts b/demo/muon-monitor/build.gradle.kts index fe3f89cb..f25c8371 100644 --- a/demo/muon-monitor/build.gradle.kts +++ b/demo/muon-monitor/build.gradle.kts @@ -22,7 +22,7 @@ kotlin { browser { commonWebpackConfig { cssSupport { - enabled = false + enabled.set(false) } } } diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt index 50e51859..d28516d0 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt @@ -1,11 +1,11 @@ package ru.mipt.npm.muon.monitor import org.w3c.dom.Document -import react.dom.client.createRoot import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.fetch import space.kscience.visionforge.Application import space.kscience.visionforge.VisionManager +import space.kscience.visionforge.react.createRoot import space.kscience.visionforge.react.render import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.three.ThreePlugin diff --git a/demo/playground/build.gradle.kts b/demo/playground/build.gradle.kts index 076f9d37..57c6bfd2 100644 --- a/demo/playground/build.gradle.kts +++ b/demo/playground/build.gradle.kts @@ -16,11 +16,13 @@ kotlin { useCommonJs() browser { webpackTask { - this.outputFileName = "js/visionforge-playground.js" + outputFileName = "js/visionforge-playground.js" } commonWebpackConfig { sourceMaps = true - cssSupport.enabled = false + cssSupport{ + enabled.set(false) + } } } binaries.executable() diff --git a/demo/playground/src/jvmMain/kotlin/serverExtensions.kt b/demo/playground/src/jvmMain/kotlin/serverExtensions.kt index b22c6514..9eb87730 100644 --- a/demo/playground/src/jvmMain/kotlin/serverExtensions.kt +++ b/demo/playground/src/jvmMain/kotlin/serverExtensions.kt @@ -16,7 +16,11 @@ public fun makeVisionFile( val actualPath = VisionPage(Global.visionManager, content = content).makeFile(path) { actualPath -> mapOf( "title" to VisionPage.title(title), - "playground" to VisionPage.importScriptHeader("js/visionforge-playground.js", resourceLocation, actualPath), + "playground" to VisionPage.importScriptHeader( + "js/visionforge-playground.js", + resourceLocation, + actualPath + ), ) } if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI()) diff --git a/demo/sat-demo/build.gradle.kts b/demo/sat-demo/build.gradle.kts index 870f3388..406591ee 100644 --- a/demo/sat-demo/build.gradle.kts +++ b/demo/sat-demo/build.gradle.kts @@ -15,7 +15,7 @@ group = "ru.mipt.npm" dependencies{ implementation(project(":visionforge-threejs:visionforge-threejs-server")) - implementation("ch.qos.logback:logback-classic:1.2.11") + implementation("ch.qos.logback:logback-classic:1.4.5") } application { diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/static.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/static.kt new file mode 100644 index 00000000..2a1fd240 --- /dev/null +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/static.kt @@ -0,0 +1,21 @@ +package ru.mipt.npm.sat + +import space.kscience.dataforge.misc.DFExperimental +import space.kscience.visionforge.html.ResourceLocation +import space.kscience.visionforge.solid.box +import space.kscience.visionforge.solid.material +import space.kscience.visionforge.solid.set +import space.kscience.visionforge.solid.solid +import space.kscience.visionforge.three.makeThreeJsFile + +@OptIn(DFExperimental::class) +fun main() = makeThreeJsFile(resourceLocation = ResourceLocation.SYSTEM) { + vision ("canvas") { + solid { + box(100, 100, 100) + material { + emissiveColor.set("red") + } + } + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 056b8ac8..b80e2265 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,9 +1,8 @@ kotlin.code.style=official kotlin.mpp.stability.nowarn=true -kotlin.jupyter.add.scanner=false kotlin.incremental.js.ir=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G -toolsVersion=0.13.3-kotlin-1.7.20 \ No newline at end of file +toolsVersion=0.13.4-kotlin-1.8.0 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ae04661e..070cb702 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/jupyter/visionforge-jupyter-gdml/build.gradle.kts b/jupyter/visionforge-jupyter-gdml/build.gradle.kts index 3129de1e..1198f022 100644 --- a/jupyter/visionforge-jupyter-gdml/build.gradle.kts +++ b/jupyter/visionforge-jupyter-gdml/build.gradle.kts @@ -14,7 +14,9 @@ kotlin { } commonWebpackConfig { sourceMaps = false - cssSupport.enabled = false + cssSupport{ + enabled.set(false) + } } } binaries.executable() diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt index 6ea0659c..8e7e1208 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt +++ b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt @@ -2,7 +2,6 @@ package space.kscience.visionforge.bootstrap import org.w3c.dom.Element import react.RBuilder -import react.dom.client.createRoot import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.isEmpty import space.kscience.visionforge.Vision @@ -67,6 +66,6 @@ public fun RBuilder.visionPropertyEditor( public fun Element.visionPropertyEditor( item: Vision, descriptor: MetaDescriptor? = item.descriptor, -): Unit = createRoot(this).render { +): Unit = space.kscience.visionforge.react.createRoot(this).render { visionPropertyEditor(item, descriptor = descriptor) } \ No newline at end of file diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/createRoot.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/createRoot.kt new file mode 100644 index 00000000..fec86770 --- /dev/null +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/createRoot.kt @@ -0,0 +1,17 @@ + +@file:JsModule("react-dom/client") +@file:JsNonModule + +package space.kscience.visionforge.react + +import org.w3c.dom.Element +import react.dom.client.Root +import react.dom.client.RootOptions + +/** + * Compatibility method to work with old browser API + */ +public external fun createRoot( + container: Element, + options: RootOptions = definedExternally, +): Root diff --git a/ui/ring/build.gradle.kts b/ui/ring/build.gradle.kts index aa168c11..8b4bf056 100644 --- a/ui/ring/build.gradle.kts +++ b/ui/ring/build.gradle.kts @@ -9,7 +9,9 @@ kotlin{ useCommonJs() browser { commonWebpackConfig { - cssSupport.enabled = false + cssSupport{ + enabled.set(false) + } } } } diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt index 03cbb722..60f36fb0 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt @@ -2,7 +2,6 @@ package space.kscience.visionforge.ring import kotlinx.coroutines.async import org.w3c.dom.Element -import react.dom.client.createRoot import space.kscience.dataforge.context.AbstractPlugin import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.PluginFactory @@ -26,7 +25,7 @@ public class ThreeWithControlsPlugin : AbstractPlugin(), ElementVisionRenderer { if (vision is Solid) ElementVisionRenderer.DEFAULT_RATING * 2 else ElementVisionRenderer.ZERO_RATING override fun render(element: Element, name: Name, vision: Vision, meta: Meta) { - createRoot(element).render { + space.kscience.visionforge.react.createRoot(element).render { child(ThreeCanvasWithControls) { attrs { this.solids = three.solids diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt index a3f81adb..83529d28 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt @@ -2,7 +2,6 @@ package space.kscience.visionforge.ring import org.w3c.dom.Element import react.RBuilder -import react.dom.client.createRoot import react.dom.p import ringui.Island import ringui.SmartTabs diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt index 71410372..4c4ab90a 100644 --- a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt @@ -4,12 +4,10 @@ import kotlinx.html.link import kotlinx.html.script import kotlinx.html.unsafe import org.slf4j.LoggerFactory -import space.kscience.visionforge.VisionManager import java.nio.file.Files import java.nio.file.Path import java.nio.file.StandardOpenOption import java.security.MessageDigest -import kotlin.io.path.ExperimentalPathApi import kotlin.io.path.readText @@ -47,15 +45,14 @@ private fun ByteArray.toHexString() = asUByteArray().joinToString("") { it.toStr * Check if the asset exists in given local location and put it there if it does not * @param */ -@OptIn(ExperimentalPathApi::class) -internal fun checkOrStoreFile(htmlPath: Path, filePath: Path, resource: String): Path { +internal fun checkOrStoreFile(htmlPath: Path, filePath: Path, resource: String, classLoader: ClassLoader): Path { val logger = LoggerFactory.getLogger("") logger.info("Resolving or storing resource file $resource") val fullPath = htmlPath.resolveSibling(filePath).toAbsolutePath().resolve(resource) logger.debug("Full path to resource file $resource: $fullPath") - val bytes = VisionManager.Companion::class.java.getResourceAsStream("/$resource")?.readAllBytes() + val bytes = classLoader.getResourceAsStream(resource)?.readAllBytes() ?: error("Resource $resource not found on classpath") val md = MessageDigest.getInstance("MD5") @@ -66,8 +63,20 @@ internal fun checkOrStoreFile(htmlPath: Path, filePath: Path, resource: String): if (!skip) { logger.debug("File $fullPath does not exist or wrong checksum. Writing file") Files.createDirectories(fullPath.parent) - Files.write(fullPath, bytes, StandardOpenOption.CREATE,StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE) - Files.write(md5File, checksum.encodeToByteArray(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE) + Files.write( + fullPath, + bytes, + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING, + StandardOpenOption.WRITE + ) + Files.write( + md5File, + checksum.encodeToByteArray(), + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING, + StandardOpenOption.WRITE + ) } return if (htmlPath.isAbsolute && fullPath.startsWith(htmlPath.parent)) { @@ -89,11 +98,11 @@ internal fun fileScriptHeader( } } -internal fun embedScriptHeader(resource: String): HtmlFragment = { +internal fun embedScriptHeader(resource: String, classLoader: ClassLoader): HtmlFragment = { script { type = "text/javascript" unsafe { - val bytes = VisionManager::class.java.getResourceAsStream("/$resource")!!.readAllBytes() + val bytes = classLoader.getResourceAsStream(resource)!!.readAllBytes() +bytes.toString(Charsets.UTF_8) } } @@ -103,8 +112,9 @@ internal fun fileCssHeader( basePath: Path, cssPath: Path, resource: String, + classLoader: ClassLoader, ): HtmlFragment = { - val relativePath = checkOrStoreFile(basePath, cssPath, resource) + val relativePath = checkOrStoreFile(basePath, cssPath, resource, classLoader) link { rel = "stylesheet" href = relativePath.toString() @@ -118,22 +128,26 @@ public fun VisionPage.Companion.importScriptHeader( scriptResource: String, resourceLocation: ResourceLocation, htmlPath: Path? = null, + classLoader: ClassLoader = Thread.currentThread().contextClassLoader, ): HtmlFragment { val targetPath = when (resourceLocation) { ResourceLocation.LOCAL -> checkOrStoreFile( htmlPath ?: Path.of("."), Path.of(VISIONFORGE_ASSETS_PATH), - scriptResource + scriptResource, + classLoader ) + ResourceLocation.SYSTEM -> checkOrStoreFile( Path.of("."), Path.of(System.getProperty("user.home")).resolve(VISIONFORGE_ASSETS_PATH), - scriptResource + scriptResource, classLoader ) + ResourceLocation.EMBED -> null } return if (targetPath == null) { - embedScriptHeader(scriptResource) + embedScriptHeader(scriptResource, classLoader) } else { fileScriptHeader(targetPath) } diff --git a/visionforge-tables/build.gradle.kts b/visionforge-tables/build.gradle.kts index 55cc27e5..abc56455 100644 --- a/visionforge-tables/build.gradle.kts +++ b/visionforge-tables/build.gradle.kts @@ -14,7 +14,9 @@ kotlin { binaries.library() browser{ commonWebpackConfig{ - cssSupport.enabled = true + cssSupport{ + enabled.set(true) + } } } } diff --git a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt index dcf7ce4f..4764069f 100644 --- a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt +++ b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt @@ -1,6 +1,6 @@ package space.kscience.visionforge.tables -import kotlinx.js.jso +import js.core.jso import org.w3c.dom.Element import org.w3c.dom.HTMLElement import space.kscience.dataforge.context.AbstractPlugin diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt index 2bd8c572..e168c1d2 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt @@ -1,7 +1,7 @@ package space.kscience.visionforge.solid.three -import kotlinx.js.jso +import js.core.jso import space.kscience.dataforge.context.logger import space.kscience.dataforge.context.warn import space.kscience.visionforge.onPropertyChange diff --git a/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt b/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt index 69a9ac51..ed2908f5 100644 --- a/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt +++ b/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt @@ -6,8 +6,6 @@ import space.kscience.visionforge.solid.three.ThreePlugin @DFExperimental -public fun main(): Unit { - runVisionClient { - plugin(ThreePlugin) - } +public fun main(): Unit = runVisionClient { + plugin(ThreePlugin) } \ No newline at end of file diff --git a/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt b/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt index ba533979..28f04f8d 100644 --- a/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt +++ b/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt @@ -10,7 +10,6 @@ import java.nio.file.Path public val VisionPage.Companion.threeJsHeader: HtmlFragment get() = scriptHeader("js/visionforge-three.js") - @DFExperimental public fun makeThreeJsFile( path: Path? = null, @@ -22,7 +21,11 @@ public fun makeThreeJsFile( val actualPath = VisionPage(Global.visionManager, content = content).makeFile(path) { actualPath -> mapOf( "title" to VisionPage.title(title), - "threeJs" to VisionPage.importScriptHeader("js/visionforge-three.js", resourceLocation, actualPath) + "threeJs" to VisionPage.importScriptHeader( + "js/visionforge-three.js", + resourceLocation, + actualPath, + ) ) } if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI()) diff --git a/visionforge-threejs/visionforge-threejs-server/src/jvmTest/kotlin/space/kscience/visionforge/three/TestServerExtensions.kt b/visionforge-threejs/visionforge-threejs-server/src/jvmTest/kotlin/space/kscience/visionforge/three/TestServerExtensions.kt new file mode 100644 index 00000000..99e7fba6 --- /dev/null +++ b/visionforge-threejs/visionforge-threejs-server/src/jvmTest/kotlin/space/kscience/visionforge/three/TestServerExtensions.kt @@ -0,0 +1,23 @@ +package space.kscience.visionforge.three + +import kotlinx.html.stream.createHTML +import space.kscience.visionforge.html.ResourceLocation +import space.kscience.visionforge.html.VisionPage +import space.kscience.visionforge.html.importScriptHeader +import kotlin.test.Test + +class TestServerExtensions { + + @Test + fun testServerHeader(){ + val string = createHTML().apply { + VisionPage.importScriptHeader( + "js/visionforge-three.js", + ResourceLocation.SYSTEM + ).invoke(this) + }.finalize() + + + //println(string) + } +} \ No newline at end of file