Skip to content

Commit

Permalink
fix(hydrate): output track elements as void elms (#5720)
Browse files Browse the repository at this point in the history
* fix(hydrate): output track elements as void elms

add `track` to the list of "EMPTY" elements (void elements) that is
referenced when we serialize nodes.

prior to this fix, the output of running `renderToString` as such:
```js
const hydrate = require('./hydrate/index.js');

const src = `<video>
<source src="x" type="video/mp4">
<track
    kind="subtitles"
    src="x"
>
</video>`;

hydrate.renderToString(src, { prettyHtml: true })
    .then(result => console.log(result.html));
```

would result in the following being printed:

```html

<!doctype html>
<html class="hydrated" data-stencil-build="shc9pw4e">
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <video>
      <source src="x" type="video/mp4">
      <!-- NOTE: track has a closing tag -->
      <track kind="subtitles" src="x"></track>
    </video>
  </body>
</html>
```

With this fix applied, we print `track` as a void element:
```html
<!doctype html>
<html class="hydrated" data-stencil-build="z6oqy2b2">
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <video>
      <source src="x" type="video/mp4">
      <track kind="subtitles" src="x">
    </video>
  </body>
</html>
```

Fixes: #2994

STENCIL-94: Using hydrate.renderToString produces "invalid" HTML with <track>

* review(cb): unit tests
  • Loading branch information
rwaskiewicz authored Apr 30, 2024
1 parent 837a329 commit 2082351
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 2 deletions.
8 changes: 7 additions & 1 deletion src/mock-doc/serialize-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ function isWithinWhitespaceSensitive(node: Node) {
return false;
}

// TODO(STENCIL-1299): Audit this list, remove unsupported/deprecated elements
/*@__PURE__*/ export const NON_ESCAPABLE_CONTENT = new Set([
'STYLE',
'SCRIPT',
Expand All @@ -485,6 +486,7 @@ function isWithinWhitespaceSensitive(node: Node) {
'PLAINTEXT',
]);

// TODO(STENCIL-1299): Audit this list, remove unsupported/deprecated elements
/**
* A list of whitespace sensitive tag names, such as `code`, `pre`, etc.
*/
Expand All @@ -498,7 +500,8 @@ function isWithinWhitespaceSensitive(node: Node) {
'TEXTAREA',
]);

/*@__PURE__*/ const EMPTY_ELEMENTS = new Set([
// TODO(STENCIL-1299): Audit this list, remove unsupported/deprecated elements
/*@__PURE__*/ export const EMPTY_ELEMENTS = new Set([
'area',
'base',
'basefont',
Expand All @@ -516,11 +519,14 @@ function isWithinWhitespaceSensitive(node: Node) {
'param',
'source',
'trace',
'track',
'wbr',
]);

// TODO(STENCIL-1299): Audit this list, remove unsupported/deprecated attr
/*@__PURE__*/ const REMOVE_EMPTY_ATTR = new Set(['class', 'dir', 'id', 'lang', 'name', 'title']);

// TODO(STENCIL-1299): Audit this list, remove unsupported/deprecated attr
/*@__PURE__*/ const BOOLEAN_ATTR = new Set([
'allowfullscreen',
'async',
Expand Down
17 changes: 16 additions & 1 deletion src/mock-doc/test/serialize-node.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MockDocument } from '../document';
import { serializeNodeToHtml } from '../serialize-node';
import { EMPTY_ELEMENTS, serializeNodeToHtml } from '../serialize-node';

describe('serializeNodeToHtml', () => {
let doc: MockDocument;
Expand Down Expand Up @@ -278,4 +278,19 @@ describe('serializeNodeToHtml', () => {
scriptElm.innerHTML = input;
expect(scriptElm.innerHTML).toBe(input);
});

it.each([...EMPTY_ELEMENTS])("does not add a closing tag for '%s'", (voidElm) => {
if (voidElm === 'frame') {
// 'frame' is a non-HTML5 compatible/deprecated element.
// Stencil technically still supports it, but it doesn't get rendered as a child element, so let's just skip it
return;
}

const elm = doc.createElement('div');

elm.innerHTML = `<${voidElm}>`;

const html = serializeNodeToHtml(elm, { prettyHtml: true });
expect(html).toBe(`<${voidElm}>`);
});
});

0 comments on commit 2082351

Please sign in to comment.