From d17f5c748d4b842e63d0017461ccde49b00b78e0 Mon Sep 17 00:00:00 2001 From: Edoardo Cavazza Date: Wed, 22 Jan 2025 21:51:26 +0100 Subject: [PATCH] fix: add check for is attribute (#15086) Fixes #15085 Add a check for is attribute in is_custom_element_node function. --- .changeset/two-doors-exercise.md | 5 +++++ .../client/visitors/RegularElement.js | 2 +- .../client/visitors/shared/fragment.js | 3 ++- packages/svelte/src/compiler/phases/nodes.js | 8 ++++++-- .../custom-element-attributes/_config.js | 19 +++++++++++++++++++ .../custom-element-attributes/main.svelte | 2 ++ 6 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 .changeset/two-doors-exercise.md create mode 100644 packages/svelte/tests/runtime-runes/samples/custom-element-attributes/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/custom-element-attributes/main.svelte diff --git a/.changeset/two-doors-exercise.md b/.changeset/two-doors-exercise.md new file mode 100644 index 000000000000..b41e582ae79a --- /dev/null +++ b/.changeset/two-doors-exercise.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: add check for `is` attribute to correctly detect custom elements diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js index d0a148f216aa..c7e218d52143 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js @@ -227,7 +227,7 @@ export function RegularElement(node, context) { node_id, attributes_id, (node.metadata.svg || node.metadata.mathml || is_custom_element_node(node)) && b.true, - node.name.includes('-') && b.true, + is_custom_element_node(node) && b.true, context.state ); diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js index 0b4ac873428e..5bc3041ca453 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js @@ -4,6 +4,7 @@ import { cannot_be_set_statically } from '../../../../../../utils.js'; import { is_event_attribute, is_text_attribute } from '../../../../../utils/ast.js'; import * as b from '../../../../../utils/builders.js'; +import { is_custom_element_node } from '../../../../nodes.js'; import { build_template_chunk } from './utils.js'; /** @@ -128,7 +129,7 @@ export function process_children(nodes, initial, is_element, { visit, state }) { function is_static_element(node, state) { if (node.type !== 'RegularElement') return false; if (node.fragment.metadata.dynamic) return false; - if (node.name.includes('-')) return false; // we're setting all attributes on custom elements through properties + if (is_custom_element_node(node)) return false; // we're setting all attributes on custom elements through properties for (const attribute of node.attributes) { if (attribute.type !== 'Attribute') { diff --git a/packages/svelte/src/compiler/phases/nodes.js b/packages/svelte/src/compiler/phases/nodes.js index 5ca4ce3380a3..003c3a2c4945 100644 --- a/packages/svelte/src/compiler/phases/nodes.js +++ b/packages/svelte/src/compiler/phases/nodes.js @@ -23,10 +23,14 @@ export function is_element_node(node) { /** * @param {AST.RegularElement | AST.SvelteElement} node - * @returns {node is AST.RegularElement} + * @returns {boolean} */ export function is_custom_element_node(node) { - return node.type === 'RegularElement' && node.name.includes('-'); + return ( + node.type === 'RegularElement' && + (node.name.includes('-') || + node.attributes.some((attr) => attr.type === 'Attribute' && attr.name === 'is')) + ); } /** diff --git a/packages/svelte/tests/runtime-runes/samples/custom-element-attributes/_config.js b/packages/svelte/tests/runtime-runes/samples/custom-element-attributes/_config.js new file mode 100644 index 000000000000..118a51157eb9 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/custom-element-attributes/_config.js @@ -0,0 +1,19 @@ +import { test } from '../../test'; + +export default test({ + mode: ['client', 'server'], + async test({ assert, target }) { + const my_element = /** @type HTMLElement & { object: { test: true }; } */ ( + target.querySelector('my-element') + ); + const my_link = /** @type HTMLAnchorElement & { object: { test: true }; } */ ( + target.querySelector('a') + ); + assert.equal(my_element.getAttribute('string'), 'test'); + assert.equal(my_element.hasAttribute('object'), false); + assert.deepEqual(my_element.object, { test: true }); + assert.equal(my_link.getAttribute('string'), 'test'); + assert.equal(my_link.hasAttribute('object'), false); + assert.deepEqual(my_link.object, { test: true }); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/custom-element-attributes/main.svelte b/packages/svelte/tests/runtime-runes/samples/custom-element-attributes/main.svelte new file mode 100644 index 000000000000..ff94a9484c9a --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/custom-element-attributes/main.svelte @@ -0,0 +1,2 @@ + +