diff --git a/.changeset/spicy-plums-admire.md b/.changeset/spicy-plums-admire.md new file mode 100644 index 0000000000..9ba9e5313c --- /dev/null +++ b/.changeset/spicy-plums-admire.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: apply event attribute validation to elements only diff --git a/packages/svelte/src/compiler/phases/2-analyze/validation.js b/packages/svelte/src/compiler/phases/2-analyze/validation.js index 2323282893..3be08c75fb 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/validation.js +++ b/packages/svelte/src/compiler/phases/2-analyze/validation.js @@ -65,12 +65,24 @@ function validate_element(node, context) { error(attribute, 'invalid-attribute-name', attribute.name); } - if (attribute.name === 'is' && context.state.options.namespace !== 'foreign') { - warn(context.state.analysis.warnings, attribute, context.path, 'avoid-is'); - } else if (attribute.name === 'slot') { + if (attribute.name.startsWith('on') && attribute.name.length > 2) { + if ( + attribute.value === true || + is_text_attribute(attribute) || + attribute.value.length > 1 + ) { + error(attribute, 'invalid-event-attribute-value'); + } + } + + if (attribute.name === 'slot') { /** @type {import('#compiler').RegularElement | import('#compiler').SvelteElement | import('#compiler').Component | import('#compiler').SvelteComponent | import('#compiler').SvelteSelf | undefined} */ validate_slot_attribute(context, attribute); } + + if (attribute.name === 'is' && context.state.options.namespace !== 'foreign') { + warn(context.state.analysis.warnings, attribute, context.path, 'avoid-is'); + } } else if (attribute.type === 'AnimateDirective') { const parent = context.path.at(-2); if (parent?.type !== 'EachBlock') { @@ -316,13 +328,6 @@ function is_tag_valid_with_parent(tag, parent_tag) { * @type {import('zimmerframe').Visitors} */ export const validation = { - Attribute(node) { - if (node.name.startsWith('on') && node.name.length > 2) { - if (node.value === true || is_text_attribute(node) || node.value.length > 1) { - error(node, 'invalid-event-attribute-value'); - } - } - }, BindDirective(node, context) { validate_no_const_assignment(node, node.expression, context.state.scope, true); diff --git a/packages/svelte/tests/validator/samples/event-attribute/errors.json b/packages/svelte/tests/validator/samples/event-attribute/errors.json new file mode 100644 index 0000000000..28a8f9f11a --- /dev/null +++ b/packages/svelte/tests/validator/samples/event-attribute/errors.json @@ -0,0 +1,14 @@ +[ + { + "message": "Event attribute must be a JavaScript expression, not a string", + "code": "invalid-event-attribute-value", + "start": { + "line": 4, + "column": 8 + }, + "end": { + "line": 4, + "column": 21 + } + } +] diff --git a/packages/svelte/tests/validator/samples/event-attribute/input.svelte b/packages/svelte/tests/validator/samples/event-attribute/input.svelte new file mode 100644 index 0000000000..2ab0e39823 --- /dev/null +++ b/packages/svelte/tests/validator/samples/event-attribute/input.svelte @@ -0,0 +1,4 @@ + + + +