fix: allow events to continue propagating following an error (#11263)

* fix: allow events to continue propagating following an error

* test

* appease eslint
pull/11260/head
Rich Harris 1 year ago committed by GitHub
parent 9721d5641b
commit 521d124267
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: allow events to continue propagating following an error

@ -122,36 +122,42 @@ export function handle_event_propagation(handler_element, event) {
} }
}); });
while (current_target !== null) { /** @param {Element} current_target */
function next(current_target) {
/** @type {null | Element} */ /** @type {null | Element} */
var parent_element = var parent_element =
current_target.parentNode || /** @type {any} */ (current_target).host || null; current_target.parentNode || /** @type {any} */ (current_target).host || null;
var internal_prop_name = '__' + event_name;
// @ts-ignore
var delegated = current_target[internal_prop_name];
if (delegated !== undefined && !(/** @type {any} */ (current_target).disabled)) {
if (is_array(delegated)) {
var [fn, ...data] = delegated;
fn.apply(current_target, [event, ...data]);
} else {
delegated.call(current_target, event);
}
}
if ( try {
event.cancelBubble || // @ts-expect-error
parent_element === handler_element || var delegated = current_target['__' + event_name];
current_target === handler_element
) { if (delegated !== undefined && !(/** @type {any} */ (current_target).disabled)) {
break; if (is_array(delegated)) {
var [fn, ...data] = delegated;
fn.apply(current_target, [event, ...data]);
} else {
delegated.call(current_target, event);
}
}
} finally {
if (
!event.cancelBubble &&
parent_element !== handler_element &&
parent_element !== null &&
current_target !== handler_element
) {
next(parent_element);
}
} }
current_target = parent_element;
} }
// @ts-expect-error is used above try {
event.__root = handler_element; next(current_target);
// @ts-expect-error is used above } finally {
current_target = handler_element; // @ts-expect-error is used above
event.__root = handler_element;
// @ts-expect-error is used above
current_target = handler_element;
}
} }

@ -0,0 +1,15 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
html: `<div><button>0 0</button>`,
async test({ assert, target }) {
const button1 = target.querySelector('button');
flushSync(() => button1?.click());
assert.htmlEqual(target.innerHTML, `<div><button>1 1</button></div>`);
},
runtime_error: 'nope'
});

@ -0,0 +1,19 @@
<script>
let y = $state(0);
let n = $state(0);
function yep() {
y += 1;
}
function nope() {
n += 1;
throw new Error('nope');
}
</script>
<div onclick={yep}>
<button onclick={nope}>
{y} {n}
</button>
</div>
Loading…
Cancel
Save