Skip to content

Commit

Permalink
fix: repair invalid raw html content during hydration (#8912)
Browse files Browse the repository at this point in the history
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 withastro/astro#7557
  • Loading branch information
dummdidumm committed Jul 4, 2023
1 parent 35221c8 commit 136aebd
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 13 deletions.
5 changes: 5 additions & 0 deletions .changeset/spicy-ladybugs-return.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: repair invalid raw html content during hydration
1 change: 1 addition & 0 deletions packages/svelte/.prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ sites/svelte.dev/.vercel
/test/**/expected*
/test/**/_output
/test/**/shards/*.test.js
/test/hydration/samples/raw-repair/_after.html
/types
!rollup.config.js
!vitest.config.js
23 changes: 10 additions & 13 deletions packages/svelte/src/runtime/internal/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
const node = nodes[i];
if (node.nodeType === 8 /* comment node */ && node.textContent.trim() === text) {
return i;
}
}
return nodes.length;
return -1;
}

/**
Expand All @@ -793,11 +793,12 @@ function find_comment(nodes, text, start) {
*/
export function claim_html_tag(nodes, is_svg) {
// find html opening tag
const start_index = find_comment(nodes, 'HTML_TAG_START', 0);
const end_index = find_comment(nodes, 'HTML_TAG_END', start_index);
if (start_index === end_index) {
const start_index = get_comment_idx(nodes, 'HTML_TAG_START', 0);
const end_index = get_comment_idx(nodes, 'HTML_TAG_END', start_index + 1);
if (start_index === -1 || end_index === -1) {
return new HtmlTagHydration(is_svg);
}

init_claim_info(nodes);
const html_tag_nodes = nodes.splice(start_index, end_index - start_index + 1);
detach(html_tag_nodes[0]);
Expand Down Expand Up @@ -1048,17 +1049,13 @@ export class HtmlTag {
* @default false
*/
is_svg = false;
// parent for creating node
/** */
/** parent for creating node */
e = undefined;
// html tag nodes
/** */
/** html tag nodes */
n = undefined;
// target
/** */
/** target */
t = undefined;
// anchor
/** */
/** anchor */
a = undefined;
constructor(is_svg = false) {
this.is_svg = is_svg;
Expand Down
2 changes: 2 additions & 0 deletions packages/svelte/test/hydration/samples/raw-repair/_after.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<p><p>invalid</p></p>
<p><p>invalid</p></p>
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script>
export let content;
</script>

<p>{@html content}</p>
7 changes: 7 additions & 0 deletions packages/svelte/test/hydration/samples/raw-repair/main.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script>
import Inner from './inner.svelte';
</script>

<Inner content="<p>invalid</p>" />

<p>{@html '<p>invalid</p>'}</p>

0 comments on commit 136aebd

Please sign in to comment.