developit / htm

Hyperscript Tagged Markup: JSX alternative using standard tagged templates, with compiler support.
Apache License 2.0
8.64k stars 169 forks source link

  isnt rendering in htm #234

Open openHawkes opened 1 year ago

openHawkes commented 1 year ago

When I have   in htm, it's outputting as literally   in the html.

I've seen some similar questions for JSX, but it seems that, even there, the space should render.

Is HTM's not rendering it as a non-breaking space intentional?

Here's a near-simplest case reproduction. Obviously the key is render(html`# #`, document.getElementById('root-element'));. It comes out without a space.

<html>
    <head>
        <title>Hello, Preact World!</title>
        <script src="https://unpkg.com/preact@10.11.3/dist/preact.umd.js"></script>
        <script src="https://unpkg.com/htm@3.1.1/preact/standalone.umd.js"></script>
        <script>
            window.render = window.preact.render;
            window.html = window.htmPreact.html;

            document.addEventListener('DOMContentLoaded', function () {
                render(html`#&nbsp;#`, document.getElementById('root-element'));
            });
        </script>
    </head>

    <body>
        <div id="root-element"></div>
    </body>
</html>

image

(Strangely, if I click "edit html" in Chrome (well, here, Brave), it shows that starts with &amp; so, for whatever reason, that & is a literal & in the render..)

image

tim-lynn-clark commented 1 year ago

Similar issue with all Unicode HTML codes like &#128512; (the smiley emoji). The htm library does not seem to handle HTML codes correctly.

I tried implementing the example below using the htm library instead of JSX, and it prints the code instead of the character.

https://codesandbox.io/s/8w7058yp9?from-embed=&file=/src/index.js

@openHawkes have you heard anything back or have you found a solution?

openHawkes commented 1 year ago

@tim-lynn-clark I have not been contacted or found a solution past sort of hackily inserting whitespace in a somewhat odd place in my template instead of using &nbsp;. Fortunately or unfortunately, that's allowed me to move on for the time being instead of cracking open the code of HTM [which for the most part I've really enjoyed using!].

rozek commented 1 year ago

Just a small note (in case that somebody likes it):

as long as HTML entities will not be rendered properly, I'll use alternatives such as ${'\xA0'} (for non-breaking spaces), ${'\x--'} for arbitrary ASCII codes or ${'\u----'} for arbitrary Unicode code points instead.

If you prefer s.th. more human-readable, you could define

  const nbsp = '\xA0'
  return html`${nbsp}`

This approach can also be used for decimal character codes (in case that you don't want to convert them into hexadecimal):

  const SmileyEmoji = String.fromCodePoint(128512)
  return html`${SmileyEmoji}`

(the character code was taken from a previous message in this issue, it does not show any emoji on my machine...)

developit commented 1 year ago

HTM doesn't decode HTML Entities because doing so requires one of two things:

Since neither of those two options are viable, we just don't support HTML Entities. They're only supported in JSX because doing so made sense in a very different context (in build tools in 2014).

@rozek 's solutions are what I'd recommend, or just use the character you want as a literal. If you want an emoji, paste the emoji into your editor and make sure your bundles are served with a utf-8 mime encoding - that's better than hand writing surrogate pairs 🧝‍♂️.

rozek commented 1 year ago

Thank you for clarifying this!

Wouldn't you like to add this constraint to the docs? This would prevent others to run into the same problem - and you could close this issue afterwards...