The Wayback Machine - http://web.archive.org/web/20201121133323/https://github.com/developit/htm/issues/171
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

Support HTML5 void elements #171

Closed
Siilwyn opened this issue Jun 9, 2020 · 10 comments
Closed

Support HTML5 void elements #171

Siilwyn opened this issue Jun 9, 2020 · 10 comments

Comments

@Siilwyn
Copy link

@Siilwyn Siilwyn commented Jun 9, 2020

It would be great to be able to write standard HTML5 without needing to close tags like in JSX, which is just another small thing to learn for developers.

E.g: an image tag normally works but doesn't in HTM: <img src="hi.png>.

@dy
Copy link

@dy dy commented Jun 9, 2020

htm@1.x supported that.

I've experimented with implementation of void elements, as well as optional closing elements here, and noticed that that reduces original HTM performance by ~20% (it needs to check each tag if that's in void list) and increases bundle size ~108 bytes.

Also see #91.

@Siilwyn
Copy link
Author

@Siilwyn Siilwyn commented Jun 10, 2020

@dy ah interesting, optional closing elements are not something I'm after, is that 20% performance difference only caused by supporting void elements?

Maybe it can be given as an option to support since 108 bytes more is not that much, the performance doesn't matter to me since I plan to use 'babel-plugin-htm'.

@dy
Copy link

@dy dy commented Jun 10, 2020

is that 20% performance difference only caused by supporting void elements

Yes - each opening tag in markup should be checked against list of possible self-closing matches: area base br col command embed hr img input keygen link meta param source track wbr. That is 16x redundant ops for each tag, unless some smart filtering involved.

@cztomsik
Copy link

@cztomsik cztomsik commented Sep 1, 2020

you can use this (preprocessing) hack:

html = html.replace(/<(area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)([^<>]*?)[^\/]>/gi, '<$1$2/>')
@dy
Copy link

@dy dy commented Sep 2, 2020

@cztomsik but how would you use it with templates html`<img src=${src}>`?

@cztomsik
Copy link

@cztomsik cztomsik commented Sep 2, 2020

I didn't need that (I'm using htm as temporary html parser so I'm just calling htm.bind(x)([html])) but you can:

import htm from 'https://unpkg.com/htm?module'

const boundHtm = htm.bind((tag, atts, ...kids) => ({ tag, atts, kids }))
const voidBoundHtm = (strings, ...values) => boundHtm(strings.map(addSlash), ...values)
const addSlash = html => html.replace(/<(area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)([^<>]*?)\/?>/gi, '<$1$2/>')

const hello = 'Hello'
console.log(voidBoundHtm`<br><hr><span>${hello}</span>`)

It's ugly but it seems to work (and the regex had one bug)

@developit
Copy link
Owner

@developit developit commented Sep 21, 2020

FWIW one of the reasons I don't think we're likely to consider this is because there are a lot of other HTML features that are unsupported in HTM. Adding a feature like void elements is net negative for performance, but it increases the likelihood of folks thinking HTM is an HTML parser. This assumption breaks down pretty quickly - attribute names are case-sensitive, whitespace is trimmed, etc.

HTM is also most often used with Virtual DOM libraries, which further diverge from HTML since they tend to adopt HTML's property semantics for "props" rather than the string-only semantics of HTML attributes. We've actually had cases in Preact where folks using HTM have run into issues using namespaced attributes. VDOM doesn't have those, and they're only "supported" in HTM because it's faster and smaller to pass-through namespaces than it would be to prevent their usage.

That all said, I do think it would be interesting for someone to resurrect the htm@1 codebase and repurpose it as a standalone HTML-to-VDOM library. It would be the fastest implementation, support 100% of HTML (since it uses DOMParser), and weigh in at around 300b. A library for that purpose wouldn't need the tagged templates stuff, it would just be a string => VNode transformer.

@Siilwyn
Copy link
Author

@Siilwyn Siilwyn commented Sep 21, 2020

Thank you for the reply @developit, much appreciated. I understand the decision. I might publish a htm@1 project when I find time. 🤞

Will close, ofc. discussion is still possible.

@Siilwyn Siilwyn closed this Sep 21, 2020
@cztomsik
Copy link

@cztomsik cztomsik commented Sep 22, 2020

of folks thinking HTM is an HTML parser.

Of course it's not, I'm using it only temporarily

BTW: @developit do you know about some small (well-formed is enough, speed is not an issue) HTML parsers?

@dy
Copy link

@dy dy commented Sep 22, 2020

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

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.