htm icon indicating copy to clipboard operation
htm copied to clipboard

  isnt rendering in htm

Open openHawkes opened this issue 3 years ago • 5 comments

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/[email protected]/dist/preact.umd.js"></script>
        <script src="https://unpkg.com/[email protected]/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

openHawkes avatar Jan 03 '23 20:01 openHawkes

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?

tim-lynn-clark avatar Jan 16 '23 21:01 tim-lynn-clark

@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!].

openHawkes avatar Jan 17 '23 19:01 openHawkes

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...)

rozek avatar Feb 16 '23 08:02 rozek

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

  • a huge map of entities, which would be many times larger than HTM itself and would destroy performance (there's one in Babel, and probably 50 in your node_modules right now); or
  • runtime entity decoding via innerHTML, which is extremely slow and only works in the browser.

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 🧝‍♂️.

developit avatar Feb 17 '23 03:02 developit

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...

rozek avatar Feb 17 '23 05:02 rozek