fix: improve event handling compatibility with delegation (#10168)

* fix: improve event handling compatibility with delegation

* fix

* lint

* add test
pull/10171/head
Dominic Gannaway 1 year ago committed by GitHub
parent a26012fc62
commit 0eca0ace94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: improve event handling compatibility with delegation

@ -319,7 +319,15 @@ export function event(event_name, dom, handler, capture, passive) {
capture, capture,
passive passive
}; };
const target_handler = handler; /**
* @this {EventTarget}
*/
function target_handler(/** @type {Event} */ event) {
handle_event_propagation(dom, event);
if (!event.cancelBubble) {
return handler.call(this, event);
}
}
dom.addEventListener(event_name, target_handler, options); dom.addEventListener(event_name, target_handler, options);
// @ts-ignore // @ts-ignore
if (dom === document.body || dom === window || dom === document) { if (dom === document.body || dom === window || dom === document) {

@ -0,0 +1,20 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
import { log } from './log.js';
export default test({
before_test() {
log.length = 0;
},
async test({ assert, target }) {
const [b1] = target.querySelectorAll('button');
flushSync(() => {
b1?.click();
});
await Promise.resolve();
assert.deepEqual(log, ['clicked button']);
}
});

@ -0,0 +1,8 @@
<script>
import { log } from './log.js';
</script>
<div on:click={(e) => { log.push('clicked div') }}>
<button onclick={(e) => { log.push('clicked button'); e.stopPropagation() }}>
Button
</button>
</div>

@ -0,0 +1,20 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
import { log } from './log.js';
export default test({
before_test() {
log.length = 0;
},
async test({ assert, target }) {
const [b1] = target.querySelectorAll('button');
flushSync(() => {
b1?.click();
});
await Promise.resolve();
assert.deepEqual(log, ['clicked button']);
}
});

@ -0,0 +1,13 @@
<script>
import { log } from './log.js';
const action = () => {}
</script>
<div use:action onclick={() => log.push('clicked container')} onkeydown={() => {}}>
<div use:action onclick={(e) => { log.push('clicked div 1') }}>
<div onclick={(e) => { log.push('clicked div 2') }}>
<button onclick={(e) => { log.push('clicked button'); e.stopPropagation() }}>
Button
</button>
</div>
</div>
</div>

@ -0,0 +1,25 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
import { log } from './log.js';
export default test({
before_test() {
log.length = 0;
},
async test({ assert, target }) {
const [b1] = target.querySelectorAll('button');
flushSync(() => {
b1?.click();
});
await Promise.resolve();
assert.deepEqual(log, [
'clicked button',
'clicked div 2',
'clicked div 1',
'clicked container'
]);
}
});

@ -0,0 +1,13 @@
<script>
import { log } from './log.js';
const action = () => {}
</script>
<div use:action onclick={() => log.push('clicked container')} onkeydown={() => {}}>
<div use:action onclick={(e) => { log.push('clicked div 1') }}>
<div onclick={(e) => { log.push('clicked div 2') }}>
<button onclick={(e) => { log.push('clicked button') }}>
Button
</button>
</div>
</div>
</div>
Loading…
Cancel
Save