Lit-html: The position of the slash of self-closing tag will change render result

Created on 8 May 2019  路  5Comments  路  Source: Polymer/lit-html

Description

See code below. Is this a feature or a bug?

Steps to Reproduce

import { html, render } from 'lit-html'

const goodSlash = () => html`
  <img src=${ 'https://example.com' } />
`

const badSlash = () => html`
  <img src=${ 'https://example.com' }/>
`

render(goodSlash(), document.body); // <img src="https://example.com" />
render(badSlash(), document.body); // <img src="https://example.com/">

Browsers Affected

  • [x] Chrome
  • [x] Firefox
  • [ ] Edge
  • [ ] Safari 11
  • [ ] Safari 10
  • [ ] IE 11
Medium Bug

Most helpful comment

Actually, this is the way the HTML parser would work:

document.body.innerHTML = `
  <img src=${ 'https://example.com' } />
  <img src=${ 'https://example.com' }/>
`;

[...document.body.children].map(i => i.getAttribute('src'))]
// => ['https://example.com', 'https://example.com/']

I think the difference here is what do we "visually parse" as the src due to the ${} syntax. A very easy fix for this would be to insert surrounding quotes to unquoted attributes, which would cause the trailing / to be parsed as a auto-close slash.

All 5 comments

Looks like a bug.

What version did you encounter this with, and have you tested if this still happens with the current master branch? I think there have been some improvements to the parser since the last release, so it may have been fixed already.

Actually, this is the way the HTML parser would work:

document.body.innerHTML = `
  <img src=${ 'https://example.com' } />
  <img src=${ 'https://example.com' }/>
`;

[...document.body.children].map(i => i.getAttribute('src'))]
// => ['https://example.com', 'https://example.com/']

I think the difference here is what do we "visually parse" as the src due to the ${} syntax. A very easy fix for this would be to insert surrounding quotes to unquoted attributes, which would cause the trailing / to be parsed as a auto-close slash.

@ruphin v1.0.0(npm) and master branch can reproduce this, the reason seems to be as Jridgewell said.

Ah yes, I did not see the missing surrounding quotes. I would say the current behaviour is arguably correct.

The most obvious way to avoid this problem is to omit the solidus (/), as it is not required for self-closing tags, and in fact has no special meaning in HTML.

Closing, as self-closing tags are not a feature of HTML5, and as @jridgewell notes the above behavior is in fact the correct parsing behavior (in HTML5, the / in the open tag is not treated specially by the parser, and since your src attribute is not quoted, the / is being consumed by the src attribute value, equivalent to if you had written src="${...}/").

There is currently a feature request to support self-closing tags at the lit parsing layer before the HTML5 parser sees it, so any further work would happen under that issue: https://github.com/Polymer/lit-html/issues/630

Was this page helpful?
0 / 5 - 0 ratings