From a1b6cc68d973a31256db946bc2c0b63ae55f0700 Mon Sep 17 00:00:00 2001
From: Simon H <5968653+dummdidumm@users.noreply.github.com>
Date: Mon, 17 Jun 2024 15:37:17 +0200
Subject: [PATCH] fix: handle `is` attribute on elements with spread (#12056)
The `is` attribute is special and always needs to be part of the static template string, or else it wouldn't be taken into account on initialization
fixes #12052
---
.changeset/large-waves-join.md | 5 +++++
.../3-transform/client/visitors/template.js | 9 +++++++++
.../samples/element-is-attribute/_config.js | 17 +++++++++++++++++
.../samples/element-is-attribute/main.svelte | 18 ++++++++++++++++++
4 files changed, 49 insertions(+)
create mode 100644 .changeset/large-waves-join.md
create mode 100644 packages/svelte/tests/runtime-runes/samples/element-is-attribute/_config.js
create mode 100644 packages/svelte/tests/runtime-runes/samples/element-is-attribute/main.svelte
diff --git a/.changeset/large-waves-join.md b/.changeset/large-waves-join.md
new file mode 100644
index 0000000000..d032f6e86c
--- /dev/null
+++ b/.changeset/large-waves-join.md
@@ -0,0 +1,5 @@
+---
+"svelte": patch
+---
+
+fix: handle `is` attribute on elements with spread
diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js
index 7a8f9660f4..b72b61cf7d 100644
--- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js
+++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js
@@ -278,6 +278,15 @@ function serialize_element_spread_attributes(
// TODO: handle contains_call_expression
const [, value] = serialize_attribute_value(attribute.value, context);
+ if (
+ name === 'is' &&
+ value.type === 'Literal' &&
+ context.state.metadata.namespace === 'html'
+ ) {
+ context.state.template.push(` is="${escape_html(value.value, true)}"`);
+ continue;
+ }
+
if (
is_event_attribute(attribute) &&
(attribute.value[0].expression.type === 'ArrowFunctionExpression' ||
diff --git a/packages/svelte/tests/runtime-runes/samples/element-is-attribute/_config.js b/packages/svelte/tests/runtime-runes/samples/element-is-attribute/_config.js
new file mode 100644
index 0000000000..6b9fd130e4
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/element-is-attribute/_config.js
@@ -0,0 +1,17 @@
+import { flushSync } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ mode: ['client'],
+ test({ assert, target, logs }) {
+ const [b1, b2] = target.querySelectorAll('button');
+
+ b1.click();
+ flushSync();
+ assert.deepEqual(logs, ['works']);
+
+ b2.click();
+ flushSync();
+ assert.deepEqual(logs, ['works', 'works']);
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/element-is-attribute/main.svelte b/packages/svelte/tests/runtime-runes/samples/element-is-attribute/main.svelte
new file mode 100644
index 0000000000..76aca5fa32
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/element-is-attribute/main.svelte
@@ -0,0 +1,18 @@
+
+
+
+
+
+