fix: improve event delegation handler hoisting (#9929)

* fix: improve event delegation handler hoisting

* fixes
pull/9922/head
Dominic Gannaway 1 year ago committed by GitHub
parent 59c7487f36
commit b8f3c49e5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: improve event delegation handler hoisting

@ -121,6 +121,16 @@ function validate_code(code) {
// based on http://developers.whatwg.org/syntax.html#syntax-tag-omission
const interactive_elements = new Set([
'a',
'button',
'iframe',
'embed',
'input',
'select',
'textarea'
]);
/** @type {Record<string, Set<string>>} */
const disallowed_contents = {
li: new Set(['li']),
@ -143,6 +153,10 @@ const disallowed_contents = {
th: new Set(['td', 'th', 'tr'])
};
for (const interactive_element of interactive_elements) {
disallowed_contents[interactive_element] = interactive_elements;
}
// can this be a child of the parent element, or does it implicitly
// close it, like `<li>one<li>two`?

@ -166,6 +166,7 @@ function get_delegated_event(node, context) {
return non_hoistable;
}
const visited_references = new Set();
const scope = target_function.metadata.scope;
for (const [reference] of scope.references) {
// Bail-out if the arguments keyword is used
@ -174,6 +175,15 @@ function get_delegated_event(node, context) {
}
const binding = scope.get(reference);
// If we have multiple references to the same store using $ prefix, bail out.
if (
binding !== null &&
binding.kind === 'store_sub' &&
visited_references.has(reference.slice(1))
) {
return non_hoistable;
}
if (
binding !== null &&
// Bail-out if the the binding is a rest param
@ -188,6 +198,7 @@ function get_delegated_event(node, context) {
) {
return non_hoistable;
}
visited_references.add(reference);
}
return { type: 'hoistable', function: target_function };
}

@ -363,8 +363,7 @@ function get_hoistable_params(node, context) {
binding.kind === 'prop' &&
!binding.reassigned &&
binding.initial === null &&
!context.state.analysis.accessors &&
context.state.analysis.runes
!context.state.analysis.accessors
) {
// Handle $$props.something use-cases
if (!added_props) {

@ -0,0 +1,7 @@
import { test } from '../../test';
export default test({
compileOptions: { dev: true }, // tests `@validate_store` code generation
html: `<button>clicks:\n0</button>`
});

@ -0,0 +1,12 @@
<script>
import {writable} from 'svelte/store'
let store = writable(0)
</script>
<button onclick={() => {
if(store && $store){
}
}}>
clicks: {$store}
</button>
Loading…
Cancel
Save