kotlin / kotlinx.html Goto Github PK
View Code? Open in Web Editor NEWKotlin DSL for HTML
License: Apache License 2.0
Kotlin DSL for HTML
License: Apache License 2.0
s/legEnd/legend/g
I was very surprised to find out that its name differs from the one used in JavaScript.
When I use inline css in an html or jsp file, IntelliJ gives me nice syntax coloring and autocompletion:
Is there a type safe way to do inline css using kotlinx.html other than using a string? Or at least a way to get autocompletion and syntax coloring?
body {
div {
style = "background: yellow;border: solid thin blue"
}
}
Hello.
Is there a way to declare <meta charset="UTF-8" />
? Also, why meta
function accepts code block, like a container-tag?
Actual signature:
meta(name: String?, content: String?, block: kotlinx.html.META.() -> kotlin.Unit)
The onsearch event is missing from input tag of type search. For instance, if I want to generate the following Html, onsearch does not exist.
<input type="search" onsearch="myFunction()">
This would shorten the following code:
td { +x.toString() }
td { +y.toString() }
td { +z.toString() }
to look like this:
td { +x }
td { +y }
td { +z }
Unsafe content support for DOM JVM as per #6
Trying to use these html tags in a kotlin2js project with gradle:
apply plugin: 'kotlin2js'
repositories {
mavenCentral()
jcenter()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
def kotlinx_html_version = "0.6.3"
compile "org.jetbrains.kotlinx:kotlinx-html-jvm:${kotlinx_html_version}"
compile "org.jetbrains.kotlinx:kotlinx-html-js:${kotlinx_html_version}"
}
but import kotlinx.html.* in my Main.kt file never works. Always get Unresolved reference
for any tags. I feel like I'm very close. Sorry, new to kotlin and kotlinjs.
I followed steps in https://medium.com/@ali.muzaffar/building-a-full-stack-web-app-in-kotlin-af8e8fe1f5dc and got everything working. Now just trying to add this kotlinx html support.
Environment: Kotlin JS 1.1.4-3
with kotlinx.html 0.6.4
test text
I use the following javascript, it works as expected, document.getElementByID('TestInput').value
The code is as follows:
A bug or am I doing something wrong?
import kotlinx.html.*
import kotlinx.html.dom.create
import kotlinx.html.js.*
import org.w3c.dom.Element
import org.w3c.dom.events.Event
import kotlin.browser.*
fun onClick(e:Event){
val element = document.getElementById("TestInput")
window.alert(element?.getAttribute("value").toString())
}
fun main(args: Array<String>) {
val root: Element = document.getElementById("root")!!
val myDiv = document.create.div {
input(InputType.text) {
id="TestInput"
value="test text"
}
button {
+"Get input.value"
onClickFunction=::onClick
}
}
root.appendChild(myDiv)
}
Also, menuitem is missing
Apparently those contents come from XSD, but in the end of the day, they are quite useless and very confusing in kotlinx.html.
if I write something invalid according to XSD, like body > span > div
body { // BODY creates FlowContent
span { // SPAN creates PhrasingContent
div { // DIV can only be created in _FlowContent_, not in SPAN
// DIV is still allowed, because it is actually created in BODY,
// not in innermost parent SPAN
}
}
}
it is still silently accepted by the compiler and even leads to obscure IllegalStateException("You can't change tag attribute because it was already passed to the downstream")
if I try to change attributes.
To me this seems like a general problem of 'fall-through' builder design.
Both functions, FlowContent.i
and PhrasingContent.i
are identical: they produce the same I
object.
But there's no common abstraction between those two functions. Which leads to the third problem.
I chose to use Tag
as a basis for my DSL, which seemed like a good base class. But in the end I had to write the ugliest code in a decade of my career:
fun Tag.mdl_icon(icon: String, text: String? = null) {
if (this is FlowContent) {
i("material-icons") {
+icon
}
if (text != null) {
span(classes = "visuallyhidden") {
+text
}
}
} else if (this is PhrasingContent) {
i("material-icons") {
+icon
}
if (text != null) {
span(classes = "visuallyhidden") {
+text
}
}
}
}
Both if
and else
part are identical, but functions i
and span
are different.
Condition like if (this is FlowContent || this is PhrasingContent)
cannot work, of course.
on getting started page it says I can download jar, zip and webjar from release page. but on release page there is only a zip of source code!
for one it may be trivial to get it from repository (http://dl.bintray.com/kotlinx/kotlinx/org/jetbrains/kotlinx/) but won't it be easier if it was just on that page?
Function th is not working, it generates ClassCastException, version 0.6.4.
import kotlinx.html.js.*
import kotlinx.html.dom.create
import kotlin.browser.document
fun main(args: Array<String>) {
val td = document.create.td()
val th = document.create.th()
println("OK")
}
There are many links like this:
link("/myapp.ico", "shortcut icon", "image/x-icon")
where image/x-icon
is type
attribute. Using it via attributes["type"] = "image/png"
is not convenient for such one-liners.
val x = StringBuilder().appendHTML().html {
body {
article {
p {
}
a {
+"aaa"
}
span { }
}
}
}.toString()
Indent is placed in the wrong place, appending space to content.
Only Exceptions are:
https://github.com/Kotlin/kotlinx.html/blob/master/shared/src/main/kotlin/api.kt#L50
The visit function should catch Trowable.
As per HTML5 standard, only "get" and "post" are allowed, see https://www.w3.org/TR/html5/forms.html#attr-fs-method
e.g. <script type="text/babel">
workaround is
script {
attributes["type"] = "text/babel"
}
Append on document itself crashes with NPE
The single quotes are not escaped in event handlers. For instance, if I have an event like oninput="myFunction('id')"
, the generated html replaces '
with '
which is not expected.
This code:
div {
onclick = { event ->
window.alert("Kotlin!")
}
}
On this doc page:
https://github.com/kotlin/kotlinx.html/wiki/Events
No longer works.
I have a question I'm trying to use konlinx.html with spring.
How can I add csrf token into form tag?
Thanks in advance
I see there is a maxLength
property for HTML5's maxlength
but I don't see a minLength
property for HTML5's minlength
. Can this be added?
In case of exception, current implementation simply aborts the processing.
I've introduced an onError
handler in the TagConsumer
, so that the library:
As the result, it's possible to use such TagConsumer:
class SafeHtmlOutput(val result: PrintWriter) : TagConsumer<PrintWriter> by result.appendHTML()
override fun onError(exception: Exception) {
// prints a very basic error block
h4(classes = "error") {
style = "background-color: red; text-color: white"
onTagContent(exception.message ?: "Unknown error")
}
exception.printStackTrace() // send to stderr log
}
}
It cannot get much simpler than that. As you see, it has all the freedom to properly react to the exception. For example, the tag contents might simply remain empty, while the rest of the page remains fully-functional.
I use Kotlinx.html for stream-like processing: page headers are sent almost instantly (by abusing TagConsumer.finalize
and PrintWriter.flush
), while the rest is generated gradually, like in the original PHP (but with good compiler) for lighting-fast zero-delay instant content delivery. Therefore errors are rather common and must be handled.
I was trying to add additional attribute properties to make some of them easier, but setting attributes as extension properties never prints out to the final html.
For example, adding a data-toggle
attribute to a button:
var BUTTON.dataToggle: String?
get() = attributes["data-toggle"]
set(value) {
attributes["data-toggle"]
}
Calling this, doesn't work:
button {
classes = setOf("navbar-toggler", "d-lg-none")
type = ButtonType.button
dataToggle = "dropdown"
}
But this does:
button {
classes = setOf("navbar-toggler", "d-lg-none")
type = ButtonType.button
attributes["data-toggle"] = "dropdown"}
Is there something weird going on that I can't see?
The figcaption tag is missing in the kotlinx DSL.
See http://w3c.github.io/html-reference/figcaption.html
In fact it would be even more helpful if the docs could detail out how to add a custom tag on top of the existing library (if this is possible with kotlinx) (ie to show how to extend the kotlinx DSL). In https://github.com/kotlin/kotlinx.html/wiki/Micro-templating-and-DSL-customizing you already do so to some extent, but custom tags don't seem not to be covered there.
For now the only workaround seems to be
StringBuilder().apply {
appendHTML().figure() {
img {
src = movie.movieInfo?.coverImageURL
}
}
append("<figcaption class='picture-item__title pull-left'>" + movie.name + """</figcaption>""")
}
but by using kotlinx I'd like to avoid simple unstructured string-building.
There are SVG builders as well but they seems doesn't work because root svg element requires valid namespace on it
style(content = "ul > li { ... }")
will be rendered like
<style>
ul > li { ... }
</style>
which is wrong. Using
style {
unsafe { +" ... "}
}
as a workaround at the moment.
Hello.
If FormMethod
enumerates only standard form.action methods, why there are PUT
and DELETE
? If not, where's PATCH
?
Methods, other than GET
and POST
, seem to be prohibited:
https://stackoverflow.com/a/8054241/3050249
https://softwareengineering.stackexchange.com/a/211790
I would add it myself and make a pull request but for a reason beyond me the code excludes any attributes called lang. Why is that ?
I'm trying to test the HTML Application, my gradle.build
dependencies are:
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
compile "org.jetbrains.ktor:ktor-core:$ktor_version"
compile 'org.jetbrains.kotlinx:kotlinx-html:0.6.4'
compile "org.jetbrains.ktor:ktor-netty:$ktor_version"
compile "org.apache.commons:commons-email:1.4"
compile "org.slf4j:slf4j-simple:1.7.25"
compile "ch.qos.logback:logback-classic:1.2.1"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
I got the below error while running gradle build
:
Could not find org.jetbrains.kotlinx:kotlinx-html:0.6.4
It should be generalized tag interfaces to make easier to declare extension functions on generic tag types
it should be way to build unsafe content (with no escaping) as well
Like this
script {
+"some script text"
}
I have this code below, but it don't work:
classes = setOf("form-group")
label {
for_ = "exampleInputFile"
text("File input")
}
input {
type = enumValueOf("file")
id = "exampleInputFile"
}
p {
classes = setOf("help-block")
text("Example block-level help text here.")
}
}
div {
classes = setOf("checkbox")
label {
input {
type = enumValueOf("checkbox")
text("Check me out")
}
}
}```
When I run this code in my browser, it show the error:
```uncaught exception: IllegalStateException: No enum constant kotlinx.html.InputType.checkbox```
How can I fix that?
Couldn't see a license file for the kotlinx.html repository. Which license is used for KotlinX HTML?
I would like to compose methods without passing the parent. Need some kind of add method. Something like below:
private fun renderGame(g: Game) = document.create.div {
style = "margin:1rem;padding:1rem;background:yellow;display:flex"
add(renderHand(g.ph))
add(renderHand(g.dh))
}
private fun renderHand(h: Hand) = document.create.div {
style = "margin:1rem;padding:1rem;background:#DDDDDD"
div { b { +h.name } }
div {
h.cards.map { div { it.name } }
}
div { b { +"${h.points} points" } }
}
fun restoreListValues(e: Event) {
println("I'm here")
}
fun doForm(trTag: TR) {
trTag.td {
form {
name = "fmform"
encType = FormEncType.textPlain
action = "/server/"
method = FormMethod.post
onSubmitFunction = {
event - > restoreListValues(event)
}
}
}
}
After executing, nothing happens to that form, I could use onSubmit
, and the final form will have the onsubmit
value, but the problem is that it expects a string, which means I could only refer to the final compiled javascript code which has no way to access the kotlinJS context.
What I want is simple, just use a kotlinJS method to handle the onsubmit
event of a form.
How to achieve that?
The following are available at https://bintray.com/kotlin/kotlinx.html/kotlinx.html/0.6.1 but there is no kotlinx-html-common:
It would be nice if I could do this:
td { +age }
instead of this:
td { +age.toString() }
I'm not able to properly render an SVG tag, because it is not possible to include the xmlns:xlink="http://www.w3.org/1999/xlink" attribute. The library complains that this is not a valid attribute name.
The package kotlinx-html-jvm-0.6.1-sources.jar
exists, but it contains only the jvm-specific sources like dom.kt
and utilsImpl.ks
.
I guess, the main part should be in kotlinx-html-common
, but this package is marked as optional in 2d51862 and is actually missing in jCenter.
TD extends HtmBlockTag while TH extends HtmlInlineTag. Is that correct?
script(type = ScriptType.textJavaScript) { +"var str = 'some text';" } will result:
<script type="text/jscript">var str = 'some text';</script>how to avoid quotation in this case?
The instructions tell me that I can download a client jar from the releases page on github. There are no jars on the releases page: https://github.com/Kotlin/kotlinx.html/releases/tag/kotlinx-html-0.6.3
INPUT.autofocus
SELECT.required
Using Gradle 3.0, Kotlin 1.0.3, and the following build.gradle file, I get a compilation error:
Could not find method compileClient() for arguments [org.jetbrains.kotlinx:kotlinx.html.js:0.5.10] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
I get a different error if using "${kotlinx.html.version}" in place of the version number:
Could not get unknown property 'kotlinx' for object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
What I did get to work properly was calling the compile method on the js version of the library, but I doubt that the behavior is intended.
buildscript {
ext.kotlin_version = '1.0.3'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
repositories {
maven {
url "http://dl.bintray.com/kotlinx/kotlinx"
}
}
dependencies {
compile "org.jetbrains.kotlinx:kotlinx.html.jvm:0.5.10"
compileClient "org.jetbrains.kotlinx:kotlinx.html.js:0.5.10"
}
It should be way to set/append tag content rather than +
operator
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.