From 68b5faae71a7b062682579555ab200063b7951fd Mon Sep 17 00:00:00 2001
From: Simon Holthausen
Date: Tue, 4 Jul 2023 22:29:32 +0200
Subject: [PATCH] fix: repair invalid raw html content during hydration
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
---
.changeset/spicy-ladybugs-return.md | 5 ++++
packages/svelte/src/runtime/internal/dom.js | 23 ++++++++-----------
.../hydration/samples/raw-repair/_after.html | 2 ++
.../hydration/samples/raw-repair/_before.html | 8 +++++++
.../hydration/samples/raw-repair/inner.svelte | 5 ++++
.../hydration/samples/raw-repair/main.svelte | 7 ++++++
6 files changed, 37 insertions(+), 13 deletions(-)
create mode 100644 .changeset/spicy-ladybugs-return.md
create mode 100644 packages/svelte/test/hydration/samples/raw-repair/_after.html
create mode 100644 packages/svelte/test/hydration/samples/raw-repair/_before.html
create mode 100644 packages/svelte/test/hydration/samples/raw-repair/inner.svelte
create mode 100644 packages/svelte/test/hydration/samples/raw-repair/main.svelte
diff --git a/.changeset/spicy-ladybugs-return.md b/.changeset/spicy-ladybugs-return.md
new file mode 100644
index 0000000000..1b1655e903
--- /dev/null
+++ b/.changeset/spicy-ladybugs-return.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: repair invalid raw html content during hydration
diff --git a/packages/svelte/src/runtime/internal/dom.js b/packages/svelte/src/runtime/internal/dom.js
index 57d3b2793e..72cb8ab75b 100644
--- a/packages/svelte/src/runtime/internal/dom.js
+++ b/packages/svelte/src/runtime/internal/dom.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) {
const node = nodes[i];
if (node.nodeType === 8 /* comment node */ && node.textContent.trim() === text) {
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) {
// 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]);
@@ -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;
diff --git a/packages/svelte/test/hydration/samples/raw-repair/_after.html b/packages/svelte/test/hydration/samples/raw-repair/_after.html
new file mode 100644
index 0000000000..31cdc12015
--- /dev/null
+++ b/packages/svelte/test/hydration/samples/raw-repair/_after.html
@@ -0,0 +1,2 @@
+invalid
+invalid
\ No newline at end of file
diff --git a/packages/svelte/test/hydration/samples/raw-repair/_before.html b/packages/svelte/test/hydration/samples/raw-repair/_before.html
new file mode 100644
index 0000000000..fe958bece5
--- /dev/null
+++ b/packages/svelte/test/hydration/samples/raw-repair/_before.html
@@ -0,0 +1,8 @@
+
+invalid
+
+
+
+invalid
+
+
diff --git a/packages/svelte/test/hydration/samples/raw-repair/inner.svelte b/packages/svelte/test/hydration/samples/raw-repair/inner.svelte
new file mode 100644
index 0000000000..a2df6c9ded
--- /dev/null
+++ b/packages/svelte/test/hydration/samples/raw-repair/inner.svelte
@@ -0,0 +1,5 @@
+
+
+{@html content}
diff --git a/packages/svelte/test/hydration/samples/raw-repair/main.svelte b/packages/svelte/test/hydration/samples/raw-repair/main.svelte
new file mode 100644
index 0000000000..41deb9d3e6
--- /dev/null
+++ b/packages/svelte/test/hydration/samples/raw-repair/main.svelte
@@ -0,0 +1,7 @@
+
+
+
+
+{@html '
invalid
'}