diff --git a/.changeset/rich-worms-burn.md b/.changeset/rich-worms-burn.md new file mode 100644 index 000000000000..8ec3af516abe --- /dev/null +++ b/.changeset/rich-worms-burn.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: attach spread attribute events synchronously diff --git a/packages/svelte/src/internal/client/dom/elements/attributes.js b/packages/svelte/src/internal/client/dom/elements/attributes.js index 545cab20f84c..d927af543ff2 100644 --- a/packages/svelte/src/internal/client/dom/elements/attributes.js +++ b/packages/svelte/src/internal/client/dom/elements/attributes.js @@ -5,7 +5,7 @@ import { create_event, delegate } from './events.js'; import { add_form_reset_listener, autofocus } from './misc.js'; import * as w from '../../warnings.js'; import { LOADING_ATTR_SYMBOL } from '../../constants.js'; -import { queue_idle_task, queue_micro_task } from '../task.js'; +import { queue_idle_task } from '../task.js'; import { is_capture_event, is_delegated, normalize_attribute } from '../../../../utils.js'; import { active_effect, @@ -209,8 +209,6 @@ export function set_attributes( // @ts-expect-error var attributes = /** @type {Record} **/ (element.__attributes ??= {}); - /** @type {Array<[string, any, () => void]>} */ - var events = []; // since key is captured we use const for (const key in next) { @@ -277,15 +275,7 @@ export function set_attributes( current[key].call(this, evt); } - if (!prev) { - events.push([ - key, - value, - () => (current[event_handle_key] = create_event(event_name, element, handle, opts)) - ]); - } else { - current[event_handle_key] = create_event(event_name, element, handle, opts); - } + current[event_handle_key] = create_event(event_name, element, handle, opts); } else { // @ts-ignore element[`__${event_name}`] = value; @@ -325,19 +315,6 @@ export function set_attributes( } } - // On the first run, ensure that events are added after bindings so - // that their listeners fire after the binding listeners - if (!prev) { - queue_micro_task(() => { - if (!element.isConnected) return; - for (const [key, value, evt] of events) { - if (current[key] === value) { - evt(); - } - } - }); - } - return current; } diff --git a/packages/svelte/tests/runtime-runes/samples/event-spread-timing/_config.js b/packages/svelte/tests/runtime-runes/samples/event-spread-timing/_config.js new file mode 100644 index 000000000000..bde384b51b8e --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/event-spread-timing/_config.js @@ -0,0 +1,7 @@ +import { test } from '../../test'; + +export default test({ + test({ assert, logs }) { + assert.deepEqual(logs, ['onfocus']); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/event-spread-timing/main.svelte b/packages/svelte/tests/runtime-runes/samples/event-spread-timing/main.svelte new file mode 100644 index 000000000000..bb04abce8379 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/event-spread-timing/main.svelte @@ -0,0 +1,7 @@ + + + console.log("onfocus")} use:focus />