Skip to content

Commit

Permalink
refactor: remove kotlinx-html
Browse files Browse the repository at this point in the history
  • Loading branch information
zlataovce committed Dec 1, 2024
1 parent 9b939d1 commit a0dcaad
Show file tree
Hide file tree
Showing 17 changed files with 776 additions and 584 deletions.
1 change: 0 additions & 1 deletion generator/web/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ plugins {

dependencies {
api(project(":generator-common"))
api(libs.kotlinx.html.jvm)
implementation(libs.bundles.jackson)
testImplementation(kotlin("test"))
testRuntimeOnly(libs.slf4j.simple)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,8 @@

package me.kcra.takenaka.generator.web

import kotlinx.html.BODY
import kotlinx.html.body
import kotlinx.html.consumers.filter
import kotlinx.html.dom.append
import kotlinx.html.dom.document
import kotlinx.html.html
import org.w3c.dom.Document
import me.kcra.takenaka.generator.web.util.HTMLBuilder
import me.kcra.takenaka.generator.web.util.buildHTML
import kotlin.properties.Delegates

/**
Expand All @@ -37,7 +32,7 @@ import kotlin.properties.Delegates
*/
data class ComponentDefinition(
val tag: String,
val content: Document,
val content: String,
val callback: String?
)

Expand All @@ -53,7 +48,7 @@ class ComponentDefinitionBuilder {
/**
* The component content/body.
*/
var content by Delegates.notNull<Document>()
var content by Delegates.notNull<String>()

/**
* A raw JS script that is called after the component has been loaded onto the site, a variable `e` of type `HTMLElement` is available.
Expand All @@ -65,15 +60,8 @@ class ComponentDefinitionBuilder {
*
* @param block the builder action
*/
inline fun content(crossinline block: BODY.() -> Unit) {
content = document {
append.filter { if (it.tagName == "html" || it.tagName == "body") SKIP else PASS }
.html {
body {
block()
}
}
}
inline fun content(crossinline block: HTMLBuilder.() -> Unit) {
content = buildHTML(false, block)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,13 @@
package me.kcra.takenaka.generator.web

import kotlinx.coroutines.*
import kotlinx.html.dom.serialize
import kotlinx.html.dom.write
import me.kcra.takenaka.core.Workspace
import me.kcra.takenaka.core.mapping.adapter.replaceCraftBukkitNMSVersion
import me.kcra.takenaka.core.mapping.resolve.impl.craftBukkitNmsVersion
import me.kcra.takenaka.generator.common.provider.AncestryProvider
import net.fabricmc.mappingio.tree.MappingTreeView
import org.w3c.dom.Document
import kotlin.io.path.createDirectories
import kotlin.io.path.writeText
import kotlin.io.path.writer

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

/**
* Serializes a [Document] to a file in the specified workspace.
* Writes a document string to a file in the specified workspace.
*
* @param workspace the workspace
* @param path the path, relative in the workspace
*/
suspend fun Document.serialize(workspace: Workspace, path: String) {
suspend fun String.write(workspace: Workspace, path: String) {
withContext(Dispatchers.IO + CoroutineName("io-coro")) {
val file = workspace[path]
file.parent.createDirectories()

if (generator.config.transformers.isEmpty()) {
file.writer().use { it.write(this@serialize) }
} else {
file.writeText(generator.transformHtml(serialize(prettyPrint = !generator.hasMinifier)))
}
file.writeText(generator.transformHtml(this@write))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@

package me.kcra.takenaka.generator.web

import kotlinx.html.dom.serialize
import io.github.oshai.kotlinlogging.KotlinLogging
import kotlinx.coroutines.*
import me.kcra.takenaka.core.Workspace
import me.kcra.takenaka.core.mapping.ElementRemapper
import me.kcra.takenaka.core.mapping.adapter.replaceCraftBukkitNMSVersion
Expand All @@ -33,10 +34,7 @@ import me.kcra.takenaka.generator.common.provider.MappingProvider
import me.kcra.takenaka.generator.web.components.footerComponent
import me.kcra.takenaka.generator.web.components.navComponent
import me.kcra.takenaka.generator.web.pages.*
import me.kcra.takenaka.generator.web.transformers.MinifyingTransformer
import me.kcra.takenaka.generator.web.transformers.Transformer
import io.github.oshai.kotlinlogging.KotlinLogging
import kotlinx.coroutines.*
import net.fabricmc.mappingio.tree.MappingTreeView
import java.io.BufferedReader
import java.nio.file.Files
Expand All @@ -61,8 +59,6 @@ open class WebGenerator(override val workspace: Workspace, val config: WebConfig
protected val namespaceFriendlyNames = config.namespaces.mapValues { it.value.friendlyName }
protected val currentComposite by workspace

internal val hasMinifier = config.transformers.any { it is MinifyingTransformer }

/**
* A [Comparator] for comparing the friendliness of namespaces, useful for sorting.
*/
Expand Down Expand Up @@ -118,7 +114,7 @@ open class WebGenerator(override val workspace: Workspace, val config: WebConfig
launch(DISPATCHER + CoroutineName("gen-coro")) {
val time = measureTimeMillis {
historyNodes.forEach { (node, fileHash) ->
historyPage(node).serialize(historyWorkspace, "$fileHash.html")
historyPage(node).write(historyWorkspace, "$fileHash.html")
}
}
logger.info { "history pages generated in ${time}ms" }
Expand Down Expand Up @@ -163,7 +159,7 @@ open class WebGenerator(override val workspace: Workspace, val config: WebConfig
val friendlyName = getFriendlyDstName(klass)

classPage(klass, type, hashMap[klass], nmsVersion, versionWorkspace, friendlyNameRemapper)
.serialize(versionWorkspace, "$friendlyName.html")
.write(versionWorkspace, "$friendlyName.html")

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

classMap.forEach { (packageName, classes) ->
packagePage(versionWorkspace, packageName, classes)
.serialize(versionWorkspace, "$packageName/index.html")
.write(versionWorkspace, "$packageName/index.html")
}

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

licensePage(versionWorkspace, licenses)
.serialize(versionWorkspace, "licenses.html")
.write(versionWorkspace, "licenses.html")

overviewPage(versionWorkspace, classMap.keys)
.serialize(versionWorkspace, "index.html")
.write(versionWorkspace, "index.html")

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

versionsPage(config.welcomeMessage, versions)
.serialize(workspace, "index.html")
.write(workspace, "index.html")
}
}

Expand Down Expand Up @@ -310,7 +306,7 @@ open class WebGenerator(override val workspace: Workspace, val config: WebConfig
)

components.forEach { (tag, content, callback) ->
appendLine("const ${tag}Component = `${transformHtml(content.documentElement.serialize(prettyPrint = false))}`;")
appendLine("const ${tag}Component = `${transformHtml(content)}`;")
appendLine("const ${tag}ComponentCallback = (e) => {")
if (callback != null) {
appendLine(callback)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

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

import kotlinx.html.*
import me.kcra.takenaka.generator.web.StyleProvider
import me.kcra.takenaka.generator.web.util.*

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

p(classes = "badge ${styleProvider.apply("badge-$lowercase", "background-color:$color;")}")
styleProvider.apply("badge-$lowercase::before", "content:\"$content\";")
} else {
p(classes = "badge") {
style = "background-color:$color"
+content
p(classes = "badge", style = "background-color:$color") {
append(content)
}
}
}
Expand All @@ -48,16 +47,15 @@ fun FlowContent.badgeComponent(content: String, color: String, styleProvider: St
* @param color the badge color in a CSS compatible format
* @param styleProvider the style provider, used for generating stylesheets
*/
fun TR.badgeColumnComponent(content: String, color: String, styleProvider: StyleProvider? = null) {
fun HTMLBuilder.badgeColumnComponent(content: String, color: String, styleProvider: StyleProvider? = null) {
if (styleProvider != null) {
val lowercase = content.lowercase()

td(classes = "badge ${styleProvider.apply("badge-$lowercase", "background-color:$color;")}")
styleProvider.apply("badge-$lowercase::before", "content:\"$content\";")
} else {
td(classes = "badge") {
style = "background-color:$color"
+content
td(classes = "badge", style = "background-color:$color") {
append(content)
}
}
}
Expand All @@ -69,19 +67,18 @@ fun TR.badgeColumnComponent(content: String, color: String, styleProvider: Style
* @param color the badge color in a CSS compatible format
* @param styleProvider the style provider, used for generating stylesheets
*/
fun FlowContent.textBadgeComponent(content: String, color: String, styleProvider: StyleProvider? = null) {
fun HTMLBuilder.textBadgeComponent(content: String, color: String, styleProvider: StyleProvider? = null) {
val lowercase = content.lowercase()

if (styleProvider != null) {
span(classes = "badge-text ${styleProvider.apply("badge-text-$lowercase", "")}")
styleProvider.apply("badge-text-$lowercase::before", "color:$color;content:\"$content\";")
styleProvider.apply("badge-text-$lowercase::after", "content:\": \";")
} else {
span(classes = "badge-text") {
style = "color:$color"
+content
span(classes = "badge-text", style = "color:$color") {
append(content)
}
+": "
append(": ")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,20 @@

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

import kotlinx.html.*
import me.kcra.takenaka.generator.web.util.*

/**
* Appends a footer.
*/
fun FlowContent.footerComponent() {
fun HTMLBuilder.footerComponent() {
footer {
spacerBottomSlimComponent()
div(classes = "footer-content") {
p {
+"Built with lots of coffee and ❤️, for people by people."
append("Built with lots of coffee and ❤️, for people by people.")
}
a(href = "https://github.com/zlataovce/takenaka", classes = "icon-link") {
attributes["aria-label"] = "GitHub"
unsafe {
+"""<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>"""
}
a(href = "https://github.com/zlataovce/takenaka", classes = "icon-link", ariaLabel = "GitHub") {
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>""")
}
}
}
Expand All @@ -42,6 +39,6 @@ fun FlowContent.footerComponent() {
/**
* Appends a footer component placeholder that is replaced with a real navbar dynamically.
*/
fun FlowContent.footerPlaceholderComponent() {
fun HTMLBuilder.footerPlaceholderComponent() {
footer {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,36 +17,34 @@

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

import kotlinx.html.*
import me.kcra.takenaka.generator.web.util.*

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

/**
* Appends a script element declaring a version root path global variable to a head element.
*
* @param rootPath the path to the version root directory
*/
fun HEAD.versionRootComponent(rootPath: String = "./") {
fun HTMLBuilder.versionRootComponent(rootPath: String = "./") {
script {
unsafe {
+"""window.root = "$rootPath";"""
}
append("""window.root = "$rootPath";""")
}
}

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

// https://ogp.me/#metadata
Expand Down
Loading

0 comments on commit a0dcaad

Please sign in to comment.