From 500b2065e01cfaf0f8caaf8561cdf8bc177451b4 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Mon, 29 Apr 2024 18:16:20 +0200 Subject: [PATCH] fix: apply modifiers to bubbled events (#11369) fixes #11365 --- .changeset/fast-penguins-matter.md | 5 +++ .../3-transform/client/visitors/template.js | 43 ++++++++++--------- .../event-handler-modifier-bubble/_config.js | 12 ++++++ .../button.svelte | 1 + .../event-handler-modifier-bubble/main.svelte | 11 +++++ 5 files changed, 52 insertions(+), 20 deletions(-) create mode 100644 .changeset/fast-penguins-matter.md create mode 100644 packages/svelte/tests/runtime-legacy/samples/event-handler-modifier-bubble/_config.js create mode 100644 packages/svelte/tests/runtime-legacy/samples/event-handler-modifier-bubble/button.svelte create mode 100644 packages/svelte/tests/runtime-legacy/samples/event-handler-modifier-bubble/main.svelte diff --git a/.changeset/fast-penguins-matter.md b/.changeset/fast-penguins-matter.md new file mode 100644 index 0000000000..523aaf8a12 --- /dev/null +++ b/.changeset/fast-penguins-matter.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: apply modifiers to bubbled events 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 89eb32f429..3a7e52ac0c 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 @@ -1170,8 +1170,11 @@ function serialize_render_stmt(state) { * @param {import('../types.js').ComponentContext} context */ function serialize_event_handler(node, { state, visit }) { + /** @type {import('estree').Expression} */ + let handler; + if (node.expression) { - let handler = node.expression; + handler = node.expression; // Event handlers can be dynamic (source/store/prop/conditional etc) const dynamic_handler = () => @@ -1209,34 +1212,34 @@ function serialize_event_handler(node, { state, visit }) { } else { handler = /** @type {import('estree').Expression} */ (visit(handler)); } - - if (node.modifiers.includes('stopPropagation')) { - handler = b.call('$.stopPropagation', handler); - } - if (node.modifiers.includes('stopImmediatePropagation')) { - handler = b.call('$.stopImmediatePropagation', handler); - } - if (node.modifiers.includes('preventDefault')) { - handler = b.call('$.preventDefault', handler); - } - if (node.modifiers.includes('self')) { - handler = b.call('$.self', handler); - } - if (node.modifiers.includes('trusted')) { - handler = b.call('$.trusted', handler); - } - - return handler; } else { state.analysis.needs_props = true; // Function + .call to preserve "this" context as much as possible - return b.function( + handler = b.function( null, [b.id('$$arg')], b.block([b.stmt(b.call('$.bubble_event.call', b.this, b.id('$$props'), b.id('$$arg')))]) ); } + + if (node.modifiers.includes('stopPropagation')) { + handler = b.call('$.stopPropagation', handler); + } + if (node.modifiers.includes('stopImmediatePropagation')) { + handler = b.call('$.stopImmediatePropagation', handler); + } + if (node.modifiers.includes('preventDefault')) { + handler = b.call('$.preventDefault', handler); + } + if (node.modifiers.includes('self')) { + handler = b.call('$.self', handler); + } + if (node.modifiers.includes('trusted')) { + handler = b.call('$.trusted', handler); + } + + return handler; } /** diff --git a/packages/svelte/tests/runtime-legacy/samples/event-handler-modifier-bubble/_config.js b/packages/svelte/tests/runtime-legacy/samples/event-handler-modifier-bubble/_config.js new file mode 100644 index 0000000000..c30af43043 --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/event-handler-modifier-bubble/_config.js @@ -0,0 +1,12 @@ +import { ok, test } from '../../test'; + +export default test({ + async test({ assert, component, target }) { + const button = target.querySelector('button'); + ok(button); + + await button.click(); + + assert.ok(component.default_was_prevented); + } +}); diff --git a/packages/svelte/tests/runtime-legacy/samples/event-handler-modifier-bubble/button.svelte b/packages/svelte/tests/runtime-legacy/samples/event-handler-modifier-bubble/button.svelte new file mode 100644 index 0000000000..d94a505c0c --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/event-handler-modifier-bubble/button.svelte @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/svelte/tests/runtime-legacy/samples/event-handler-modifier-bubble/main.svelte b/packages/svelte/tests/runtime-legacy/samples/event-handler-modifier-bubble/main.svelte new file mode 100644 index 0000000000..d5134e28fa --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/event-handler-modifier-bubble/main.svelte @@ -0,0 +1,11 @@ + + +