From 18bc15caf53052c606a2cd187462c757fca6c691 Mon Sep 17 00:00:00 2001 From: severn-everett Date: Wed, 31 May 2023 10:02:10 +0200 Subject: [PATCH] Upgrades to Kotlin and Gradle versions (#208) * Upgraded Kotlin to 1.8; Upgraded Gradle to 7.6; Addressing code deprecation warnings; Removed Jackson dependency for JVMTest subset * Upgraded Kotlin to 1.8.20; Upgraded Gradle to 8.1.1 --- README.md | 2 +- build.gradle.kts | 11 +--- buildSrc/build.gradle.kts | 4 +- .../kotlinx/html/generate/attributes.kt | 2 +- .../kotlin/kotlinx/html/generate/codegen.kt | 8 +-- .../kotlin/kotlinx/html/generate/enums.kt | 8 ++- .../kotlin/kotlinx/html/generate/humanizer.kt | 2 +- .../main/kotlin/kotlinx/html/generate/kdoc.kt | 4 +- .../main/kotlin/kotlinx/html/generate/main.kt | 14 ++--- .../kotlin/kotlinx/html/generate/model.kt | 4 +- .../kotlin/kotlinx/html/generate/rules.kt | 2 +- .../kotlinx/html/generate/tag-builders.kt | 4 +- .../kotlin/kotlinx/html/generate/tagsgen.kt | 62 +++++++++---------- .../main/kotlin/kotlinx/html/generate/util.kt | 9 +++ gradle/wrapper/gradle-wrapper.properties | 2 +- src/commonMain/kotlin/stream.kt | 8 +-- src/jsMain/kotlin/dom-js.kt | 8 +-- src/jsMain/kotlin/injector.kt | 5 +- src/jsTest/kotlin/trees.kt | 10 +-- src/jvmMain/kotlin/dom-jvm.kt | 2 +- src/jvmTest/kotlin/dom-trees.kt | 2 +- 21 files changed, 90 insertions(+), 83 deletions(-) create mode 100644 buildSrc/src/main/kotlin/kotlinx/html/generate/util.kt diff --git a/README.md b/README.md index c2523057..8c446364 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ [![Kotlin Stable](https://kotl.in/badges/stable.svg)](https://kotlinlang.org/docs/components-stability.html) [![Official JetBrains Project](https://jb.gg/badges/official.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub) [![GitHub license](https://img.shields.io/badge/license-Apache%20License%202.0-green.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0) -[![Kotlin](https://img.shields.io/badge/kotlin-1.7.10-blue.svg?logo=kotlin)](http://kotlinlang.org) +[![Kotlin](https://img.shields.io/badge/kotlin-1.8.20-blue.svg?logo=kotlin)](http://kotlinlang.org) [![npm](https://img.shields.io/npm/v/kotlinx-html.svg)](https://www.npmjs.com/package/kotlinx-html) [![TeamCity (simple build status)](https://teamcity.jetbrains.com/app/rest/builds/aggregated/strob:\(branch:\(buildType:\(id:KotlinTools_KotlinxHtml_BuildGradleMasterBranch\),policy:active_history_and_active_vcs_branches\),locator:\(buildType:\(id:KotlinTools_KotlinxHtml_BuildGradleMasterBranch\)\)\)/statusIcon.svg)](https://teamcity.jetbrains.com/viewType.html?buildTypeId=KotlinTools_KotlinxHtml_BuildGradleMasterBranch&branch_Kotlin_KotlinX=%3Cdefault%3E&tab=buildTypeStatusDiv&guest=1) diff --git a/build.gradle.kts b/build.gradle.kts index deaa0524..87ad15ce 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,14 +1,12 @@ import Build_gradle.MavenPomFile import kotlinx.html.js.packageJson -import org.apache.tools.ant.taskdefs.condition.Os -import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsSetupTask /** * This build script supports following parameters: * -PversionTag - works together with "branch-build" profile and overrides "-SNAPSHOT" suffix of the version. */ plugins { - kotlin("multiplatform") version "1.7.10" + kotlin("multiplatform") version "1.8.20" id("maven-publish") id("signing") } @@ -192,16 +190,13 @@ kotlin { val jvmMain by getting { dependencies { - implementation(kotlin("stdlib-jdk8")) + implementation(kotlin("stdlib")) } } val jvmTest by getting { dependencies { implementation(kotlin("test-junit")) - /* Jackson is required to parse declarations.json. */ - implementation("com.fasterxml.jackson.core:jackson-core:2.10.1") - implementation("com.fasterxml.jackson.core:jackson-databind:2.10.1") } } @@ -244,7 +239,7 @@ tasks.withType { "Build-Jdk" to System.getProperty("java.version"), "Implementation-Vendor" to "JetBrains s.r.o.", "Implementation-Version" to archiveVersion.get(), - "Created-By" to org.gradle.util.GradleVersion.current() + "Created-By" to GradleVersion.current() ) } } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index e844e19c..de9ec918 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - kotlin("jvm") version "1.7.10" + kotlin("jvm") version "1.8.20" } repositories { @@ -7,6 +7,6 @@ repositories { } dependencies { - implementation(kotlin("stdlib-jdk8")) + implementation(kotlin("stdlib")) implementation("com.sun.xsom:xsom:20140925") } \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/attributes.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/attributes.kt index d6041486..48e42873 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/attributes.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/attributes.kt @@ -41,7 +41,7 @@ fun Appendable.facade(facade: AttributeFacade) { } facade.attributes.filter { !isAttributeExcluded(it.name) }.forEach { attribute -> - if (attribute.name.isLowerCase() || attribute.name.toLowerCase() !in facade.attributeNames) { + if (attribute.name.isLowerCase() || attribute.name.lowercase() !in facade.attributeNames) { attributeProperty(attribute, receiver = facadeName, indent = 0) } } diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/codegen.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/codegen.kt index b05c0eb5..a6a1f17c 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/codegen.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/codegen.kt @@ -35,11 +35,11 @@ fun Appendable.import(name : String) { fun Appendable.doNotEditWarning() { append("/") append("*".repeat(79)) - appendln() + appendLine() append(" DO NOT EDIT") - appendln() + appendLine() append(" This file was generated by module generate") - appendln() + appendLine() append("*".repeat(79)) append("/") } @@ -211,7 +211,7 @@ fun O.defineIs(expression : CharSequence) : O { return this } -fun Appendable.emptyLine() { appendln() } +fun Appendable.emptyLine() { appendLine() } fun T.with(block : T.() -> Unit) : T { block() diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/enums.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/enums.kt index f81e0d6f..023a08e7 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/enums.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/enums.kt @@ -1,5 +1,7 @@ package kotlinx.html.generate +import java.util.* + val reservedNames = setOf("class", "val", "var", "object", "true", "false", "as", "is", "for") fun String.replaceIfReserved() = if (this in reservedNames) "html" + this.capitalize() else this @@ -10,7 +12,7 @@ fun List.toAttributeValues() : List = fun Appendable.enumObject(attribute : AttributeInfo) { val name = attribute.enumTypeName - appendln("@Suppress(\"unused\")") + appendLine("@Suppress(\"unused\")") clazz(Clazz(name, isObject = true)) { attribute.enumValues.forEach { append(" ") @@ -32,7 +34,7 @@ fun Appendable.enum(attribute : AttributeInfo) { val name = attribute.enumTypeName val realValue = Var("realValue", "String", false, true) - appendln("@Suppress(\"unused\")") + appendLine("@Suppress(\"unused\")") append("enum ") clazz(Clazz(name, variables = listOf(realValue), parents = listOf("AttributeEnum"))) { attribute.enumValues.forEachIndexed { idx, it -> @@ -45,7 +47,7 @@ fun Appendable.enum(attribute : AttributeInfo) { append(",") } - appendln() + appendLine() } } diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/humanizer.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/humanizer.kt index 570478b6..fc2c69c2 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/humanizer.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/humanizer.kt @@ -5,7 +5,7 @@ fun String.humanize() : String { return "empty" } - val fixedAllUpper = if (all { it.isUpperCase() }) toLowerCase() else this + val fixedAllUpper = if (all { it.isUpperCase() }) lowercase() else this val fixedFirstUpper = fixedAllUpper.decapitalize() return fixedFirstUpper.replaceHyphensToCamelCase().makeCamelCaseByDictionary().replaceMistakesAndUglyWords().decapitalize() diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/kdoc.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/kdoc.kt index 3f69c4a6..fb98b00e 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/kdoc.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/kdoc.kt @@ -15,7 +15,7 @@ fun fillKdocRepositoryExtension() { KdocRepository.tags = parseDocInfos() } -val TagInfo.kdoc: KDocInfo? get() = KdocRepository.tags[this.name.toLowerCase()] +val TagInfo.kdoc: KDocInfo? get() = KdocRepository.tags[this.name.lowercase()] private fun parseDocInfos(): Map { val html = parseDocInfo(HTML_TABLE_URL) @@ -30,7 +30,7 @@ private fun parseDocInfo(xmlPath: URL): List { return xml.getElementsByTagName("tag").asList().map { node -> KDocInfo( - name = node.getAttributeString("name").toLowerCase(), + name = node.getAttributeString("name").lowercase(), description = node.getAttributeString("description").capitalize(), helpref = node.getAttributeString("helpref") ) diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/main.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/main.kt index 45d7a050..3243f49c 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/main.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/main.kt @@ -63,8 +63,8 @@ fun generate(packg: String, todir: String, jsdir: String) { emptyLine() Repository.tags.values.filterIgnored().forEach { - val contentlessTag = it.name.toLowerCase() in contentlessTags - if (it.possibleChildren.isEmpty() && it.name.toLowerCase() !in emptyTags && !contentlessTag) { + val contentlessTag = it.name.lowercase() in contentlessTags + if (it.possibleChildren.isEmpty() && it.name.lowercase() !in emptyTags && !contentlessTag) { consumerBuilderShared(it, false) } else if (contentlessTag) { deprecated("This tag doesn't support content or requires unsafe (try unsafe {})") @@ -92,8 +92,8 @@ fun generate(packg: String, todir: String, jsdir: String) { emptyLine() Repository.tags.values.filterIgnored().forEach { - val contentlessTag = it.name.toLowerCase() in contentlessTags - if (it.possibleChildren.isEmpty() && it.name.toLowerCase() !in emptyTags && !contentlessTag) { + val contentlessTag = it.name.lowercase() in contentlessTags + if (it.possibleChildren.isEmpty() && it.name.lowercase() !in emptyTags && !contentlessTag) { consumerBuilderJS(it, false) } else if (contentlessTag) { deprecated("This tag doesn't support content or requires unsafe (try unsafe {})") @@ -272,10 +272,10 @@ fun generate(packg: String, todir: String, jsdir: String) { } append(";") - appendln() + appendLine() variable(Var(name = "text", type = "String")) - appendln() + appendLine() getter() defineIs(StringBuilder().apply { append("&".quote()) @@ -285,7 +285,7 @@ fun generate(packg: String, todir: String, jsdir: String) { append(" + ") append(";".quote()) }) - appendln() + appendLine() } } } diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/model.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/model.kt index e64f43ab..f240c81e 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/model.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/model.kt @@ -73,7 +73,7 @@ data class AttributeInfo( val HasType.typeName : String get() = if (type == AttributeType.ENUM) enumTypeName else type.typeName -fun String.isLowerCase() = this.toLowerCase() == this +fun String.isLowerCase() = this.lowercase() == this data class TagInfo( val name : String, @@ -84,7 +84,7 @@ data class TagInfo( val suggestedAttributes : Set, val tagGroupNames: List ) { - val className: String = name.humanize().toUpperCase() + val className: String = name.humanize().uppercase() val memberName: String = name.humanize().replaceIfReserved() } diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/rules.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/rules.kt index f7b227e0..954a8958 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/rules.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/rules.kt @@ -47,7 +47,7 @@ val tagIgnoreList = setOf( "menu", "menuitem" ) -fun Iterable.filterIgnored() = filter { it.name.toLowerCase() !in tagIgnoreList } +fun Iterable.filterIgnored() = filter { it.name.lowercase() !in tagIgnoreList } val globalSuggestedAttributeNames = setOf("class") diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/tag-builders.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/tag-builders.kt index 619fe087..d7cc614d 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/tag-builders.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/tag-builders.kt @@ -23,8 +23,8 @@ track wbr""".lines().toSet() fun Appendable.htmlTagBuilders(receiver : String, tag : TagInfo) { - val contentlessTag = tag.name.toLowerCase() in contentlessTags - val probablyContentOnly = tag.possibleChildren.isEmpty() && tag.name.toLowerCase() !in emptyTags && !contentlessTag + val contentlessTag = tag.name.lowercase() in contentlessTags + val probablyContentOnly = tag.possibleChildren.isEmpty() && tag.name.lowercase() !in emptyTags && !contentlessTag htmlTagBuilderMethod(receiver, tag, true) if (probablyContentOnly) { htmlTagBuilderMethod(receiver, tag, false) diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/tagsgen.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/tagsgen.kt index 9d17929b..1bdca4a1 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/tagsgen.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/tagsgen.kt @@ -8,8 +8,8 @@ fun Appendable.tagClass(tag : TagInfo, excludeAttributes : Set) { val allParentIfaces = parentAttributeIfaces + parentElementIfaces val betterParentIfaces = humanizeJoin(allParentIfaces) - val namespace = tagNamespaces[tag.name.toLowerCase()] - val customizableNamespace = tag.name.toLowerCase() in tagsWithCustomizableNamespace + val namespace = tagNamespaces[tag.name.lowercase()] + val customizableNamespace = tag.name.lowercase() in tagsWithCustomizableNamespace val parameters = mutableListOf( Var("initialAttributes", "Map", false, false, true), @@ -29,7 +29,7 @@ fun Appendable.tagClass(tag : TagInfo, excludeAttributes : Set) { superConstructorArguments[3] = "namespace" } - appendln("@Suppress(\"unused\")") + appendLine("@Suppress(\"unused\")") clazz(Clazz( name = tag.className, variables = parameters, @@ -43,21 +43,21 @@ fun Appendable.tagClass(tag : TagInfo, excludeAttributes : Set) { }, isOpen = true )) { - val lowerCasedNames = tag.attributes.map {it.name.toLowerCase()}.toSet() + val lowerCasedNames = tag.attributes.map {it.name.lowercase()}.toSet() val attributes = tag.attributes.filter {it.name !in excludeAttributes} attributes.filter {!isAttributeExcluded(it.name) }.forEach { attribute -> - if (attribute.name[0].isLowerCase() || attribute.name.toLowerCase() !in lowerCasedNames) { + if (attribute.name[0].isLowerCase() || attribute.name.lowercase() !in lowerCasedNames) { attributeProperty(attribute) } } fun contentlessTagDeprecation() { indent() - appendln("@Deprecated(\"This tag most likely doesn't support text content or requires unsafe content (try unsafe {}\")") + appendLine("@Deprecated(\"This tag most likely doesn't support text content or requires unsafe content (try unsafe {}\")") } - if (tag.name.toLowerCase() in contentlessTags) { + if (tag.name.lowercase() in contentlessTags) { contentlessTagDeprecation() indent() @@ -66,11 +66,11 @@ fun Appendable.tagClass(tag : TagInfo, excludeAttributes : Set) { indent(2) append("@Suppress(\"DEPRECATION\") ") functionCall("entity", listOf("this")) - appendln() + appendLine() indent() } - appendln() + appendLine() contentlessTagDeprecation() indent() @@ -79,11 +79,11 @@ fun Appendable.tagClass(tag : TagInfo, excludeAttributes : Set) { indent(2) append("@Suppress(\"DEPRECATION\") ") functionCall("text", listOf("this")) - appendln() + appendLine() indent() } - appendln() + appendLine() contentlessTagDeprecation() indent() @@ -92,11 +92,11 @@ fun Appendable.tagClass(tag : TagInfo, excludeAttributes : Set) { indent(2) receiverDot("super") functionCall("text", listOf("s")) - appendln() + appendLine() indent() } - appendln() + appendLine() contentlessTagDeprecation() indent() @@ -105,11 +105,11 @@ fun Appendable.tagClass(tag : TagInfo, excludeAttributes : Set) { indent(2) receiverDot("super") functionCall("text", listOf("n")) - appendln() + appendLine() indent() } - appendln() + appendLine() contentlessTagDeprecation() indent() @@ -118,7 +118,7 @@ fun Appendable.tagClass(tag : TagInfo, excludeAttributes : Set) { indent(2) receiverDot("super") functionCall("entity", listOf("e")) - appendln() + appendLine() indent() } } @@ -135,7 +135,7 @@ fun Appendable.tagClass(tag : TagInfo, excludeAttributes : Set) { if (commons.isNotEmpty()) { parentElementIfaces.forEach { group -> variable(Var(name = "as" + group, type = group), receiver = tag.className) - appendln() + appendLine() getter() defineIs("this") emptyLine() @@ -165,7 +165,7 @@ internal fun Appendable.tagAttributeVar(attribute: AttributeInfo, receiver: Stri fun probeType(htmlClassName : String) : Boolean = htmlClassName in knownTagClasses -private fun tagCandidates(tag : TagInfo) = (listOf(tag.memberName) + tagReplacements.map { tag.memberName.replace(it.first.toRegex(), it.second) }).flatMap { listOf(it.capitalize(), it.toUpperCase()) }.distinct() +private fun tagCandidates(tag : TagInfo) = (listOf(tag.memberName) + tagReplacements.map { tag.memberName.replace(it.first.toRegex(), it.second) }).flatMap { listOf(it.capitalize(), it.uppercase()) }.distinct() fun getTagResultClass(tag: TagInfo) = tagCandidates(tag) @@ -173,7 +173,7 @@ fun getTagResultClass(tag: TagInfo) = .firstOrNull { probeType(it) } ?: "HTMLElement" fun contentArgumentValue(tag : TagInfo, blockOrContent : Boolean) = when { - tag.name.toLowerCase() in emptyTags -> "block" + tag.name.lowercase() in emptyTags -> "block" blockOrContent -> "block" else -> "{+content}" } @@ -186,7 +186,7 @@ fun Appendable.consumerBuilderJS(tag : TagInfo, blockOrContent : Boolean) { "this" ) - if (tag.name.toLowerCase() in tagsWithCustomizableNamespace) { + if (tag.name.lowercase() in tagsWithCustomizableNamespace) { constructorArgs.add("namespace") } @@ -216,7 +216,7 @@ fun Appendable.consumerBuilderShared(tag : TagInfo, blockOrContent : Boolean) { "this" ) - if (tag.name.toLowerCase() in tagsWithCustomizableNamespace) { + if (tag.name.lowercase() in tagsWithCustomizableNamespace) { constructorArgs.add("namespace") } @@ -242,7 +242,7 @@ fun Appendable.htmlTagBuilderMethod(receiver : String, tag : TagInfo, blockOrCon "consumer" ) - if (tag.name.toLowerCase() in tagsWithCustomizableNamespace) { + if (tag.name.lowercase() in tagsWithCustomizableNamespace) { constructorArgs.add("namespace") } @@ -269,7 +269,7 @@ fun Appendable.htmlTagEnumBuilderMethod(receiver : String, tag : TagInfo, blockO buildSuggestedAttributesArgument(tag, mapOf(enumAttribute.fieldName to enumAttribute.typeName + "." + enumValue.fieldName + ".realValue")), "consumer" ) - if (tag.name.toLowerCase() in tagsWithCustomizableNamespace) { + if (tag.name.lowercase() in tagsWithCustomizableNamespace) { constructorArgs.add("namespace") } @@ -317,15 +317,15 @@ private fun buildSuggestedAttributesArgument(tag: TagInfo, predefinedValues : Ma } private fun tagBuilderCouldBeInline(tag: TagInfo, blockOrContent: Boolean): Boolean = when { - tag.name.toLowerCase() in emptyTags -> true + tag.name.lowercase() in emptyTags -> true blockOrContent -> true else -> false } private fun tagBuilderFunctionArguments(tag: TagInfo, blockOrContent : Boolean) : ArrayList { val arguments = ArrayList() - val customizableNamespace = tag.name.toLowerCase() in tagsWithCustomizableNamespace - val defaultNamespace: String = tagNamespaces[tag.name.toLowerCase()]?.quote().toString() + val customizableNamespace = tag.name.lowercase() in tagsWithCustomizableNamespace + val defaultNamespace: String = tagNamespaces[tag.name.lowercase()]?.quote().toString() tag.mergeAttributes().filter {it.name in tag.suggestedAttributes}.forEach { attribute -> val type = when (attribute.type) { @@ -350,7 +350,7 @@ private fun tagBuilderFunctionArguments(tag: TagInfo, blockOrContent : Boolean) } when { - tag.name.toLowerCase() in emptyTags || blockOrContent -> { + tag.name.lowercase() in emptyTags || blockOrContent -> { addNamespaceParameter() addBlockParameter() } @@ -364,14 +364,14 @@ private fun tagBuilderFunctionArguments(tag: TagInfo, blockOrContent : Boolean) } private fun Appendable.htmlDslMarker() { - appendln("@HtmlTagMarker") + appendLine("@HtmlTagMarker") } private fun Appendable.tagKdoc(tag: TagInfo) { val kdoc = tag.kdoc ?: return - appendln("/**") - appendln(" * ${kdoc.description}") - appendln(" */") + appendLine("/**") + appendLine(" * ${kdoc.description}") + appendLine(" */") } private val inlineTags = """a diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/util.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/util.kt new file mode 100644 index 00000000..a0f6a513 --- /dev/null +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/util.kt @@ -0,0 +1,9 @@ +package kotlinx.html.generate + +import java.util.* + +private val locale = Locale.getDefault() + +fun String.capitalize() = replaceFirstChar { if (it.isLowerCase()) it.titlecase(locale) else it.toString() } + +fun String.decapitalize() = replaceFirstChar { it.lowercase(locale) } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d7e66b5c..1f017e4e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/commonMain/kotlin/stream.kt b/src/commonMain/kotlin/stream.kt index e116b974..6a3719df 100644 --- a/src/commonMain/kotlin/stream.kt +++ b/src/commonMain/kotlin/stream.kt @@ -134,7 +134,7 @@ class HTMLStreamBuilder(val out: O, val prettyPrint: Boolean } } -private val AVERAGE_PAGE_SIZE = 32768 +private const val AVERAGE_PAGE_SIZE = 32768 fun createHTML(prettyPrint: Boolean = true, xhtmlCompatible: Boolean = false): TagConsumer = HTMLStreamBuilder( @@ -156,7 +156,7 @@ private val escapeMap = mapOf( '&' to "&", '\"' to """ ).let { mappings -> - val maxCode = mappings.keys.map { it.toInt() }.maxOrNull() ?: -1 + val maxCode = mappings.keys.maxOfOrNull { it.code } ?: -1 Array(maxCode + 1) { mappings[it.toChar()] } } @@ -184,8 +184,8 @@ private fun Appendable.escapeAppend(s: CharSequence) { val mappings = escapeMap val size = mappings.size - for (idx in 0..s.length - 1) { - val ch = s[idx].toInt() + for (idx in s.indices) { + val ch = s[idx].code if (ch < 0 || ch >= size) continue val escape = mappings[ch] if (escape != null) { diff --git a/src/jsMain/kotlin/dom-js.kt b/src/jsMain/kotlin/dom-js.kt index c7157fa0..62e18cb1 100644 --- a/src/jsMain/kotlin/dom-js.kt +++ b/src/jsMain/kotlin/dom-js.kt @@ -33,7 +33,7 @@ class JSDOMBuilder(val document : Document) : TagConsumer throw IllegalStateException("No current tag") - path.last().tagName.toLowerCase() != tag.tagName.toLowerCase() -> throw IllegalStateException("Wrong current tag") + path.last().tagName.lowercase() != tag.tagName.lowercase() -> throw IllegalStateException("Wrong current tag") else -> path.last().let { node -> if (value == null) { node.removeAttribute(attribute) @@ -47,13 +47,13 @@ class JSDOMBuilder(val document : Document) : TagConsumer Unit) { when { path.isEmpty() -> throw IllegalStateException("No current tag") - path.last().tagName.toLowerCase() != tag.tagName.toLowerCase() -> throw IllegalStateException("Wrong current tag") + path.last().tagName.lowercase() != tag.tagName.lowercase() -> throw IllegalStateException("Wrong current tag") else -> path.last().setEvent(event, value) } } override fun onTagEnd(tag: Tag) { - if (path.isEmpty() || path.last().tagName.toLowerCase() != tag.tagName.toLowerCase()) { + if (path.isEmpty() || path.last().tagName.lowercase() != tag.tagName.lowercase()) { throw IllegalStateException("We haven't entered tag ${tag.tagName} but trying to leave") } @@ -101,7 +101,7 @@ class JSDOMBuilder(val document : Document) : TagConsumer F.injectTo(bean: T, field: KMutableProperty1) { field.set(bean, this) } +@Suppress("UnsafeCastFromDynamic") private fun F.injectToUnsafe(bean: T, field: KMutableProperty1) { injectTo(bean, field.asDynamic()) } @@ -35,7 +36,7 @@ class InjectorConsumer( private val tagNamesMap = rules .filter { it.first is InjectByTagName } .map { it.first as InjectByTagName to it.second } - .groupBy({ it.first.tagName.toLowerCase() }, { it.second }) + .groupBy({ it.first.tagName.lowercase() }, { it.second }) private val rootCaptures = rules.filter { it.first == InjectRoot }.map { it.second } private val customCaptures = @@ -53,7 +54,7 @@ class InjectorConsumer( } if (tagNamesMap.isNotEmpty()) { - tagNamesMap[node.tagName.toLowerCase()]?.forEach { field -> + tagNamesMap[node.tagName.lowercase()]?.forEach { field -> node.injectToUnsafe(bean, field) } } diff --git a/src/jsTest/kotlin/trees.kt b/src/jsTest/kotlin/trees.kt index 31cf1a35..1e7197a0 100644 --- a/src/jsTest/kotlin/trees.kt +++ b/src/jsTest/kotlin/trees.kt @@ -190,7 +190,7 @@ class DomTreeImplTest { } @Suppress("UNCHECKED_CAST") - assertEquals("http://www.w3.org/2000/svg", (wrapper.childNodes.asList() as List).first { it.tagName.toLowerCase() == "svg" }.namespaceURI) + assertEquals("http://www.w3.org/2000/svg", (wrapper.childNodes.asList() as List).first { it.tagName.lowercase() == "svg" }.namespaceURI) } @test fun assignEvent() { @@ -222,10 +222,10 @@ class DomTreeImplTest { val col = document.create.col() val colGroup = document.create.colGroup() - assertEquals("TH", th.tagName.toUpperCase()) - assertEquals("TD", td.tagName.toUpperCase()) - assertEquals("COL", col.tagName.toUpperCase()) - assertEquals("COLGROUP", colGroup.tagName.toUpperCase()) + assertEquals("TH", th.tagName.uppercase()) + assertEquals("TD", td.tagName.uppercase()) + assertEquals("COL", col.tagName.uppercase()) + assertEquals("COLGROUP", colGroup.tagName.uppercase()) } @test fun testPrepend() { diff --git a/src/jvmMain/kotlin/dom-jvm.kt b/src/jvmMain/kotlin/dom-jvm.kt index 96a6b7a0..c6440b10 100644 --- a/src/jvmMain/kotlin/dom-jvm.kt +++ b/src/jvmMain/kotlin/dom-jvm.kt @@ -53,7 +53,7 @@ class HTMLDOMBuilder(val document : Document) : TagConsumer { } override fun onTagEnd(tag: Tag) { - if (path.isEmpty() || path.last().tagName.toLowerCase() != tag.tagName.toLowerCase()) { + if (path.isEmpty() || path.last().tagName.lowercase() != tag.tagName.lowercase()) { throw IllegalStateException("We haven't entered tag ${tag.tagName} but trying to leave") } diff --git a/src/jvmTest/kotlin/dom-trees.kt b/src/jvmTest/kotlin/dom-trees.kt index 97eb80a3..63194541 100644 --- a/src/jvmTest/kotlin/dom-trees.kt +++ b/src/jvmTest/kotlin/dom-trees.kt @@ -13,7 +13,7 @@ class TestDOMTrees { +"content" } - assertEquals("div", tree.getElementById("test-node")?.tagName?.toLowerCase()) + assertEquals("div", tree.getElementById("test-node")?.tagName?.lowercase()) } @test fun `able to create complex tree and render it with pretty print`() {