fix: improve event delegation handler hoisting

pull/9929/head
Dominic Gannaway 3 years ago
parent 59c7487f36
commit 1b13438fb0

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

@ -121,6 +121,8 @@ 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', 'label']);
/** @type {Record<string, Set<string>>} */
const disallowed_contents = {
li: new Set(['li']),
@ -140,9 +142,13 @@ const disallowed_contents = {
tfoot: new Set(['tbody']),
tr: new Set(['tr', 'tbody']),
td: new Set(['td', 'th', 'tr']),
th: new Set(['td', 'th', 'tr'])
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