mirror of https://github.com/sveltejs/svelte
fix: tighten up event attributes and hoisting logic (#9433)
- add event delegation to spread_attributes - add event attributes to spread - don't delegate when bindings/actions on the same element in order to preserve backwards compatibility of ordering - don't hoist identifiers when one of them is used in an event that is not delegateable --------- Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>baseballyama-docs/string-event
parent
3f56baf760
commit
73ae5ef5bc
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: handle event attribute spreading with event delegation
|
@ -0,0 +1,18 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
// Checks that event handlers are not hoisted when one of them is not delegateable
|
||||||
|
export default test({
|
||||||
|
html: `<button>0</button>`,
|
||||||
|
|
||||||
|
async test({ assert, target }) {
|
||||||
|
const [button] = target.querySelectorAll('button');
|
||||||
|
|
||||||
|
button.click();
|
||||||
|
await Promise.resolve();
|
||||||
|
assert.htmlEqual(target.innerHTML, '<button>1</button>');
|
||||||
|
|
||||||
|
button.dispatchEvent(new MouseEvent('mouseenter'));
|
||||||
|
await Promise.resolve();
|
||||||
|
assert.htmlEqual(target.innerHTML, '<button>2</button>');
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,11 @@
|
|||||||
|
<script>
|
||||||
|
let count = $state(0)
|
||||||
|
|
||||||
|
function increment() {
|
||||||
|
count += 1
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={increment} onmouseenter={increment}>
|
||||||
|
{count}
|
||||||
|
</button>
|
@ -0,0 +1,67 @@
|
|||||||
|
import { flushSync } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
html: `
|
||||||
|
<button>click me</button>
|
||||||
|
<button>click me</button>
|
||||||
|
<button>click me</button>
|
||||||
|
<button>click me</button>
|
||||||
|
`,
|
||||||
|
|
||||||
|
async test({ assert, target }) {
|
||||||
|
const [b1, b2, b3, b4] = target.querySelectorAll('button');
|
||||||
|
|
||||||
|
flushSync(() => {
|
||||||
|
b1?.click();
|
||||||
|
});
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<button>click spread</button>
|
||||||
|
<button>click spread</button>
|
||||||
|
<button>click spread</button>
|
||||||
|
<button>click spread</button>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
flushSync(() => {
|
||||||
|
b2?.click();
|
||||||
|
});
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<button>click onclick</button>
|
||||||
|
<button>click onclick</button>
|
||||||
|
<button>click onclick</button>
|
||||||
|
<button>click onclick</button>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
flushSync(() => {
|
||||||
|
b3?.click();
|
||||||
|
});
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<button>click spread</button>
|
||||||
|
<button>click spread</button>
|
||||||
|
<button>click spread!</button>
|
||||||
|
<button>click spread!</button>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
flushSync(() => {
|
||||||
|
b4?.click();
|
||||||
|
});
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<button>click onclick</button>
|
||||||
|
<button>click onclick</button>
|
||||||
|
<button>click onclick?</button>
|
||||||
|
<button>click onclick?</button>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,21 @@
|
|||||||
|
<script>
|
||||||
|
let text = $state('click me');
|
||||||
|
let text2 = $state('');
|
||||||
|
let spread = { onclick: () => text = 'click spread' };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={() => text = 'click onclick'} {...spread}>
|
||||||
|
{text}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button {...spread} onclick={() => text = 'click onclick'}>
|
||||||
|
{text}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button onclick={() => text = 'click onclick'} {...spread} on:click={() => text2 = '!'}>
|
||||||
|
{text}{text2}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button on:click={() => text2 = '?'} {...spread} onclick={() => text = 'click onclick'}>
|
||||||
|
{text}{text2}
|
||||||
|
</button>
|
Loading…
Reference in new issue