fix: repair invalid raw html content during hydration (#8912)

When the HTML that is coming from raw html is invalid, the browser reshuffles things. Bail in that case to try to repair more often. Should help with https://github.com/withastro/astro/issues/7557
pull/8911/head
Simon H 2 years ago committed by GitHub
parent 35221c8811
commit 136aebd8eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: repair invalid raw html content during hydration

@ -16,6 +16,7 @@ sites/svelte.dev/.vercel
/test/**/expected* /test/**/expected*
/test/**/_output /test/**/_output
/test/**/shards/*.test.js /test/**/shards/*.test.js
/test/hydration/samples/raw-repair/_after.html
/types /types
!rollup.config.js !rollup.config.js
!vitest.config.js !vitest.config.js

@ -777,14 +777,14 @@ export function claim_comment(nodes, data) {
); );
} }
function find_comment(nodes, text, start) { function get_comment_idx(nodes, text, start) {
for (let i = start; i < nodes.length; i += 1) { for (let i = start; i < nodes.length; i += 1) {
const node = nodes[i]; const node = nodes[i];
if (node.nodeType === 8 /* comment node */ && node.textContent.trim() === text) { if (node.nodeType === 8 /* comment node */ && node.textContent.trim() === text) {
return i; return i;
} }
} }
return nodes.length; return -1;
} }
/** /**
@ -793,11 +793,12 @@ function find_comment(nodes, text, start) {
*/ */
export function claim_html_tag(nodes, is_svg) { export function claim_html_tag(nodes, is_svg) {
// find html opening tag // find html opening tag
const start_index = find_comment(nodes, 'HTML_TAG_START', 0); const start_index = get_comment_idx(nodes, 'HTML_TAG_START', 0);
const end_index = find_comment(nodes, 'HTML_TAG_END', start_index); const end_index = get_comment_idx(nodes, 'HTML_TAG_END', start_index + 1);
if (start_index === end_index) { if (start_index === -1 || end_index === -1) {
return new HtmlTagHydration(is_svg); return new HtmlTagHydration(is_svg);
} }
init_claim_info(nodes); init_claim_info(nodes);
const html_tag_nodes = nodes.splice(start_index, end_index - start_index + 1); const html_tag_nodes = nodes.splice(start_index, end_index - start_index + 1);
detach(html_tag_nodes[0]); detach(html_tag_nodes[0]);
@ -1048,17 +1049,13 @@ export class HtmlTag {
* @default false * @default false
*/ */
is_svg = false; is_svg = false;
// parent for creating node /** parent for creating node */
/** */
e = undefined; e = undefined;
// html tag nodes /** html tag nodes */
/** */
n = undefined; n = undefined;
// target /** target */
/** */
t = undefined; t = undefined;
// anchor /** anchor */
/** */
a = undefined; a = undefined;
constructor(is_svg = false) { constructor(is_svg = false) {
this.is_svg = is_svg; this.is_svg = is_svg;

@ -0,0 +1,2 @@
<p><p>invalid</p></p>
<p><p>invalid</p></p>

@ -0,0 +1,8 @@
<p><!-- HTML_TAG_START --></p>
<p>invalid</p>
<!-- HTML_TAG_END -->
<p></p>
<p><!-- HTML_TAG_START --></p>
<p>invalid</p>
<!-- HTML_TAG_END -->
<p></p>

@ -0,0 +1,5 @@
<script>
export let content;
</script>
<p>{@html content}</p>

@ -0,0 +1,7 @@
<script>
import Inner from './inner.svelte';
</script>
<Inner content="<p>invalid</p>" />
<p>{@html '<p>invalid</p>'}</p>
Loading…
Cancel
Save