fix: ensure spread attribute events are attached synchronously (#14387)

* fix: ensure spread attribute events are attached synchronously

* fix: ensure spread attribute events are attached synchronously

* Update .changeset/rich-worms-burn.md

Co-authored-by: Rich Harris <rich.harris@vercel.com>

* simplify

---------

Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
broken-slot-pruning
Dominic Gannaway 1 month ago committed by GitHub
parent 6a5f30b290
commit dd9abea2a1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: attach spread attribute events synchronously

@ -5,7 +5,7 @@ import { create_event, delegate } from './events.js';
import { add_form_reset_listener, autofocus } from './misc.js'; import { add_form_reset_listener, autofocus } from './misc.js';
import * as w from '../../warnings.js'; import * as w from '../../warnings.js';
import { LOADING_ATTR_SYMBOL } from '../../constants.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 { is_capture_event, is_delegated, normalize_attribute } from '../../../../utils.js';
import { import {
active_effect, active_effect,
@ -209,8 +209,6 @@ export function set_attributes(
// @ts-expect-error // @ts-expect-error
var attributes = /** @type {Record<string, unknown>} **/ (element.__attributes ??= {}); var attributes = /** @type {Record<string, unknown>} **/ (element.__attributes ??= {});
/** @type {Array<[string, any, () => void]>} */
var events = [];
// since key is captured we use const // since key is captured we use const
for (const key in next) { for (const key in next) {
@ -277,15 +275,7 @@ export function set_attributes(
current[key].call(this, evt); current[key].call(this, evt);
} }
if (!prev) { current[event_handle_key] = create_event(event_name, element, handle, opts);
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);
}
} else { } else {
// @ts-ignore // @ts-ignore
element[`__${event_name}`] = value; 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; return current;
} }

@ -0,0 +1,7 @@
import { test } from '../../test';
export default test({
test({ assert, logs }) {
assert.deepEqual(logs, ['onfocus']);
}
});

@ -0,0 +1,7 @@
<script>
const focus = (input) => {
input.focus();
};
</script>
<input {...({})} onfocus={() => console.log("onfocus")} use:focus />
Loading…
Cancel
Save