fix: event listeners in spread

pull/18058/head
paoloricciuti 5 months ago
parent 020dc9e1bb
commit 37bf4452f5

@ -395,7 +395,7 @@ function set_attributes(
const opts = {}; const opts = {};
const event_handle_key = '$$' + key; const event_handle_key = '$$' + key;
let event_name = key.slice(2); let event_name = key.slice(2);
var is_delegated = can_delegate_event(event_name); var is_delegated = renderer == null && can_delegate_event(event_name);
if (is_capture_event(event_name)) { if (is_capture_event(event_name)) {
event_name = event_name.slice(0, -7); event_name = event_name.slice(0, -7);
@ -419,10 +419,10 @@ function set_attributes(
} else if (value != null) { } else if (value != null) {
/** /**
* @this {any} * @this {any}
* @param {Event} evt * @param {...any} args
*/ */
function handle(evt) { function handle(...args) {
current[key].call(this, evt); current[key].apply(this, args);
} }
current[event_handle_key] = create_event(event_name, element, handle, opts); current[event_handle_key] = create_event(event_name, element, handle, opts);

@ -0,0 +1,29 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
html: '<button>click me</button> <p>0</p>',
test({ assert, target, serialize, logs }) {
const button = target.children.find(
(/** @type {any} */ n) => n.type === 'element' && n.name === 'button'
);
assert.ok(button);
const listeners = button.listeners?.click;
assert.ok(listeners, 'button should have click listeners');
// Call the handler with multiple arguments.
// Custom renderers may pass multiple arguments to event handlers,
// so we need to make sure all arguments are forwarded through spreads too.
for (const { handler } of listeners) {
handler.call(button, { type: 'click' }, 'extra', 42);
}
flushSync();
const html = serialize(target);
assert.equal(html, '<button>click me</button> <p>1</p>');
// Verify all arguments were forwarded to the actual handler
assert.deepEqual(logs, [{ type: 'click' }, 'extra', 42]);
}
});

@ -0,0 +1,13 @@
<script>
let count = $state(0);
const spread = {
onclick(...args) {
count++;
console.log(...args);
}
};
</script>
<button {...spread}>click me</button>
<p>{count}</p>
Loading…
Cancel
Save