Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSDOMBuilder converts raw string contents to HTML tags #206

Open
aSemy opened this issue Jan 6, 2023 · 2 comments
Open

JSDOMBuilder converts raw string contents to HTML tags #206

aSemy opened this issue Jan 6, 2023 · 2 comments

Comments

@aSemy
Copy link

aSemy commented Jan 6, 2023

I want to display a Map<String, String> in an HTML page.

import kotlinx.browser.document
import kotlinx.html.*
import kotlinx.html.dom.*

fun main() {
  document.body!!.append.div {
    pre {
      code {
        unsafe {
          raw("""
            val map: Map<String, String> = mapOf(
              "key1" to "value1",
              "key2" to "value2",
            )
          """.trimIndent())
        }
      }
    }
  }

The code is not display 'raw' though, and the generic parameters are converted into HTML tags <string, string=""> - very strange!

<div>
  <pre>
    <code>
      val map: Map<string, string=""> = mapOf(
        "key1" to "value1",
        "key2" to "value2",
      )
      </string,>
    </code>
  </pre>
</div>

The code rendered in my browser does not match the raw string.

image

Expected result

If I don't use JSDOMBBuilder, then the HTML matches the raw content:

import kotlinx.html.*
import kotlinx.html.dom.createHTMLDocument
import kotlinx.html.stream.createHTML

fun main() {
  println(createHTML(prettyPrint = true).div {
    pre {
      code {
        unsafe {
          raw("""
            val map: Map<String, String> = mapOf(
              "key1" to "value1",
              "key2" to "value2",
            )
          """.trimIndent())
        }
      }
    }
  })
}
<div>
  <pre><code>val map: Map<String, String> = mapOf(
  "key1" to "value1",
  "key2" to "value2",
)</code></pre>
</div>

Compose Web

With Compose Web v1.2.2 I am also able to output raw content

import org.jetbrains.compose.web.*
import org.jetbrains.compose.web.css.*
import org.jetbrains.compose.web.dom.*

fun main() {
  renderComposable(rootElementId = "root") {
    Div {
      Pre {
        Code {
          Text(
            """
              val map: Map<String, String> = mapOf(
                "key1" to "value1",
                "key2" to "value2",
              )
            """.trimIndent()
          )
        }
      }
    }
  }
}

However, Compose Web escapes the angled brackets.

<div><pre><code>
val map: Map&lt;String, String&gt; = mapOf(
  "key1" to "value1",
  "key2" to "value2",
)</code></pre></div>

The result matches the raw input:

image

Versions

  • Kotlin/JS 1.7.20
  • Kotlinx HTML 0.7.5
@severn-everett
Copy link
Contributor

Because your code includes angled brackets, it actually should be escaped. The un-escaped code of

<div>
  <pre><code>val map: Map<String, String> = mapOf(
  "key1" to "value1",
  "key2" to "value2",
)</code></pre>
</div>

will display like this in a browser:

val map: Map = mapOf(
              "key1" to "value1",
              "key2" to "value2",
            )

i.e. the type declaration of the map does not render.

Instead, you should just use the normal text appending functionality in the library if you want to inject Kotlin code into a <code> block, e.g.

fun main() {
  document.body!!.append.div {
    pre {
      code {
        +"""
            val map: Map<String, String> = mapOf(
              "key1" to "value1",
              "key2" to "value2",
            )
          """.trimIndent()
      }
    }
  }
}

@aSemy
Copy link
Author

aSemy commented May 8, 2024

Thanks for the suggestion @severn-everett. You are right, that technically the code should be escaped.

It's been a while since I looked at this. IIRC I was trying to use a JavaScript library for code syntax highlighting, which required the angled brackets were rendered as-is, because it needed to parse the code. It would then perform its own escaping.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants