6 Commits

Author SHA1 Message Date
963e934953 Fix svg/unsafe, add onBeforeUpdate, v. 0.5.6 2021-08-19 09:53:16 +02:00
0ccbe105b7 Fix memoize option, v. 0.5.5 2021-08-18 11:07:26 +02:00
dac465a161 Fixes 2021-07-11 13:29:34 +02:00
48708580ca Cleanup 2021-07-02 19:47:27 +02:00
1e6e34bec5 Do updates immediatly 2021-07-02 19:45:48 +02:00
fa6252832b Cleanup 2021-06-29 17:21:27 +02:00
14 changed files with 981 additions and 796 deletions

2
.gitignore vendored
View File

@@ -1,4 +1,6 @@
# Created by .ignore support plugin (hsz.mobi)
build
.gradle
web/js/generated
gradle.properties
local.properties

View File

@@ -1,27 +1,23 @@
plugins {
kotlin("multiplatform") version "1.4.32"
kotlin("multiplatform") version "1.5.21"
`maven-publish`
}
group = "nl.astraeus"
version = "0.3.0-SNAPSHOT"
version = "0.5.7-SNAPSHOT"
repositories {
mavenCentral()
jcenter()
}
kotlin {
/* Targets configuration omitted.
* To find out how to configure the targets, please follow the link:
* https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#setting-up-targets */
js(BOTH) {
browser {
//produceKotlinLibrary()
testTask {
useKarma {
useChromeHeadless()
useChromiumHeadless()
//useChromeHeadless()
}
}
}
@@ -32,7 +28,7 @@ kotlin {
dependencies {
implementation(kotlin("stdlib-common"))
api("org.jetbrains.kotlinx:kotlinx-html-js:0.7.2")
api("org.jetbrains.kotlinx:kotlinx-html-js:0.7.3")
}
}
val jsMain by getting {
@@ -53,7 +49,7 @@ publishing {
if (project.properties["nexusUsername"] != null) {
maven {
name = "releases"
url = uri("http://nexus.astraeus.nl/nexus/content/repositories/releases")
url = uri("https://nexus.astraeus.nl/nexus/content/repositories/releases")
credentials {
val nexusUsername: String by project
val nexusPassword: String by project
@@ -64,7 +60,7 @@ publishing {
}
maven {
name = "snapshots"
url = uri("http://nexus.astraeus.nl/nexus/content/repositories/snapshots")
url = uri("https://nexus.astraeus.nl/nexus/content/repositories/snapshots")
credentials {
val nexusUsername: String by project
val nexusPassword: String by project

View File

@@ -1,5 +1,5 @@
#Wed Mar 04 13:29:12 CET 2020
distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-all.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStorePath=wrapper/dists

View File

@@ -1,25 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="komp:commonMain" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.type="sourceSet" external.system.module.version="0.3.0-SNAPSHOT" type="JAVA_MODULE" version="4">
<module external.linked.project.id="komp:commonMain" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.type="sourceSet" external.system.module.version="0.5.6-SNAPSHOT" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="Common (experimental) " allPlatforms="JS []/JVM [1.8]/Native []/Native [general]" useProjectSettings="false" isTestModule="false" externalProjectId="komp" pureKotlinSourceFolders="$MODULE_DIR$/src/jsMain/kotlin;/home/rnentjes/Development/komp/komp/build/externals/komp-jsLegacy/src;/home/rnentjes/Development/komp/komp/build/externals/komp-jsIr/src;/home/rnentjes/Development/komp/komp/src/jsTest/kotlin">
<configuration version="3" platform="Common (experimental) " allPlatforms="JS []/JVM [1.8]/Native []/Native [general]" useProjectSettings="false" isTestModule="false" externalProjectId="komp" pureKotlinSourceFolders="$MODULE_DIR$/src/jsMain/kotlin;/home/rnentjes/Development/komp/komp/build/externals/komp-js-legacy/src;/home/rnentjes/Development/komp/komp/build/externals/komp-js-ir/src;/home/rnentjes/Development/komp/komp/src/jsTest/kotlin">
<newMppModelJpsModuleKind>SOURCE_SET_HOLDER</newMppModelJpsModuleKind>
<compilerSettings />
<compilerArguments>
<option name="languageVersion" value="1.4" />
<option name="apiVersion" value="1.4" />
<option name="languageVersion" value="1.5" />
<option name="apiVersion" value="1.5" />
<option name="pluginOptions">
<array />
</option>
<option name="pluginClasspaths">
<array>
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-scripting-jvm/1.4.32/49656d531bfab9d6e45d3f27bc4d03b542d6766/kotlin-scripting-jvm-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-scripting-common/1.4.32/6abda0fe69677f0e46e7539fd185e4bd093b7258/kotlin-scripting-common-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-scripting-jvm/1.5.21/8143908a15163e634fecb87013ed4a139170b032/kotlin-scripting-jvm-1.5.21.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-scripting-common/1.5.21/5d271f9e7e7191902f8c0d45c600f5b57a284036/kotlin-scripting-common-1.5.21.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-core/1.3.8/f62be6d4cbf27781c2969867b4ed952f38378492/kotlinx-coroutines-core-1.3.8.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.4.32/461367948840adbb0839c51d91ed74ef4a9ccb52/kotlin-stdlib-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.4.32/ef50bfa2c0491a11dcc35d9822edbfd6170e1ea2/kotlin-stdlib-common-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.5.21/2f537cad7e9eeb9da73738c8812e1e4cf9b62e4e/kotlin-stdlib-1.5.21.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-script-runtime/1.4.32/bac50b0748be017dbc13fc1cb7231b1c9da0e106/kotlin-script-runtime-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.5.21/cc8bf3586fd2ebcf234058b9440bb406e62dfacb/kotlin-stdlib-common-1.5.21.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-script-runtime/1.5.21/96d49e89873fde985750af354b6eabb60cfa999b/kotlin-script-runtime-1.5.21.jar" />
</array>
</option>
<option name="multiPlatform" value="true" />
@@ -32,7 +32,7 @@
<content url="file://$MODULE_DIR$/src/commonMain" />
<orderEntry type="jdk" jdkName="Kotlin SDK" jdkType="KotlinSDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-common:1.4.32" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlinx:kotlinx-html-common:0.7.2" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-common:1.5.21" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlinx:kotlinx-html-common:0.7.3" level="project" />
</component>
</module>

View File

@@ -1,28 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="komp:commonTest" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.type="sourceSet" external.system.module.version="0.3.0-SNAPSHOT" type="JAVA_MODULE" version="4">
<module external.linked.project.id="komp:commonTest" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.type="sourceSet" external.system.module.version="0.5.6-SNAPSHOT" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="Common (experimental) " allPlatforms="JS []/JVM [1.8]/Native []/Native [general]" useProjectSettings="false" isTestModule="true" externalProjectId="komp" pureKotlinSourceFolders="$MODULE_DIR$/src/jsMain/kotlin;/home/rnentjes/Development/komp/komp/build/externals/komp-jsLegacy/src;/home/rnentjes/Development/komp/komp/build/externals/komp-jsIr/src;/home/rnentjes/Development/komp/komp/src/jsTest/kotlin">
<configuration version="3" platform="Common (experimental) " allPlatforms="JS []/JVM [1.8]/Native []/Native [general]" useProjectSettings="false" isTestModule="true" externalProjectId="komp" pureKotlinSourceFolders="$MODULE_DIR$/src/jsMain/kotlin;/home/rnentjes/Development/komp/komp/build/externals/komp-js-legacy/src;/home/rnentjes/Development/komp/komp/build/externals/komp-js-ir/src;/home/rnentjes/Development/komp/komp/src/jsTest/kotlin">
<newMppModelJpsModuleKind>SOURCE_SET_HOLDER</newMppModelJpsModuleKind>
<externalSystemTestTasks>
<externalSystemTestTask>jsLegacyBrowserTest|komp:jsTest|jsLegacy</externalSystemTestTask>
</externalSystemTestTasks>
<compilerSettings />
<compilerArguments>
<option name="languageVersion" value="1.4" />
<option name="apiVersion" value="1.4" />
<option name="languageVersion" value="1.5" />
<option name="apiVersion" value="1.5" />
<option name="pluginOptions">
<array />
</option>
<option name="pluginClasspaths">
<array>
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-scripting-jvm/1.4.32/49656d531bfab9d6e45d3f27bc4d03b542d6766/kotlin-scripting-jvm-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-scripting-common/1.4.32/6abda0fe69677f0e46e7539fd185e4bd093b7258/kotlin-scripting-common-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-scripting-jvm/1.5.21/8143908a15163e634fecb87013ed4a139170b032/kotlin-scripting-jvm-1.5.21.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-scripting-common/1.5.21/5d271f9e7e7191902f8c0d45c600f5b57a284036/kotlin-scripting-common-1.5.21.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-core/1.3.8/f62be6d4cbf27781c2969867b4ed952f38378492/kotlinx-coroutines-core-1.3.8.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.4.32/461367948840adbb0839c51d91ed74ef4a9ccb52/kotlin-stdlib-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.4.32/ef50bfa2c0491a11dcc35d9822edbfd6170e1ea2/kotlin-stdlib-common-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.5.21/2f537cad7e9eeb9da73738c8812e1e4cf9b62e4e/kotlin-stdlib-1.5.21.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-script-runtime/1.4.32/bac50b0748be017dbc13fc1cb7231b1c9da0e106/kotlin-script-runtime-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.5.21/cc8bf3586fd2ebcf234058b9440bb406e62dfacb/kotlin-stdlib-common-1.5.21.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-script-runtime/1.5.21/96d49e89873fde985750af354b6eabb60cfa999b/kotlin-script-runtime-1.5.21.jar" />
</array>
</option>
<option name="multiPlatform" value="true" />
@@ -36,9 +36,9 @@
<orderEntry type="jdk" jdkName="Kotlin SDK" jdkType="KotlinSDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="komp.commonMain" scope="TEST" />
<orderEntry type="library" scope="TEST" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-js:1.4.32" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.jetbrains.kotlinx:kotlinx-html-common:0.7.2" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-common:1.4.32" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-common:1.5.21" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-js:1.5.21" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.jetbrains.kotlinx:kotlinx-html-common:0.7.3" level="project" />
</component>
<component name="TestModuleProperties" production-module="komp.commonMain" />
</module>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="komp" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.version="0.3.0-SNAPSHOT" type="JAVA_MODULE" version="4">
<module external.linked.project.id="komp" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.version="0.5.6-SNAPSHOT" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">

230
komp.ipr
View File

@@ -61,6 +61,48 @@
<element id="module-output" name="komp.jsMain" />
</root>
</artifact>
<artifact type="jar" name="komp-jslegacy-0.4.0-SNAPSHOT">
<output-path>$PROJECT_DIR$/build/libs</output-path>
<root id="archive" name="komp-jslegacy-0.4.0-SNAPSHOT.jar">
<element id="module-output" name="komp.jsMain" />
</root>
</artifact>
<artifact type="jar" name="komp-jslegacy-0.4.1">
<output-path>$PROJECT_DIR$/build/libs</output-path>
<root id="archive" name="komp-jslegacy-0.4.1.jar">
<element id="module-output" name="komp.jsMain" />
</root>
</artifact>
<artifact type="jar" name="komp-jslegacy-0.5.1">
<output-path>$PROJECT_DIR$/build/libs</output-path>
<root id="archive" name="komp-jslegacy-0.5.1.jar">
<element id="module-output" name="komp.jsMain" />
</root>
</artifact>
<artifact type="jar" name="komp-jslegacy-0.5.2">
<output-path>$PROJECT_DIR$/build/libs</output-path>
<root id="archive" name="komp-jslegacy-0.5.2.jar">
<element id="module-output" name="komp.jsMain" />
</root>
</artifact>
<artifact type="jar" name="komp-jslegacy-0.5.3">
<output-path>$PROJECT_DIR$/build/libs</output-path>
<root id="archive" name="komp-jslegacy-0.5.3.jar">
<element id="module-output" name="komp.jsMain" />
</root>
</artifact>
<artifact type="jar" name="komp-jslegacy-0.5.4">
<output-path>$PROJECT_DIR$/build/libs</output-path>
<root id="archive" name="komp-jslegacy-0.5.4.jar">
<element id="module-output" name="komp.jsMain" />
</root>
</artifact>
<artifact type="jar" name="komp-jslegacy-0.5.6-SNAPSHOT">
<output-path>$PROJECT_DIR$/build/libs</output-path>
<root id="archive" name="komp-jslegacy-0.5.6-SNAPSHOT.jar">
<element id="module-output" name="komp.jsMain" />
</root>
</artifact>
</component>
<component name="CheckStyle-IDEA">
<option name="configuration">
@@ -260,6 +302,80 @@
</group>
</component>
<component name="PhpWorkspaceProjectConfiguration" backward_compatibility_performed="true" />
<component name="ProjectCodeStyleConfiguration">
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
<code_scheme name="Project" version="173">
<option name="LINE_SEPARATOR" value="&#10;" />
<option name="RIGHT_MARGIN" value="140" />
<H2CodeStyleSettings version="6">
<option name="USE_GENERAL_STYLE" value="false" />
</H2CodeStyleSettings>
<H2CodeStyleSettings version="6">
<option name="USE_GENERAL_STYLE" value="false" />
</H2CodeStyleSettings>
<JavaCodeStyleSettings>
<option name="ANNOTATION_PARAMETER_WRAP" value="5" />
<option name="ALIGN_MULTILINE_ANNOTATION_PARAMETERS" value="true" />
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="50" />
</JavaCodeStyleSettings>
<JetCodeStyleSettings>
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="99" />
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="99" />
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<codeStyleSettings language="JAVA">
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="ALIGN_MULTILINE_CHAINED_METHODS" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION" value="true" />
<option name="ALIGN_GROUP_FIELD_DECLARATIONS" value="true" />
<option name="ALIGN_CONSECUTIVE_VARIABLE_DECLARATIONS" value="true" />
<option name="ALIGN_CONSECUTIVE_ASSIGNMENTS" value="true" />
<option name="ALIGN_SUBSEQUENT_SIMPLE_METHODS" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="5" />
<option name="CALL_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
<option name="CALL_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
<option name="RESOURCE_LIST_WRAP" value="5" />
<option name="RESOURCE_LIST_LPAREN_ON_NEXT_LINE" value="true" />
<option name="RESOURCE_LIST_RPAREN_ON_NEXT_LINE" value="true" />
<option name="EXTENDS_LIST_WRAP" value="5" />
<option name="THROWS_LIST_WRAP" value="5" />
<option name="THROWS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="5" />
<option name="PARENTHESES_EXPRESSION_LPAREN_WRAP" value="true" />
<option name="PARENTHESES_EXPRESSION_RPAREN_WRAP" value="true" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="FOR_STATEMENT_LPAREN_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_RPAREN_ON_NEXT_LINE" value="true" />
<option name="ARRAY_INITIALIZER_WRAP" value="5" />
<option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true" />
<option name="ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE" value="true" />
<option name="ASSERT_STATEMENT_WRAP" value="5" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="DOWHILE_BRACE_FORCE" value="3" />
<option name="WHILE_BRACE_FORCE" value="3" />
<option name="FOR_BRACE_FORCE" value="3" />
<option name="ENUM_CONSTANTS_WRAP" value="5" />
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/komp.iml" filepath="$PROJECT_DIR$/komp.iml" />
@@ -310,6 +426,13 @@
<option name="url" value="https://jcenter.bintray.com/" />
</remote-repository>
</component>
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
</set>
</option>
</component>
<component name="RunManager">
<configuration default="true" type="Applet" factoryName="Applet">
<option name="WIDTH" value="400" />
@@ -373,129 +496,58 @@
<mapping directory="" vcs="Git" />
</component>
<component name="accountSettings">
<option name="activeRegion" value="us-east-1" />
<option name="recentlyUsedRegions">
<list>
<option value="us-east-1" />
</list>
</option>
</component>
<component name="libraries-with-intellij-classes">
<option name="intellijApiContainingLibraries">
<list>
<LibraryCoordinatesState>
<option name="artifactId" value="ideaIU" />
<option name="groupId" value="com.jetbrains.intellij.idea" />
</LibraryCoordinatesState>
<LibraryCoordinatesState>
<option name="artifactId" value="ideaIU" />
<option name="groupId" value="com.jetbrains" />
</LibraryCoordinatesState>
<LibraryCoordinatesState>
<option name="artifactId" value="ideaIC" />
<option name="groupId" value="com.jetbrains.intellij.idea" />
</LibraryCoordinatesState>
<LibraryCoordinatesState>
<option name="artifactId" value="ideaIC" />
<option name="groupId" value="com.jetbrains" />
</LibraryCoordinatesState>
<LibraryCoordinatesState>
<option name="artifactId" value="pycharmPY" />
<option name="groupId" value="com.jetbrains.intellij.pycharm" />
</LibraryCoordinatesState>
<LibraryCoordinatesState>
<option name="artifactId" value="pycharmPY" />
<option name="groupId" value="com.jetbrains" />
</LibraryCoordinatesState>
<LibraryCoordinatesState>
<option name="artifactId" value="pycharmPC" />
<option name="groupId" value="com.jetbrains.intellij.pycharm" />
</LibraryCoordinatesState>
<LibraryCoordinatesState>
<option name="artifactId" value="pycharmPC" />
<option name="groupId" value="com.jetbrains" />
</LibraryCoordinatesState>
<LibraryCoordinatesState>
<option name="artifactId" value="clion" />
<option name="groupId" value="com.jetbrains.intellij.clion" />
</LibraryCoordinatesState>
<LibraryCoordinatesState>
<option name="artifactId" value="clion" />
<option name="groupId" value="com.jetbrains" />
</LibraryCoordinatesState>
<LibraryCoordinatesState>
<option name="artifactId" value="riderRD" />
<option name="groupId" value="com.jetbrains.intellij.rider" />
</LibraryCoordinatesState>
<LibraryCoordinatesState>
<option name="artifactId" value="riderRD" />
<option name="groupId" value="com.jetbrains" />
</LibraryCoordinatesState>
</list>
</option>
</component>
<component name="libraryTable">
<library name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-common:1.4.32" type="kotlin.common">
<library name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-common:1.5.21" type="kotlin.common">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.4.32/ef50bfa2c0491a11dcc35d9822edbfd6170e1ea2/kotlin-stdlib-common-1.4.32.jar!/" />
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.5.21/cc8bf3586fd2ebcf234058b9440bb406e62dfacb/kotlin-stdlib-common-1.5.21.jar!/" />
</CLASSES>
<JAVADOC />
<JAVADOC>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.5.21/5b8f86fea035328fc9e8c660773037a3401ce25f/kotlin-stdlib-common-1.5.21-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.4.32/f3e47c26a177728549b3dd2a624fec333aa17b36/kotlin-stdlib-common-1.4.32-sources.jar!/" />
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.5.21/64f0dd5eac2d479a65bc077185d9a8f661c948fe/kotlin-stdlib-common-1.5.21-sources.jar!/" />
</SOURCES>
</library>
<library name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-js:1.4.32" type="kotlin.js">
<library name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-js:1.5.21" type="kotlin.js">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-js/1.4.32/8dca0e318b64909eecfb2d00a9d045562f3e66f8/kotlin-stdlib-js-1.4.32.jar!/" />
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-js/1.5.21/9b22e0c2e0dcf2ba9f27e45a48944d05b0384bc3/kotlin-stdlib-js-1.5.21.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-js/1.4.32/5729944dc91bf28689461fe44b9e401fd41a84a7/kotlin-stdlib-js-1.4.32-sources.jar!/" />
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-js/1.5.21/dcd3e87dab1d7ecc7f2952d5d213e20f977bbddc/kotlin-stdlib-js-1.5.21-sources.jar!/" />
</SOURCES>
</library>
<library name="Gradle: org.jetbrains.kotlin:kotlin-test-annotations-common:1.4.32" type="kotlin.common">
<library name="Gradle: org.jetbrains.kotlin:kotlin-test-js:1.5.21" type="kotlin.js">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test-annotations-common/1.4.32/f242cb223feb6d44e79588c26ca66bf57b0bc3a8/kotlin-test-annotations-common-1.4.32.jar!/" />
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test-js/1.5.21/db9c8e994715fb1edd5bef91db179b60347cbfc9/kotlin-test-js-1.5.21.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test-annotations-common/1.4.32/57512e29ee20defe37d54ce19507d599b0f2113/kotlin-test-annotations-common-1.4.32-sources.jar!/" />
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test-js/1.5.21/8e70170db077d3f421c3fb6d24468b3938990f4a/kotlin-test-js-1.5.21-sources.jar!/" />
</SOURCES>
</library>
<library name="Gradle: org.jetbrains.kotlin:kotlin-test-common:1.4.32" type="kotlin.common">
<library name="Gradle: org.jetbrains.kotlinx:kotlinx-html-common:0.7.3" type="kotlin.common">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test-common/1.4.32/a10168dd408319a4af03763ad11f12e0fc1fc5ba/kotlin-test-common-1.4.32.jar!/" />
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-html-common/0.7.3/4f3df7b2096bce6fef3e532ca1ccff13bd15a6bc/kotlinx-html-metadata-0.7.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test-common/1.4.32/d1818d1bdc457b51289f006884a260b56a55cb77/kotlin-test-common-1.4.32-sources.jar!/" />
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-html-common/0.7.3/f4eb48699d893b863f142a3c30e1ddddd13b876/kotlinx-html-common-0.7.3-sources.jar!/" />
</SOURCES>
</library>
<library name="Gradle: org.jetbrains.kotlin:kotlin-test-js:1.4.32" type="kotlin.js">
<library name="Gradle: org.jetbrains.kotlinx:kotlinx-html-js:0.7.3" type="kotlin.js">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test-js/1.4.32/f4b4bf663acffeff2a664677b9e780f206f6842f/kotlin-test-js-1.4.32.jar!/" />
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-html-js/0.7.3/93a1ab4269d3a567e05088d1237eedbc2efd03c9/kotlinx-html-jslegacy-0.7.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test-js/1.4.32/8e70170db077d3f421c3fb6d24468b3938990f4a/kotlin-test-js-1.4.32-sources.jar!/" />
</SOURCES>
</library>
<library name="Gradle: org.jetbrains.kotlinx:kotlinx-html-common:0.7.2" type="kotlin.common">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-html-common/0.7.2/7da838083337896b558cab2884c4118709a58769/kotlinx-html-metadata-0.7.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-html-common/0.7.2/866bbbfe0a81d49cdf19fd149adafbb938b35be4/kotlinx-html-common-0.7.2-sources.jar!/" />
</SOURCES>
</library>
<library name="Gradle: org.jetbrains.kotlinx:kotlinx-html-js:0.7.2" type="kotlin.js">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-html-js/0.7.2/baf7e494e549776d0ae3e0ee225804a513f5dc26/kotlinx-html-jslegacy-0.7.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-html-js/0.7.2/b09bfd3565058174afa3fd0888743f8b8dca5406/kotlinx-html-js-0.7.2-sources.jar!/" />
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-html-js/0.7.3/fc3bc71d1c037b715689112c95c44b96bb2409ea/kotlinx-html-js-0.7.3-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="komp:jsMain" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.type="sourceSet" external.system.module.version="0.3.0-SNAPSHOT" type="JAVA_MODULE" version="4">
<module external.linked.project.id="komp:jsMain" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.type="sourceSet" external.system.module.version="0.5.6-SNAPSHOT" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="JavaScript " allPlatforms="JS []" useProjectSettings="false" isTestModule="false" externalProjectId="komp" pureKotlinSourceFolders="$MODULE_DIR$/src/jsMain/kotlin;/home/rnentjes/Development/komp/komp/build/externals/komp-jsLegacy/src;/home/rnentjes/Development/komp/komp/build/externals/komp-jsIr/src;/home/rnentjes/Development/komp/komp/src/jsTest/kotlin">
<configuration version="3" platform="JavaScript " allPlatforms="JS []" useProjectSettings="false" isTestModule="false" externalProjectId="komp" pureKotlinSourceFolders="$MODULE_DIR$/src/jsMain/kotlin;/home/rnentjes/Development/komp/komp/build/externals/komp-js-legacy/src;/home/rnentjes/Development/komp/komp/build/externals/komp-js-ir/src;/home/rnentjes/Development/komp/komp/src/jsTest/kotlin">
<dependsOnModuleNames>komp:commonMain</dependsOnModuleNames>
<sourceSets>
<sourceSet>komp.commonMain</sourceSet>
@@ -10,25 +10,25 @@
<newMppModelJpsModuleKind>COMPILATION_AND_SOURCE_SET_HOLDER</newMppModelJpsModuleKind>
<compilerSettings />
<compilerArguments>
<option name="outputFile" value="$MODULE_DIR$/build/js/packages/komp-jsLegacy/kotlin/komp-jsLegacy.js" />
<option name="outputFile" value="$MODULE_DIR$/build/js/packages/komp-js-legacy/kotlin/komp-js-legacy.js" />
<option name="noStdlib" value="true" />
<option name="sourceMap" value="true" />
<option name="metaInfo" value="true" />
<option name="target" value="v5" />
<option name="moduleKind" value="umd" />
<option name="main" value="call" />
<option name="languageVersion" value="1.4" />
<option name="apiVersion" value="1.4" />
<option name="languageVersion" value="1.5" />
<option name="apiVersion" value="1.5" />
<option name="pluginOptions">
<array />
</option>
<option name="pluginClasspaths">
<array>
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-script-runtime/1.4.32/bac50b0748be017dbc13fc1cb7231b1c9da0e106/kotlin-script-runtime-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-scripting-common/1.4.32/6abda0fe69677f0e46e7539fd185e4bd093b7258/kotlin-scripting-common-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-scripting-jvm/1.4.32/49656d531bfab9d6e45d3f27bc4d03b542d6766/kotlin-scripting-jvm-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.4.32/ef50bfa2c0491a11dcc35d9822edbfd6170e1ea2/kotlin-stdlib-common-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.4.32/461367948840adbb0839c51d91ed74ef4a9ccb52/kotlin-stdlib-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-script-runtime/1.5.21/96d49e89873fde985750af354b6eabb60cfa999b/kotlin-script-runtime-1.5.21.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-scripting-common/1.5.21/5d271f9e7e7191902f8c0d45c600f5b57a284036/kotlin-scripting-common-1.5.21.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-scripting-jvm/1.5.21/8143908a15163e634fecb87013ed4a139170b032/kotlin-scripting-jvm-1.5.21.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.5.21/cc8bf3586fd2ebcf234058b9440bb406e62dfacb/kotlin-stdlib-common-1.5.21.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.5.21/2f537cad7e9eeb9da73738c8812e1e4cf9b62e4e/kotlin-stdlib-1.5.21.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-core/1.3.8/f62be6d4cbf27781c2969867b4ed952f38378492/kotlinx-coroutines-core-1.3.8.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar" />
</array>
@@ -42,18 +42,18 @@
</facet>
</component>
<component name="NewModuleRootManager">
<output url="file://$MODULE_DIR$/build/js/packages/komp-jsLegacy/kotlin" />
<output url="file://$MODULE_DIR$/build/js/packages/komp-js-legacy/kotlin" />
<exclude-output />
<content url="file://$MODULE_DIR$/build/externals/komp-jsIr/src" />
<content url="file://$MODULE_DIR$/build/externals/komp-jsLegacy/src" />
<content url="file://$MODULE_DIR$/build/externals/komp-js-ir/src" />
<content url="file://$MODULE_DIR$/build/externals/komp-js-legacy/src" />
<content url="file://$MODULE_DIR$/src/jsMain">
<sourceFolder url="file://$MODULE_DIR$/src/jsMain/kotlin" type="kotlin-source" />
</content>
<orderEntry type="jdk" jdkName="Kotlin SDK" jdkType="KotlinSDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="komp.commonMain" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlinx:kotlinx-html-js:0.7.2" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-js:1.4.32" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-common:1.4.32" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlinx:kotlinx-html-js:0.7.3" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-js:1.5.21" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-common:1.5.21" level="project" />
</component>
</module>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="komp:jsTest" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.type="sourceSet" external.system.module.version="0.3.0-SNAPSHOT" type="JAVA_MODULE" version="4">
<module external.linked.project.id="komp:jsTest" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="nl.astraeus" external.system.module.type="sourceSet" external.system.module.version="0.5.6-SNAPSHOT" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="JavaScript " allPlatforms="JS []" useProjectSettings="false" isTestModule="true" externalProjectId="komp" pureKotlinSourceFolders="$MODULE_DIR$/src/jsMain/kotlin;/home/rnentjes/Development/komp/komp/build/externals/komp-jsLegacy/src;/home/rnentjes/Development/komp/komp/build/externals/komp-jsIr/src;/home/rnentjes/Development/komp/komp/src/jsTest/kotlin">
<configuration version="3" platform="JavaScript " allPlatforms="JS []" useProjectSettings="false" isTestModule="true" externalProjectId="komp" pureKotlinSourceFolders="$MODULE_DIR$/src/jsMain/kotlin;/home/rnentjes/Development/komp/komp/build/externals/komp-js-legacy/src;/home/rnentjes/Development/komp/komp/build/externals/komp-js-ir/src;/home/rnentjes/Development/komp/komp/src/jsTest/kotlin">
<dependsOnModuleNames>komp:commonTest</dependsOnModuleNames>
<sourceSets>
<sourceSet>komp.commonTest</sourceSet>
@@ -15,25 +15,25 @@
</externalSystemTestTasks>
<compilerSettings />
<compilerArguments>
<option name="outputFile" value="$MODULE_DIR$/build/js/packages/komp-jsLegacy-test/kotlin/komp-jsLegacy-test.js" />
<option name="outputFile" value="$MODULE_DIR$/build/js/packages/komp-js-legacy-test/kotlin/komp-js-legacy-test.js" />
<option name="noStdlib" value="true" />
<option name="sourceMap" value="true" />
<option name="metaInfo" value="true" />
<option name="target" value="v5" />
<option name="moduleKind" value="umd" />
<option name="main" value="call" />
<option name="languageVersion" value="1.4" />
<option name="apiVersion" value="1.4" />
<option name="languageVersion" value="1.5" />
<option name="apiVersion" value="1.5" />
<option name="pluginOptions">
<array />
</option>
<option name="pluginClasspaths">
<array>
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-script-runtime/1.4.32/bac50b0748be017dbc13fc1cb7231b1c9da0e106/kotlin-script-runtime-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-scripting-common/1.4.32/6abda0fe69677f0e46e7539fd185e4bd093b7258/kotlin-scripting-common-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-scripting-jvm/1.4.32/49656d531bfab9d6e45d3f27bc4d03b542d6766/kotlin-scripting-jvm-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.4.32/ef50bfa2c0491a11dcc35d9822edbfd6170e1ea2/kotlin-stdlib-common-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.4.32/461367948840adbb0839c51d91ed74ef4a9ccb52/kotlin-stdlib-1.4.32.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-script-runtime/1.5.21/96d49e89873fde985750af354b6eabb60cfa999b/kotlin-script-runtime-1.5.21.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-scripting-common/1.5.21/5d271f9e7e7191902f8c0d45c600f5b57a284036/kotlin-scripting-common-1.5.21.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-scripting-jvm/1.5.21/8143908a15163e634fecb87013ed4a139170b032/kotlin-scripting-jvm-1.5.21.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.5.21/cc8bf3586fd2ebcf234058b9440bb406e62dfacb/kotlin-stdlib-common-1.5.21.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.5.21/2f537cad7e9eeb9da73738c8812e1e4cf9b62e4e/kotlin-stdlib-1.5.21.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-core/1.3.8/f62be6d4cbf27781c2969867b4ed952f38378492/kotlinx-coroutines-core-1.3.8.jar" />
<option value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar" />
</array>
@@ -47,7 +47,7 @@
</facet>
</component>
<component name="NewModuleRootManager">
<output-test url="file://$MODULE_DIR$/build/js/packages/komp-jsLegacy-test/kotlin" />
<output-test url="file://$MODULE_DIR$/build/js/packages/komp-js-legacy-test/kotlin" />
<exclude-output />
<content url="file://$MODULE_DIR$/src/jsTest">
<sourceFolder url="file://$MODULE_DIR$/src/jsTest/kotlin" type="kotlin-test" />
@@ -58,13 +58,29 @@
<orderEntry type="module" module-name="komp.commonTest" scope="TEST" production-on-test="" />
<orderEntry type="module" module-name="komp.jsMain" scope="TEST" />
<orderEntry type="module" module-name="komp.jsMain" scope="RUNTIME" />
<orderEntry type="library" scope="TEST" name="Gradle: org.jetbrains.kotlinx:kotlinx-html-js:0.7.2" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.jetbrains.kotlin:kotlin-test-js:1.4.32" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-js:1.4.32" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.jetbrains.kotlinx:kotlinx-html-common:0.7.2" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-common:1.4.32" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.jetbrains.kotlin:kotlin-test-common:1.4.32" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.jetbrains.kotlin:kotlin-test-annotations-common:1.4.32" level="project" />
<orderEntry type="module-library" scope="PROVIDED">
<library name="Gradle: nl.astraeus:komp">
<CLASSES>
<root url="file://$MODULE_DIR$/build/classes/kotlin/jsIr/main" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" scope="RUNTIME">
<library>
<CLASSES>
<root url="file://$MODULE_DIR$/build/processedResources/jsIr/main" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="library" scope="TEST" name="Gradle: org.jetbrains.kotlinx:kotlinx-html-js:0.7.3" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.jetbrains.kotlin:kotlin-test-js:1.5.21" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.jetbrains.kotlinx:kotlinx-html-common:0.7.3" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-js:1.5.21" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-common:1.5.21" level="project" />
</component>
<component name="TestModuleProperties" production-module="komp.jsMain" />
</module>

View File

@@ -12,5 +12,3 @@ pluginManagement {
}
rootProject.name = "komp"
enableFeaturePreview("GRADLE_METADATA")

View File

@@ -1,206 +0,0 @@
package nl.astraeus.komp
import org.w3c.dom.HTMLElement
import org.w3c.dom.HTMLInputElement
import org.w3c.dom.Node
import org.w3c.dom.get
object DiffPatch {
private fun updateKomponentOnNode(element: Node, newVdom: VDOMElement) {
val komponent = newVdom.komponent
if (komponent != null) {
if (Komponent.logReplaceEvent) {
console.log("Keeping oldNode, set oldNode element on Komponent", element, komponent)
}
komponent.element = element
}
}
fun updateNode(element: Node, oldVdom: VDOMElement, newVdom: VDOMElement): Node {
if (oldVdom.hash == newVdom.hash) {
if (Komponent.logReplaceEvent) {
console.log("Hashes match", oldVdom, newVdom, oldVdom.hash, newVdom.hash)
}
// no change
return element
}
if (oldVdom.type == newVdom.type && oldVdom.type == VDOMElementType.TEXT) {
if (oldVdom.content != newVdom.content) {
if (Komponent.logReplaceEvent) {
console.log("Updating text content", oldVdom, newVdom)
}
element.textContent = newVdom.content
}
return element
}
if (oldVdom.type == newVdom.type && oldVdom.type == VDOMElementType.TAG) {
if (oldVdom.content == newVdom.content) {
if (Komponent.logReplaceEvent) {
console.log("Update attributes", oldVdom.content, newVdom.content)
}
updateAttributes(element as HTMLElement, oldVdom, newVdom)
if (Komponent.logReplaceEvent) {
console.log("Update events", oldVdom.content, newVdom.content)
}
updateEvents(element as HTMLElement, oldVdom, newVdom)
if (Komponent.logReplaceEvent) {
console.log("Update children", oldVdom.content, newVdom.content)
}
updateKomponentOnNode(element, newVdom)
updateChildren(element, oldVdom, newVdom)
return element
}
}
if (Komponent.logReplaceEvent) {
console.log("Replace node (type)", newVdom.type, oldVdom, newVdom)
}
val newNode = newVdom.createElement()
updateKomponentOnNode(newNode, newVdom)
element.parentNode?.replaceChild(newNode, element)
return newNode
}
private fun updateAttributes(element: HTMLElement, oldVdom: VDOMElement, newVdom: VDOMElement) {
// removed attributes
for ((name, attr) in oldVdom.attributes) {
if (newVdom.attributes[name] == null) {
element.removeAttribute(name)
}
}
for ((name, value) in newVdom.attributes) {
val oldValue = oldVdom.attributes[name]
if (value != oldValue) {
element.setAttribute(name, value)
}
}
if (newVdom.content == "input" && oldVdom.content == "input") {
if (element is HTMLInputElement) {
element.value = newVdom.attributes["value"] ?: ""
element.checked = newVdom.attributes["checked"] == "true"
}
}
}
private fun updateChildren(
element: HTMLElement,
oldVdom: VDOMElement,
newVdom: VDOMElement
) {
var oldIndex = 0
var newIndex = 0
if (Komponent.logReplaceEvent) {
console.log(
"updateChildren HTML old(${oldVdom.childNodes.size})",
oldVdom.toString()
)
console.log(
"updateChildren HTML new(${newVdom.childNodes.size})",
newVdom.toString()
)
}
while (oldIndex < oldVdom.childNodes.size && newIndex < newVdom.childNodes.size) {
if (Komponent.logReplaceEvent) {
console.log("Update Old/new", oldIndex, newIndex)
}
val oldChildNode = oldVdom.childNodes[oldIndex]
val newChildNode = newVdom.childNodes[newIndex]
if (Komponent.logReplaceEvent) {
console.log("Update node Old/new", oldChildNode, newChildNode)
}
// scenarios:
// - hashes match, next
// - hashes don't match:
// -- old hash is down in new list
// --- delta == 1, insert new node
// -- new hash is down in old list
// --- delta == 1, remove current else swap?
// else: replace current node with new
if (oldVdom.hash != newVdom.hash &&
newChildNode.type == VDOMElementType.TAG &&
oldChildNode.type == VDOMElementType.TAG
) {
if (Komponent.logReplaceEvent) {
console.log("Hashes don't match")
}
val oldHash = oldChildNode.hash.hashCode()
val newHash = newChildNode.hash.hashCode()
val newHashIndexInOld = oldVdom.findNodeHashIndex(newHash)
val oldHashIndexInNew = newVdom.findNodeHashIndex(oldHash)
if (newHashIndexInOld == oldIndex + 1 && oldHashIndexInNew == newIndex) {
// remove
element.removeChild(element.childNodes[oldIndex]!!)
oldIndex++
continue
} else if (newHashIndexInOld == oldIndex && oldHashIndexInNew == newIndex + 1) {
// insert
element.insertBefore(newChildNode.createElement(), element.childNodes[oldIndex]!!)
newIndex++
oldIndex++
continue
}
}
// update
updateNode(element.childNodes[oldIndex]!!, oldChildNode, newChildNode)
oldIndex++
newIndex++
}
while (element.childNodes.length > newVdom.childNodes.size) {
element.childNodes[element.childNodes.length - 1]?.also {
if (Komponent.logReplaceEvent) {
console.log("Remove old node", it)
}
element.removeChild(it)
}
}
while (newIndex < newVdom.childNodes.size) {
newVdom.childNodes[newIndex].also {
element.appendChild(it.createElement())
}
newIndex++
}
}
private fun updateEvents(element: HTMLElement, oldVdom: VDOMElement, newVdom: VDOMElement) {
val oldEvents = oldVdom.events
val newEvents = newVdom.events
if (Komponent.logReplaceEvent) {
console.log("Update events", oldEvents, newEvents)
}
for ((name, event) in oldEvents) {
element.removeEventListener(name, event)
}
for ((name, event) in newEvents) {
if (Komponent.logReplaceEvent) {
console.log("Set event $event on", element)
}
element.addEventListener(name, event)
}
}
}

View File

@@ -1,311 +1,521 @@
package nl.astraeus.komp
import kotlinx.browser.document
import kotlinx.html.*
import kotlinx.html.DefaultUnsafe
import kotlinx.html.Entities
import kotlinx.html.FlowOrMetaDataOrPhrasingContent
import kotlinx.html.Tag
import kotlinx.html.TagConsumer
import kotlinx.html.Unsafe
import org.w3c.dom.Element
import org.w3c.dom.HTMLElement
import org.w3c.dom.HTMLInputElement
import org.w3c.dom.HTMLSpanElement
import org.w3c.dom.Node
import org.w3c.dom.asList
import org.w3c.dom.events.Event
import kotlin.collections.MutableList
import kotlin.collections.MutableMap
import kotlin.collections.arrayListOf
import kotlin.collections.component1
import kotlin.collections.component2
import kotlin.collections.isNotEmpty
import kotlin.collections.iterator
import kotlin.collections.last
import kotlin.collections.lastIndex
import kotlin.collections.mutableListOf
import kotlin.collections.mutableMapOf
import kotlin.collections.set
import kotlin.collections.withIndex
import org.w3c.dom.get
private fun attributeHash(key: String, value: String): Int =
3 * key.hashCode() +
5 * value.hashCode()
private var currentElement: Element? = null
private fun MutableMap<String, String>.kompHash(): Int {
var result = 0
interface HtmlConsumer : TagConsumer<Element> {
fun append(node: Element)
fun include(komponent: Komponent)
fun debug(block: HtmlConsumer.() -> Unit)
}
for ((name, value) in this) {
result += attributeHash(name, value)
fun Int.asSpaces(): String {
val result = StringBuilder()
repeat(this) {
result.append(" ")
}
return result.toString()
}
fun FlowOrMetaDataOrPhrasingContent.currentElement(): Element =
currentElement ?: error("No current element defined!")
fun Element.printTree(indent: Int = 0): String {
val result = StringBuilder()
result.append(indent.asSpaces())
result.append(tagName)
if (this.namespaceURI != "http://www.w3.org/1999/xhtml") {
result.append(" [")
result.append(namespaceURI)
result.append("]")
}
result.append(" (")
var first = true
if (hasAttributes()) {
for (index in 0 until attributes.length) {
if (!first) {
result.append(", ")
} else {
first = false
}
result.append(attributes[index]?.localName)
result.append("=")
result.append(attributes[index]?.value)
}
}
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) {
result.append(it.printTree(indent + 2))
} else {
result.append((indent + 2).asSpaces())
result.append(it.textContent)
result.append("\n")
}
}
}
result.append(indent.asSpaces())
result.append("}\n")
return result.toString()
}
private fun Element.clearKompAttributes() {
val attributes = this.asDynamic()["komp-attributes"] as MutableSet<String>?
if (attributes == null) {
this.asDynamic()["komp-attributes"] = mutableSetOf<String>()
} else {
attributes.clear()
}
if (this is HTMLInputElement) {
this.checked = false
}
}
private fun Element.getKompAttributes(): MutableSet<String> {
var result: MutableSet<String>? = this.asDynamic()["komp-attributes"] as MutableSet<String>?
if (result == null) {
result = mutableSetOf()
this.asDynamic()["komp-attributes"] = result
}
return result
}
private fun MutableMap<String, (Event) -> Unit>.kompHash(): Int {
var result = 0
private fun Element.setKompAttribute(name: String, value: String) {
val setAttrs: MutableSet<String> = getKompAttributes()
setAttrs.add(name)
for ((name, event) in this) {
result += attributeHash(name, event.toString())
}
if (this is HTMLInputElement) {
when (name) {
"checked" -> {
this.checked = value == "checked"
}
"value" -> {
this.value = value
return result
}
private fun MutableList<VDOMElement>.kompHash(): Int {
var result = 0
for (vdom in this) {
result += 3 * vdom.hash.hashCode()
}
return result
}
enum class VDOMElementType {
TAG,
TEXT,
ENTITY,
UNSAFE,
COMMENT
}
class VDOMElementHash(
var baseHash: Int,
var contentHash: Int,
var typeHash: Int,
var namespaceHash: Int = 0,
var attributesHash: Int = 0,
var eventsHash: Int = 0,
var childNodesHash: Int = 0
) {
override fun hashCode(): Int = baseHash +
3 * contentHash +
5 * typeHash +
7 * namespaceHash +
11 * attributesHash +
13 * eventsHash +
15 * childNodesHash
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is VDOMElementHash) return false
return other.hashCode() == this.hashCode()
}
}
class VDOMElement(
val baseHash: Int,
var content: String,
var namespace: String? = null,
var type: VDOMElementType = VDOMElementType.TAG,
) {
val attributes: MutableMap<String, String> = mutableMapOf()
val events: MutableMap<String, (Event) -> Unit> = mutableMapOf()
val childNodes: MutableList<VDOMElement> = mutableListOf()
val hash = VDOMElementHash(
baseHash,
content.hashCode(),
type.hashCode()
)
var id: String = ""
set(value) {
field = value
attributes["id"] = value
}
var komponent: Komponent? = null
fun setKompEvent(event: String, value: (Event) -> Unit) {
val eventName = if (event.startsWith("on")) {
event.substring(2)
} else {
event
}
val recalculate = events.containsKey(eventName)
events[eventName] = value
if (recalculate) {
hash.eventsHash = events.kompHash()
} else {
hash.eventsHash += attributeHash(eventName, value.toString())
}
}
fun appendChild(element: VDOMElement) {
childNodes.add(element)
//hash.childNodesHash += element.hash.hashCode()
}
fun updateChildHash() {
hash.childNodesHash = childNodes.kompHash()
}
fun removeAttribute(attr: String) {
if (attributes.containsKey(attr)) {
hash.attributesHash -= attributeHash(attr, attributes[attr] ?: "")
}
attributes.remove(attr)
}
fun setAttribute(attr: String, value: String) {
if (attributes.containsKey(attr)) {
hash.attributesHash -= attributeHash(attr, attributes[attr] ?: "")
}
if (attr.toLowerCase() == "id") {
id = value
}
attributes[attr] = value
hash.attributesHash += attributeHash(attr, value)
}
fun findNodeHashIndex(hash: Int): Int {
for ((index, node) in this.childNodes.withIndex()) {
if (node.type == VDOMElementType.TAG && node.hash.hashCode() == hash) {
return index
}
else -> {
setAttribute(name, value)
}
}
return -2
}
fun createElement(): Node {
val result = when (type) {
VDOMElementType.TAG -> {
val result: Element = if (namespace != null) {
document.createElementNS(namespace, content)
} else {
document.createElement(content)
}
for ((name, value) in attributes) {
result.setAttribute(name, value)
}
for ((name, value) in events) {
result.addEventListener(name, value)
}
for (child in childNodes) {
result.appendChild(child.createElement())
}
result
}
VDOMElementType.ENTITY,
VDOMElementType.UNSAFE,
VDOMElementType.TEXT -> {
document.createTextNode(content)
}
VDOMElementType.COMMENT -> {
document.createComment(content)
}
}
komponent?.also {
it.element = result
}
return result
} else if (this.getAttribute(name) != value) {
setAttribute(name, value)
}
}
interface HtmlConsumer : TagConsumer<VDOMElement> {
fun append(node: VDOMElement)
private fun Element.clearKompEvents() {
for ((name, event) in getKompEvents()) {
currentElement?.removeEventListener(name, event)
}
val events = this.asDynamic()["komp-events"] as MutableMap<String, (Event) -> Unit>?
if (events == null) {
this.asDynamic()["komp-events"] = mutableMapOf<String, (Event) -> Unit>()
} else {
events.clear()
}
}
private fun Element.setKompEvent(name: String, event: (Event) -> Unit) {
val eventName: String = if (name.startsWith("on")) {
name.substring(2)
} else {
name
}
val events: MutableMap<String, (Event) -> Unit> = getKompEvents()
events[eventName]?.let {
println("Warn event already defined!")
currentElement?.removeEventListener(eventName, it)
}
events[eventName] = event
this.asDynamic()["komp-events"] = events
this.addEventListener(eventName, event)
}
private fun Element.getKompEvents(): MutableMap<String, (Event) -> Unit> {
return this.asDynamic()["komp-events"] ?: mutableMapOf()
}
private data class ElementIndex(
val parent: Node,
var childIndex: Int
)
private fun ArrayList<ElementIndex>.currentParent(): Node {
this.lastOrNull()?.let {
return it.parent
}
throw IllegalStateException("currentParent should never be null!")
}
private fun ArrayList<ElementIndex>.currentElement(): Node? {
this.lastOrNull()?.let {
return it.parent.childNodes[it.childIndex]
}
return null
}
private fun ArrayList<ElementIndex>.nextElement() {
this.lastOrNull()?.let {
it.childIndex++
}
}
private fun ArrayList<ElementIndex>.pop() {
this.removeLast()
}
private fun ArrayList<ElementIndex>.push(element: Node) {
this.add(ElementIndex(element, 0))
}
private fun ArrayList<ElementIndex>.replace(new: Node) {
if (this.currentElement() != null) {
this.currentElement()?.parentElement?.replaceChild(new, this.currentElement()!!)
} else {
this.last().parent.appendChild(new)
}
}
private fun Node.asElement() = this as? HTMLElement
class HtmlBuilder(
val baseHash: Int
val parent: Element,
var childIndex: Int = 0
) : HtmlConsumer {
private val path = arrayListOf<VDOMElement>()
private var lastLeaved: VDOMElement? = null
private var currentPosition = arrayListOf<ElementIndex>()
private var inDebug = false
var currentNode: Node? = null
var root: Element? = null
val currentAttributes: MutableMap<String, String> = mutableMapOf()
init {
currentPosition.add(ElementIndex(parent, childIndex))
}
override fun include(komponent: Komponent) {
if (
komponent.element != null &&
!komponent.memoizeChanged()
) {
currentPosition.replace(komponent.element!!)
if (Komponent.logRenderEvent) {
console.log("Skipped include $komponent, memoize hasn't changed")
}
} else {
komponent.create(
currentPosition.last().parent as Element,
currentPosition.last().childIndex
)
}
currentPosition.nextElement()
}
override fun append(node: Element) {
currentPosition.replace(node)
currentPosition.nextElement()
}
override fun debug(block: HtmlConsumer.() -> Unit) {
inDebug = true
try {
block.invoke(this)
} finally {
inDebug = false
}
}
fun logReplace(msg: String) {
if (Komponent.logReplaceEvent && inDebug) {
console.log(msg)
}
}
override fun onTagStart(tag: Tag) {
val element = VDOMElement(baseHash, tag.tagName, tag.namespace)
//logReplace"onTagStart, [${tag.tagName}, ${tag.namespace}], currentPosition: $currentPosition")
currentNode = currentPosition.currentElement()
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}")
currentNode = if (tag.namespace != null) {
document.createElementNS(tag.namespace, tag.tagName)
} else {
document.createElement(tag.tagName)
}
currentPosition.replace(currentNode!!)
} else {
//logReplace"onTagStart, same node type")
for (entry in tag.attributesEntries) {
element.setAttribute(entry.key, entry.value)
}
if (path.isNotEmpty()) {
path.last().appendChild(element)
currentElement = currentNode as? Element ?: currentElement
if (currentNode is Element) {
if (root == null) {
//logReplace"Setting root: $currentNode")
root = currentNode as Element
}
currentElement?.clearKompAttributes()
currentElement?.clearKompEvents()
for (entry in tag.attributesEntries) {
currentElement!!.setKompAttribute(entry.key.lowercase(), entry.value)
}
if (tag.namespace != null) {
//logReplace"onTagStart, same node type")
(currentNode as? Element)?.innerHTML = ""
}
}
path.add(element)
//logReplace"onTagStart, currentElement2: $currentNode")
currentPosition.push(currentNode!!)
}
private fun checkTag(tag: Tag) {
check(currentElement != null) {
js("debugger")
"No current tag"
}
check(currentElement?.tagName.equals(tag.tagName, ignoreCase = true)) {
js("debugger")
"Wrong current tag"
}
}
override fun onTagAttributeChange(tag: Tag, attribute: String, value: String?) {
when {
path.isEmpty() -> throw IllegalStateException("No current tag")
path.last().content.toLowerCase() != tag.tagName.toLowerCase() -> throw IllegalStateException("Wrong current tag")
else -> path.last().let { node ->
if (value == null) {
node.removeAttribute(attribute)
} else {
node.setAttribute(attribute, value)
}
}
logReplace("onTagAttributeChange, ${tag.tagName} [$attribute, $value]")
checkTag(tag)
if (value == null) {
currentElement?.removeAttribute(attribute.lowercase())
} else {
currentElement?.setKompAttribute(attribute.lowercase(), value)
}
}
override fun onTagEvent(tag: Tag, event: String, value: (Event) -> Unit) {
when {
path.isEmpty() -> throw IllegalStateException("No current tag")
path.last().content.toLowerCase() != tag.tagName.toLowerCase() -> throw IllegalStateException("Wrong current tag")
else -> path.last().setKompEvent(event, value)
}
//logReplace"onTagEvent, ${tag.tagName} [$event, $value]")
checkTag(tag)
currentElement?.setKompEvent(event.lowercase(), value)
}
override fun onTagEnd(tag: Tag) {
if (path.isEmpty() || path.last().content.toLowerCase() != tag.tagName.toLowerCase()) {
throw IllegalStateException("We haven't entered tag ${tag.tagName} but trying to leave")
while (currentPosition.currentElement() != null) {
currentPosition.currentElement()?.let {
it.parentElement?.removeChild(it)
}
}
lastLeaved = path.removeAt(path.lastIndex)
lastLeaved?.updateChildHash()
checkTag(tag)
currentPosition.pop()
val setAttrs: List<String> = currentElement.asDynamic()["komp-attributes"] ?: listOf()
// remove attributes that where not set
val element = currentElement
if (element?.hasAttributes() == true) {
for (index in 0 until element.attributes.length) {
val attr = element.attributes[index]
if (attr != null) {
if (element is HTMLElement && attr.name == "data-has-focus" && "true" == attr.value) {
element.focus()
}
if (!setAttrs.contains(attr.name)) {
if (element is HTMLInputElement) {
if (attr.name == "checkbox") {
element.checked = false
} else if (attr.name == "value") {
element.value = ""
}
} else {
if (Komponent.logReplaceEvent) {
console.log("Clear attribute [${attr.name}] on $element)")
}
element.removeAttribute(attr.name)
}
}
}
}
}
currentPosition.nextElement()
currentElement = currentElement?.parentElement as? HTMLElement
//logReplace"onTagEnd, popped: $currentElement")
}
override fun onTagContent(content: CharSequence) {
if (path.isEmpty()) {
throw IllegalStateException("No current DOM node")
//logReplace"onTagContent, [$content]")
check(currentElement != null) {
"No current DOM node"
}
path.last().appendChild(VDOMElement(baseHash, content.toString(), type = VDOMElementType.TEXT))
//logReplace"Tag content: $content")
if (
currentElement?.nodeType != Node.TEXT_NODE ||
currentElement?.textContent != content.toString()
) {
currentElement?.textContent = content.toString()
}
currentPosition.nextElement()
}
override fun onTagContentEntity(entity: Entities) {
if (path.isEmpty()) {
throw IllegalStateException("No current DOM node")
//logReplace"onTagContentEntity, [${entity.text}]")
check(currentElement != null) {
"No current DOM node"
}
// stupid hack as browsers don't support createEntityReference
path.last().appendChild(VDOMElement(baseHash, entity.text, type = VDOMElementType.ENTITY))
}
override fun append(node: VDOMElement) {
path.last().appendChild(node)
val s = document.createElement("span") as HTMLSpanElement
s.innerHTML = entity.text
currentPosition.replace(
s.childNodes.asList().firstOrNull() ?: document.createTextNode(entity.text)
)
currentPosition.nextElement()
}
override fun onTagContentUnsafe(block: Unsafe.() -> Unit) {
with(DefaultUnsafe()) {
block()
path.last().appendChild(VDOMElement(baseHash, toString(), type = VDOMElementType.UNSAFE))
val textContent = toString()
//logReplace"onTagContentUnsafe, [$textContent]")
var namespace: String? = null
if (currentPosition.currentParent().nodeType == 1.toShort()) {
val element = currentPosition.currentParent() as Element
namespace = when (Komponent.unsafeMode) {
UnsafeMode.UNSAFE_ALLOWED -> {
element.namespaceURI
}
UnsafeMode.UNSAFE_SVG_ONLY -> {
if (element.namespaceURI == "http://www.w3.org/2000/svg") {
element.namespaceURI
} else {
null
}
}
else -> {
null
}
}
}
//logReplace"onTagContentUnsafe, namespace: [$namespace]")
if (Komponent.unsafeMode == UnsafeMode.UNSAFE_ALLOWED ||
(Komponent.unsafeMode == UnsafeMode.UNSAFE_SVG_ONLY && namespace == "http://www.w3.org/2000/svg")
) {
if (currentElement?.innerHTML != textContent) {
currentElement?.innerHTML += textContent
}
} else if (currentElement?.textContent != textContent) {
currentElement?.textContent = textContent
}
currentPosition.nextElement()
}
}
override fun onTagComment(content: CharSequence) {
if (path.isEmpty()) {
throw IllegalStateException("No current DOM node")
}
//logReplace"onTagComment, [$content]")
path.last().appendChild(VDOMElement(baseHash, content.toString(), type = VDOMElementType.COMMENT))
check(currentElement != null) {
"No current DOM node"
}
currentElement?.appendChild(
document.createComment(content.toString())
)
currentPosition.nextElement()
}
override fun finalize(): VDOMElement {
return lastLeaved ?: throw IllegalStateException("We can't finalize as there was no tags")
override fun finalize(): Element {
//logReplace"finalize, currentPosition: $currentPosition")
return root ?: throw IllegalStateException("We can't finalize as there was no tags")
}
companion object {
fun create(content: HtmlBuilder.() -> Unit): VDOMElement {
val komponent = DummyKomponent()
val consumer = HtmlBuilder(komponent.hashCode())
fun create(content: HtmlBuilder.() -> Unit): Element {
val container = document.createElement("div") as HTMLElement
val consumer = HtmlBuilder(container, 0)
content.invoke(consumer)
return consumer.finalize()
return consumer.root ?: error("error")
}
}
}

View File

@@ -1,16 +1,13 @@
package nl.astraeus.komp
import kotlinx.browser.document
import kotlinx.browser.window
import kotlinx.html.div
import org.w3c.dom.HTMLDivElement
import org.w3c.dom.Element
import org.w3c.dom.HTMLElement
import org.w3c.dom.Node
import org.w3c.dom.css.CSSStyleDeclaration
import org.w3c.dom.get
import kotlin.reflect.KProperty
typealias CssStyle = CSSStyleDeclaration.() -> Unit
class StateDelegate<T>(
val komponent: Komponent,
initialValue: T
@@ -31,112 +28,126 @@ class StateDelegate<T>(
inline fun <reified T> Komponent.state(initialValue: T): StateDelegate<T> = StateDelegate(this, initialValue)
fun HtmlConsumer.include(component: Komponent) {
append(component.create())
}
class DummyKomponent: Komponent() {
override fun HtmlBuilder.render() {
div {
+ "dummy"
}
}
enum class UnsafeMode {
UNSAFE_ALLOWED,
UNSAFE_DISABLED,
UNSAFE_SVG_ONLY
}
abstract class Komponent {
private var createIndex = getNextCreateIndex()
val createIndex = getNextCreateIndex()
private var dirty: Boolean = true
private var lastMemoizeHash: Int? = null
var vdom: VDOMElement? = null
var element: Node? = null
val declaredStyles: MutableMap<String, CSSStyleDeclaration> = HashMap()
open fun create(): VDOMElement {
val consumer = HtmlBuilder(this.createIndex)
try {
consumer.render()
} catch (e: Throwable) {
println("Exception occurred in ${this::class.simpleName}.render() call!")
open fun create(parent: Element, childIndex: Int? = null) {
onBeforeUpdate()
val builder = HtmlBuilder(
parent,
childIndex ?: parent.childElementCount
)
throw e
}
val result = consumer.finalize()
if (result.id.isBlank()) {
result.id = "komp_${createIndex}"
}
result.komponent = this
vdom = result
dirty = false
return result
builder.render()
element = builder.root
lastMemoizeHash = generateMemoizeHash()
onAfterUpdate()
}
fun memoizeChanged() = lastMemoizeHash != null && lastMemoizeHash != generateMemoizeHash()
abstract fun HtmlBuilder.render()
/**
* This method is called after the Komponent is updated
*
* note: it's also called at first render
*/
open fun onAfterUpdate() {}
/**
* This method is called before the Komponent is updated
* and before memoizeHash is checked
*
* note: it's also called at first render
*/
open fun onBeforeUpdate() {}
fun requestUpdate() {
dirty = true
scheduleForUpdate(this)
}
open fun style(className: String, vararg imports: CssStyle, block: CssStyle = {}) {
val style = (document.createElement("div") as HTMLDivElement).style
for (imp in imports) {
imp(style)
}
block(style)
declaredStyles[className] = style
/**
* Request an immediate update of this Komponent
*
* This will run immediately, make sure Komponents are not rendered multiple times
* Any scheduled updates will be run as well
*/
fun requestImmediateUpdate() {
dirty = true
runUpdateImmediately(this)
}
/**
* This function can be overwritten if you know how to update the Komponent yourself
*
* HTMLBuilder.render() is called 1st time the component is rendered, after that this
* method will be called
*/
open fun update() {
refresh()
}
/**
* If this function returns a value it will be stored and on the next render it will be compared.
*
* The render will only happen if the hash is not null and has changed
*/
open fun generateMemoizeHash(): Int? = null
internal fun refresh() {
val oldElement = vdom
val currentElement = element
if (logRenderEvent) {
console.log("Rendering", this)
}
val newElement = create()
element = if (oldElement != null && element != null) {
if (logReplaceEvent) {
console.log("DomDiffing", oldElement, newElement)
}
DiffPatch.updateNode(element!!, oldElement, newElement)
} else {
if (logReplaceEvent) {
console.log("Create", newElement)
}
newElement.createElement()
check(currentElement != null) {
error("element is null")
}
vdom = newElement
val parent = currentElement.parentElement as? HTMLElement ?: error("parent is null!?")
var childIndex = 0
for (index in 0 until parent.children.length) {
if (parent.children[index] == currentElement) {
childIndex = index
}
}
val consumer = HtmlBuilder(parent, childIndex)
consumer.root = null
consumer.render()
element = consumer.root
dirty = false
}
override fun toString(): String {
return "${this::class.simpleName}"
}
companion object {
private var nextCreateIndex: Int = 1
private var updateCallback: Int? = null
private var scheduledForUpdate = mutableSetOf<Komponent>()
private var interceptor: (Komponent, () -> Unit) -> Unit = { _, block -> block() }
var logRenderEvent = false
var logReplaceEvent = false
var unsafeMode = UnsafeMode.UNSAFE_DISABLED
fun create(parent: HTMLElement, component: Komponent, insertAsFirst: Boolean = false) {
val vdomElement = component.create()
val element = vdomElement.createElement()
component.element = element
component.create(parent)
}
if (insertAsFirst && parent.childElementCount > 0) {
parent.insertBefore(element, parent.firstChild)
} else {
parent.appendChild(element)
}
fun setUpdateInterceptor(block: (Komponent, () -> Unit) -> Unit) {
interceptor = block
}
private fun getNextCreateIndex() = nextCreateIndex++
@@ -151,6 +162,11 @@ abstract class Komponent {
}
}
private fun runUpdateImmediately(komponent: Komponent) {
scheduledForUpdate.add(komponent)
runUpdate()
}
private fun runUpdate() {
val todo = scheduledForUpdate.sortedBy { komponent -> komponent.createIndex }
@@ -159,25 +175,32 @@ abstract class Komponent {
}
todo.forEach { next ->
val element = next.element
interceptor(next) {
val element = next.element
if (element is HTMLElement) {
if (document.getElementById(element.id) != null) {
if (element is HTMLElement) {
if (next.dirty) {
if (logRenderEvent) {
console.log("Update dirty ${next.createIndex}")
}
next.update()
val memoizeHash = next.generateMemoizeHash()
if (memoizeHash == null || next.lastMemoizeHash != memoizeHash) {
next.onBeforeUpdate()
next.update()
next.lastMemoizeHash = memoizeHash
next.onAfterUpdate()
} else if (logRenderEvent) {
console.log("Skipped render, memoizeHash is equal $next-[$memoizeHash]")
}
} else {
if (logRenderEvent) {
console.log("Skip ${next.createIndex}")
}
}
} else {
console.log("Komponent element has no id, ", next, element)
console.log("Komponent element is null", next, element)
}
} else {
console.log("Komponent element is null", next)
}
}

View File

@@ -1,144 +1,238 @@
package nl.astraeus.komp
import kotlinx.html.*
import kotlinx.browser.document
import kotlinx.html.div
import kotlinx.html.i
import kotlinx.html.id
import kotlinx.html.js.onClickFunction
import kotlinx.html.p
import kotlinx.html.span
import kotlinx.html.svg
import kotlinx.html.table
import kotlinx.html.td
import kotlinx.html.tr
import kotlinx.html.unsafe
import org.w3c.dom.Element
import org.w3c.dom.HTMLElement
import org.w3c.dom.get
import org.w3c.dom.HTMLDivElement
import kotlin.test.Test
import kotlin.test.assertTrue
fun nodesEqual(element: Element, vdom: VDOMElement): Boolean {
if (element.childNodes.length != vdom.childNodes.size) {
return false
}
if (element.attributes.length != vdom.attributes.size) {
return false
}
for ((name, value) in vdom.attributes) {
if (value != element.getAttribute(name)) {
return false
class TestKomponent : Komponent() {
override fun HtmlBuilder.render() {
div {
+"Test"
}
}
for ((index, child) in vdom.childNodes.withIndex()) {
if (index < element.childNodes.length) {
val elementChild = element.childNodes[index]
}
if (child.type == VDOMElementType.TAG) {
if (!nodesEqual(elementChild as HTMLElement, child)) {
return false
class Child1 : Komponent() {
override fun HtmlBuilder.render() {
div {
+"Child 1"
}
}
}
class Child2 : Komponent() {
override fun HtmlBuilder.render() {
div {
+"Child 2"
}
}
}
class SimpleKomponent : Komponent() {
var hello = true
var append = HtmlBuilder.create {
p {
+"Appended"
}
}
override fun HtmlBuilder.render() {
div("div_class") {
span {
svg {
unsafe {
+"""
<p bla>
""".trimIndent()
}
}
} else if (child.type == VDOMElementType.TEXT) {
if (child.content != element.textContent) {
return false
if (hello) {
div {
+"Hello"
}
} else {
span {
+"Good bye"
}
}
}
} else {
return false
div {
if (hello) {
id = "123"
+"div text"
} else {
+"div text goodbye"
}
onClickFunction = if (hello) {
{
println("onClick")
}
} else {
{
println("onClick 2")
}
}
}
if (hello) {
span {
+"2nd span"
}
}
//append(append)
if (hello) {
include(Child1())
} else {
include(Child2())
}
//append(append)
}
}
return true
}
class IncludeKomponent(
var text: String = "My Text"
) : Komponent() {
override fun generateMemoizeHash(): Int = text.hashCode()
override fun HtmlBuilder.render() {
span {
+text
}
}
}
class ReplaceKomponent : Komponent() {
val includeKomponent = IncludeKomponent()
var includeSpan = true
override fun generateMemoizeHash(): Int = includeSpan.hashCode() * 7 + includeKomponent.generateMemoizeHash()
override fun HtmlBuilder.render() {
div {
+"Child 2"
div {
if (includeSpan) {
span {
i("fas fa-eye") {
+"span1"
}
}
span {
i("fas fa-eye") {
+"span2"
}
}
span {
i("fas fa-eye") {
+"span3"
}
}
}
include(includeKomponent)
}
}
}
}
class TestUpdate {
@Test
fun testCompare() {
val dom1 = HtmlBuilder.create {
div {
div(classes = "bla") {
span {
+" Some Text "
}
table {
tr {
td {
+"Table column"
}
}
}
}
}
}
val dom2 = HtmlBuilder.create {
div {
span {
id = "123"
+"New dom!"
}
input {
value = "bla"
}
}
}
var element = dom1.createElement()
assertTrue(nodesEqual(element as Element, dom1), "Created dom not equal to original")
element = DiffPatch.updateNode(element, dom1, dom2) as HTMLElement
assertTrue(nodesEqual(element, dom2), "Updated dom not equal to original")
}
@Test
fun testCompare2() {
val dom1 = HtmlBuilder.create {
div {
div(classes = "bla") {
span {
+" Some Text "
}
table {
tr {
th {
+"Header"
}
}
tr {
td {
+"Table column"
}
}
}
}
}
}
val dom2 = HtmlBuilder.create {
div {
div {
span {
+"Other text"
}
}
span {
id = "123"
+"New dom!"
}
input {
value = "bla"
onClickFunction = {
println("Clickerdyclick!")
}
}
}
}
fun testUpdateWithEmpty() {
val div = document.createElement("div") as HTMLDivElement
val rk = ReplaceKomponent()
Komponent.logRenderEvent = true
var element = dom1.createElement()
Komponent.create(div, rk)
assertTrue(nodesEqual(element as Element, dom1), "Created dom not equal to original")
println("ReplaceKomponent: ${div.printTree()}")
element = DiffPatch.updateNode(element, dom1, dom2) as HTMLElement
rk.requestImmediateUpdate()
assertTrue(nodesEqual(element, dom2), "Updated dom not equal to original")
println("ReplaceKomponent: ${div.printTree()}")
rk.requestImmediateUpdate()
println("ReplaceKomponent: ${div.printTree()}")
rk.includeSpan = false
rk.requestImmediateUpdate()
println("ReplaceKomponent: ${div.printTree()}")
rk.includeSpan = true
rk.includeKomponent.text = "New Text"
rk.requestImmediateUpdate()
println("ReplaceKomponent: ${div.printTree()}")
}
@Test
fun testSimpleKomponent() {
val sk = SimpleKomponent()
val div = document.createElement("div") as HTMLDivElement
Komponent.create(div, sk)
println("SimpleKomponent: ${div.printTree()}")
sk.hello = false
sk.requestImmediateUpdate()
println("SimpleKomponent updated: ${div.printTree()}")
}
@Test
fun testCreate() {
var elemTest: Element? = null
val element = HtmlBuilder.create {
div("div_class") {
id = "123"
+"Test"
span("span_class") {
+"Span"
elemTest = currentElement()
}
table {
tr {
td {
+"column 1"
}
td {
+"column 2"
}
}
}
}
}
println("Element: ${element.printTree()}")
println("divTst: ${elemTest?.printTree()}")
println("span class: ${
elemTest?.getAttributeNames()?.joinToString
{ "," }
}"
)
}
}