Skip to content

Commit a0dcaad

Browse files
committed
refactor: remove kotlinx-html
1 parent 9b939d1 commit a0dcaad

File tree

17 files changed

+776
-584
lines changed

17 files changed

+776
-584
lines changed

generator/web/build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ plugins {
66

77
dependencies {
88
api(project(":generator-common"))
9-
api(libs.kotlinx.html.jvm)
109
implementation(libs.bundles.jackson)
1110
testImplementation(kotlin("test"))
1211
testRuntimeOnly(libs.slf4j.simple)

generator/web/src/main/kotlin/me/kcra/takenaka/generator/web/ComponentDefinition.kt

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,8 @@
1717

1818
package me.kcra.takenaka.generator.web
1919

20-
import kotlinx.html.BODY
21-
import kotlinx.html.body
22-
import kotlinx.html.consumers.filter
23-
import kotlinx.html.dom.append
24-
import kotlinx.html.dom.document
25-
import kotlinx.html.html
26-
import org.w3c.dom.Document
20+
import me.kcra.takenaka.generator.web.util.HTMLBuilder
21+
import me.kcra.takenaka.generator.web.util.buildHTML
2722
import kotlin.properties.Delegates
2823

2924
/**
@@ -37,7 +32,7 @@ import kotlin.properties.Delegates
3732
*/
3833
data class ComponentDefinition(
3934
val tag: String,
40-
val content: Document,
35+
val content: String,
4136
val callback: String?
4237
)
4338

@@ -53,7 +48,7 @@ class ComponentDefinitionBuilder {
5348
/**
5449
* The component content/body.
5550
*/
56-
var content by Delegates.notNull<Document>()
51+
var content by Delegates.notNull<String>()
5752

5853
/**
5954
* A raw JS script that is called after the component has been loaded onto the site, a variable `e` of type `HTMLElement` is available.
@@ -65,15 +60,8 @@ class ComponentDefinitionBuilder {
6560
*
6661
* @param block the builder action
6762
*/
68-
inline fun content(crossinline block: BODY.() -> Unit) {
69-
content = document {
70-
append.filter { if (it.tagName == "html" || it.tagName == "body") SKIP else PASS }
71-
.html {
72-
body {
73-
block()
74-
}
75-
}
76-
}
63+
inline fun content(crossinline block: HTMLBuilder.() -> Unit) {
64+
content = buildHTML(false, block)
7765
}
7866

7967
/**

generator/web/src/main/kotlin/me/kcra/takenaka/generator/web/GenerationContext.kt

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,13 @@
1818
package me.kcra.takenaka.generator.web
1919

2020
import kotlinx.coroutines.*
21-
import kotlinx.html.dom.serialize
22-
import kotlinx.html.dom.write
2321
import me.kcra.takenaka.core.Workspace
2422
import me.kcra.takenaka.core.mapping.adapter.replaceCraftBukkitNMSVersion
2523
import me.kcra.takenaka.core.mapping.resolve.impl.craftBukkitNmsVersion
2624
import me.kcra.takenaka.generator.common.provider.AncestryProvider
2725
import net.fabricmc.mappingio.tree.MappingTreeView
28-
import org.w3c.dom.Document
2926
import kotlin.io.path.createDirectories
3027
import kotlin.io.path.writeText
31-
import kotlin.io.path.writer
3228

3329
/**
3430
* A generation context, not version-bound.
@@ -46,21 +42,17 @@ class GenerationContext(
4642
internal val versionReplaceCandidates = generator.config.craftBukkitVersionReplaceCandidates.toSet()
4743

4844
/**
49-
* Serializes a [Document] to a file in the specified workspace.
45+
* Writes a document string to a file in the specified workspace.
5046
*
5147
* @param workspace the workspace
5248
* @param path the path, relative in the workspace
5349
*/
54-
suspend fun Document.serialize(workspace: Workspace, path: String) {
50+
suspend fun String.write(workspace: Workspace, path: String) {
5551
withContext(Dispatchers.IO + CoroutineName("io-coro")) {
5652
val file = workspace[path]
5753
file.parent.createDirectories()
5854

59-
if (generator.config.transformers.isEmpty()) {
60-
file.writer().use { it.write(this@serialize) }
61-
} else {
62-
file.writeText(generator.transformHtml(serialize(prettyPrint = !generator.hasMinifier)))
63-
}
55+
file.writeText(generator.transformHtml(this@write))
6456
}
6557
}
6658

generator/web/src/main/kotlin/me/kcra/takenaka/generator/web/WebGenerator.kt

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919

2020
package me.kcra.takenaka.generator.web
2121

22-
import kotlinx.html.dom.serialize
22+
import io.github.oshai.kotlinlogging.KotlinLogging
23+
import kotlinx.coroutines.*
2324
import me.kcra.takenaka.core.Workspace
2425
import me.kcra.takenaka.core.mapping.ElementRemapper
2526
import me.kcra.takenaka.core.mapping.adapter.replaceCraftBukkitNMSVersion
@@ -33,10 +34,7 @@ import me.kcra.takenaka.generator.common.provider.MappingProvider
3334
import me.kcra.takenaka.generator.web.components.footerComponent
3435
import me.kcra.takenaka.generator.web.components.navComponent
3536
import me.kcra.takenaka.generator.web.pages.*
36-
import me.kcra.takenaka.generator.web.transformers.MinifyingTransformer
3737
import me.kcra.takenaka.generator.web.transformers.Transformer
38-
import io.github.oshai.kotlinlogging.KotlinLogging
39-
import kotlinx.coroutines.*
4038
import net.fabricmc.mappingio.tree.MappingTreeView
4139
import java.io.BufferedReader
4240
import java.nio.file.Files
@@ -61,8 +59,6 @@ open class WebGenerator(override val workspace: Workspace, val config: WebConfig
6159
protected val namespaceFriendlyNames = config.namespaces.mapValues { it.value.friendlyName }
6260
protected val currentComposite by workspace
6361

64-
internal val hasMinifier = config.transformers.any { it is MinifyingTransformer }
65-
6662
/**
6763
* A [Comparator] for comparing the friendliness of namespaces, useful for sorting.
6864
*/
@@ -118,7 +114,7 @@ open class WebGenerator(override val workspace: Workspace, val config: WebConfig
118114
launch(DISPATCHER + CoroutineName("gen-coro")) {
119115
val time = measureTimeMillis {
120116
historyNodes.forEach { (node, fileHash) ->
121-
historyPage(node).serialize(historyWorkspace, "$fileHash.html")
117+
historyPage(node).write(historyWorkspace, "$fileHash.html")
122118
}
123119
}
124120
logger.info { "history pages generated in ${time}ms" }
@@ -163,7 +159,7 @@ open class WebGenerator(override val workspace: Workspace, val config: WebConfig
163159
val friendlyName = getFriendlyDstName(klass)
164160

165161
classPage(klass, type, hashMap[klass], nmsVersion, versionWorkspace, friendlyNameRemapper)
166-
.serialize(versionWorkspace, "$friendlyName.html")
162+
.write(versionWorkspace, "$friendlyName.html")
167163

168164
classMap.getOrPut(friendlyName.substringBeforeLast('/')) { sortedMapOf(compareBy(ClassType::ordinal)) }
169165
.getOrPut(type, ::sortedSetOf) += friendlyName.substringAfterLast('/')
@@ -178,7 +174,7 @@ open class WebGenerator(override val workspace: Workspace, val config: WebConfig
178174

179175
classMap.forEach { (packageName, classes) ->
180176
packagePage(versionWorkspace, packageName, classes)
181-
.serialize(versionWorkspace, "$packageName/index.html")
177+
.write(versionWorkspace, "$packageName/index.html")
182178
}
183179

184180
val licenses = config.namespaces
@@ -193,10 +189,10 @@ open class WebGenerator(override val workspace: Workspace, val config: WebConfig
193189
.toMap()
194190

195191
licensePage(versionWorkspace, licenses)
196-
.serialize(versionWorkspace, "licenses.html")
192+
.write(versionWorkspace, "licenses.html")
197193

198194
overviewPage(versionWorkspace, classMap.keys)
199-
.serialize(versionWorkspace, "index.html")
195+
.write(versionWorkspace, "index.html")
200196

201197
versionWorkspace["class-index.js"].writeText("updateClassIndex(`${classIndex.trim()}`);") // do not minify this file
202198
}
@@ -208,7 +204,7 @@ open class WebGenerator(override val workspace: Workspace, val config: WebConfig
208204
val versions = mappings.mapValuesTo(TreeMap(Collections.reverseOrder())) { it.value.dstNamespaces }
209205

210206
versionsPage(config.welcomeMessage, versions)
211-
.serialize(workspace, "index.html")
207+
.write(workspace, "index.html")
212208
}
213209
}
214210

@@ -310,7 +306,7 @@ open class WebGenerator(override val workspace: Workspace, val config: WebConfig
310306
)
311307

312308
components.forEach { (tag, content, callback) ->
313-
appendLine("const ${tag}Component = `${transformHtml(content.documentElement.serialize(prettyPrint = false))}`;")
309+
appendLine("const ${tag}Component = `${transformHtml(content)}`;")
314310
appendLine("const ${tag}ComponentCallback = (e) => {")
315311
if (callback != null) {
316312
appendLine(callback)

generator/web/src/main/kotlin/me/kcra/takenaka/generator/web/components/badge.kt

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717

1818
package me.kcra.takenaka.generator.web.components
1919

20-
import kotlinx.html.*
2120
import me.kcra.takenaka.generator.web.StyleProvider
21+
import me.kcra.takenaka.generator.web.util.*
2222

2323
/**
2424
* Appends a namespace badge component.
@@ -27,16 +27,15 @@ import me.kcra.takenaka.generator.web.StyleProvider
2727
* @param color the badge color in a CSS compatible format
2828
* @param styleProvider the style provider, used for generating stylesheets
2929
*/
30-
fun FlowContent.badgeComponent(content: String, color: String, styleProvider: StyleProvider? = null) {
30+
fun HTMLBuilder.badgeComponent(content: String, color: String, styleProvider: StyleProvider? = null) {
3131
if (styleProvider != null) {
3232
val lowercase = content.lowercase()
3333

3434
p(classes = "badge ${styleProvider.apply("badge-$lowercase", "background-color:$color;")}")
3535
styleProvider.apply("badge-$lowercase::before", "content:\"$content\";")
3636
} else {
37-
p(classes = "badge") {
38-
style = "background-color:$color"
39-
+content
37+
p(classes = "badge", style = "background-color:$color") {
38+
append(content)
4039
}
4140
}
4241
}
@@ -48,16 +47,15 @@ fun FlowContent.badgeComponent(content: String, color: String, styleProvider: St
4847
* @param color the badge color in a CSS compatible format
4948
* @param styleProvider the style provider, used for generating stylesheets
5049
*/
51-
fun TR.badgeColumnComponent(content: String, color: String, styleProvider: StyleProvider? = null) {
50+
fun HTMLBuilder.badgeColumnComponent(content: String, color: String, styleProvider: StyleProvider? = null) {
5251
if (styleProvider != null) {
5352
val lowercase = content.lowercase()
5453

5554
td(classes = "badge ${styleProvider.apply("badge-$lowercase", "background-color:$color;")}")
5655
styleProvider.apply("badge-$lowercase::before", "content:\"$content\";")
5756
} else {
58-
td(classes = "badge") {
59-
style = "background-color:$color"
60-
+content
57+
td(classes = "badge", style = "background-color:$color") {
58+
append(content)
6159
}
6260
}
6361
}
@@ -69,19 +67,18 @@ fun TR.badgeColumnComponent(content: String, color: String, styleProvider: Style
6967
* @param color the badge color in a CSS compatible format
7068
* @param styleProvider the style provider, used for generating stylesheets
7169
*/
72-
fun FlowContent.textBadgeComponent(content: String, color: String, styleProvider: StyleProvider? = null) {
70+
fun HTMLBuilder.textBadgeComponent(content: String, color: String, styleProvider: StyleProvider? = null) {
7371
val lowercase = content.lowercase()
7472

7573
if (styleProvider != null) {
7674
span(classes = "badge-text ${styleProvider.apply("badge-text-$lowercase", "")}")
7775
styleProvider.apply("badge-text-$lowercase::before", "color:$color;content:\"$content\";")
7876
styleProvider.apply("badge-text-$lowercase::after", "content:\": \";")
7977
} else {
80-
span(classes = "badge-text") {
81-
style = "color:$color"
82-
+content
78+
span(classes = "badge-text", style = "color:$color") {
79+
append(content)
8380
}
84-
+": "
81+
append(": ")
8582
}
8683
}
8784

generator/web/src/main/kotlin/me/kcra/takenaka/generator/web/components/footer.kt

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,20 @@
1717

1818
package me.kcra.takenaka.generator.web.components
1919

20-
import kotlinx.html.*
20+
import me.kcra.takenaka.generator.web.util.*
2121

2222
/**
2323
* Appends a footer.
2424
*/
25-
fun FlowContent.footerComponent() {
25+
fun HTMLBuilder.footerComponent() {
2626
footer {
2727
spacerBottomSlimComponent()
2828
div(classes = "footer-content") {
2929
p {
30-
+"Built with lots of coffee and ❤️, for people by people."
30+
append("Built with lots of coffee and ❤️, for people by people.")
3131
}
32-
a(href = "https://github.com/zlataovce/takenaka", classes = "icon-link") {
33-
attributes["aria-label"] = "GitHub"
34-
unsafe {
35-
+"""<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"/></svg>"""
36-
}
32+
a(href = "https://github.com/zlataovce/takenaka", classes = "icon-link", ariaLabel = "GitHub") {
33+
append("""<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"/></svg>""")
3734
}
3835
}
3936
}
@@ -42,6 +39,6 @@ fun FlowContent.footerComponent() {
4239
/**
4340
* Appends a footer component placeholder that is replaced with a real navbar dynamically.
4441
*/
45-
fun FlowContent.footerPlaceholderComponent() {
42+
fun HTMLBuilder.footerPlaceholderComponent() {
4643
footer {}
4744
}

generator/web/src/main/kotlin/me/kcra/takenaka/generator/web/components/head.kt

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,36 +17,34 @@
1717

1818
package me.kcra.takenaka.generator.web.components
1919

20-
import kotlinx.html.*
20+
import me.kcra.takenaka.generator.web.util.*
2121

2222
/**
2323
* Appends default resources (scripts, stylesheets, meta, ...) to a head element.
2424
*
2525
* @param rootPath the path to the website root directory
2626
*/
27-
fun HEAD.defaultResourcesComponent(rootPath: String = "/") {
27+
fun HTMLBuilder.defaultResourcesComponent(rootPath: String = "/") {
2828
meta(name = "viewport", content = "width=device-width, initial-scale=1")
2929
link(href = "${rootPath}assets/main.css", rel = "stylesheet")
30-
script(src = "${rootPath}assets/main.js") {}
30+
script(src = "${rootPath}assets/main.js")
3131
}
3232

3333
/**
3434
* Appends a script element declaring a version root path global variable to a head element.
3535
*
3636
* @param rootPath the path to the version root directory
3737
*/
38-
fun HEAD.versionRootComponent(rootPath: String = "./") {
38+
fun HTMLBuilder.versionRootComponent(rootPath: String = "./") {
3939
script {
40-
unsafe {
41-
+"""window.root = "$rootPath";"""
42-
}
40+
append("""window.root = "$rootPath";""")
4341
}
4442
}
4543

4644
/**
4745
* Appends [OpenGraph](https://ogp.me/#metadata) and `theme-color` metadata to a head element.
4846
*/
49-
fun HEAD.metadataComponent(title: String? = null, description: String? = null, themeColor: String? = null) {
47+
fun HTMLBuilder.metadataComponent(title: String? = null, description: String? = null, themeColor: String? = null) {
5048
if (themeColor != null) meta(name = "theme-color", content = themeColor)
5149

5250
// https://ogp.me/#metadata

0 commit comments

Comments
 (0)