fix: implement bubble on props strategy

pull/13362/head
paoloricciuti 2 years ago
parent 5f72e3f0e3
commit d5e0eaa21d

@ -117,7 +117,7 @@ export function migrate(source) {
.join(`,${props_separator}`);
if (analysis.uses_rest_props) {
props += `,${props_separator}...${state.rest_props_name}`;
props += `${state.props.length > 0 ? `,${props_separator}` : ''}...${state.rest_props_name}`;
}
}
@ -172,7 +172,7 @@ export function migrate(source) {
? `\n${indent}${[...state.script_insertions].join(indent)}\n`
: '';
str.prepend(
`<script>\n${imports}${indent}${props_declaration}${script_insertions}\n</script>\n\n`
`<script>\n${imports}${script_insertions}${indent}${props_declaration}\n</script>\n\n`
);
added_legacy_import = true;
}
@ -739,23 +739,19 @@ function handle_events(element, state) {
for (let i = 0; i < nodes.length; i += 1) {
const node = nodes[i];
const payload_name =
(node.expression?.type === 'ArrowFunctionExpression' ||
node.expression?.type === 'FunctionExpression') &&
node.expression.params[0]?.type === 'Identifier'
? node.expression.params[0].name
: generate_event_name(node, state);
const indent = get_indent(state, node, element);
const new_line_index = state.str.original.lastIndexOf('\n', node.start);
const needs_line_delete =
state.str.original.substring(new_line_index, node.start).trim() === '' && i !== 0;
// Check if prop already set, could happen when on:click on different elements
let local = state.props.find((prop) => prop.exported === exported)?.local;
// always move once as the first modifier
const sorted_modifier = [...node.modifiers].sort((a, b) =>
a === 'once' ? 1 : b === 'once' ? -1 : 0
);
let body = `${state.legacy_imports_names.bubble}('${node.name}')`;
let body = local ?? name;
if (node.expression) {
body = state.str.original.substring(
@ -763,6 +759,19 @@ function handle_events(element, state) {
/** @type {number} */ (node.expression.end)
);
} else {
const init = `${state.legacy_imports_names.bubble}('${node.name}')`;
if (!local) {
local = state.scope.generate(`on${node.name}`);
state.props.push({
local,
exported,
init,
bindable: false,
optional: true,
type: '(event: any) => void'
});
}
body = local;
state.legacy_imports.add('createBubbler');
state.script_insertions.add(
`const ${state.legacy_imports_names.bubble} = ${state.legacy_imports_names.createBubbler}();\n`
@ -791,11 +800,15 @@ function handle_events(element, state) {
handlers_body += `${handler.needs_line_delete || nodes.length > 1 ? `\n${handler.indent}` : ''}${handler.handler},`;
}
handlers_body = handlers_body.substring(0, handlers_body.length - 1);
state.str.overwrite(
first_node.start,
first_node.end,
`${name}={${nodes.length > 1 ? `${state.legacy_imports_names.handlers}(` : ''}${handlers_body}${nodes.length > 1 ? ')' : ''}}`
);
if (handlers_body === name && local === name) {
state.str.overwrite(first_node.start, first_node.end, `{${name}}`);
} else {
state.str.overwrite(
first_node.start,
first_node.end,
`${name}={${nodes.length > 1 ? `${state.legacy_imports_names.handlers}(` : ''}${handlers_body}${nodes.length > 1 ? ')' : ''}}`
);
}
}
}
}

@ -1,4 +1,11 @@
<script>
/** @type {{onclick?: (event: any) => void, ontoggle?: (event: any) => void, 'oncustom-event-bubble'?: (event: any) => void, onblur?: (event: any) => void}} */
let {
onclick = bubble_1('click'),
ontoggle = bubble_1('toggle'),
'oncustom-event-bubble': oncustom_event_bubble = bubble_1('custom-event-bubble'),
onblur = bubble_1('blur')
} = $props();
import { handlers as handlers_1, createBubbler as createBubbler_1, preventDefault, stopPropagation as stopPropagation_1, stopImmediatePropagation as stopImmediatePropagation_1, self as self_1, trusted as trusted_1, once as once_1 } from 'svelte/legacy';
const bubble_1 = createBubbler_1();
@ -15,25 +22,25 @@
<button onclick={handlers_1(
() => console.log('hi'),
bubble_1('click'))} >click me</button>
onclick)} >click me</button>
<button onclick={handlers_1(
function(){ console.log('hi') },
bubble_1('click'))} >click me</button>
onclick)} >click me</button>
<button onclick={handlers_1(
() => console.log('before'),
bubble_1('click'),
onclick,
() => console.log('after'))}
>click me</button
>
<button onclick={handlers_1(
bubble_1('click'),
onclick,
foo)} >click me</button>
<button onclick={bubble_1('click')}>click me</button>
<button {onclick}>click me</button>
<button ondblclick={() => console.log('hi')}>click me</button>
<button ontoggle={bubble_1('toggle')}>click me</button>
<button ontoggle={ontoggle}>click me</button>
<button oncustom-event={() => 'hi'}>click me</button>
<button oncustom-event-bubble={bubble_1('custom-event-bubble')}>click me</button>
<button oncustom-event-bubble={oncustom_event_bubble}>click me</button>
<button onclick={preventDefault(() => (searching = true))}>click me</button>
<button onclick={preventDefault(() => '')}>click me</button>
@ -53,13 +60,13 @@
<button
onclick={handlers_1(
bubble_1('click'),
onclick,
foo,
()=>'',
once_1(preventDefault(trusted_1(()=>''))))}
onblur={handlers_1(
foo,
once_1(preventDefault(trusted_1(bubble_1('blur')))))}
once_1(preventDefault(trusted_1(onblur))))}
>
click me
</button>

@ -1,31 +1,38 @@
<script>
import { handlers, createBubbler, preventDefault, stopPropagation, stopImmediatePropagation, self, trusted, once } from 'svelte/legacy';
const bubble = createBubbler();
/** @type {{onclick?: (event: any) => void, ontoggle?: (event: any) => void, 'oncustom-event-bubble'?: (event: any) => void, onblur?: (event: any) => void}} */
let {
onclick = bubble('click'),
ontoggle = bubble('toggle'),
'oncustom-event-bubble': oncustom_event_bubble = bubble('custom-event-bubble'),
onblur = bubble('blur')
} = $props();
</script>
<button onclick={handlers(
() => console.log('hi'),
bubble('click'))} >click me</button>
onclick)} >click me</button>
<button onclick={handlers(
function(){ console.log('hi') },
bubble('click'))} >click me</button>
onclick)} >click me</button>
<button onclick={handlers(
() => console.log('before'),
bubble('click'),
onclick,
() => console.log('after'))}
>click me</button
>
<button onclick={handlers(
bubble('click'),
onclick,
foo)} >click me</button>
<button onclick={bubble('click')}>click me</button>
<button {onclick}>click me</button>
<button ondblclick={() => console.log('hi')}>click me</button>
<button ontoggle={bubble('toggle')}>click me</button>
<button ontoggle={ontoggle}>click me</button>
<button oncustom-event={() => 'hi'}>click me</button>
<button oncustom-event-bubble={bubble('custom-event-bubble')}>click me</button>
<button oncustom-event-bubble={oncustom_event_bubble}>click me</button>
<button onclick={preventDefault(() => (searching = true))}>click me</button>
<button onclick={preventDefault(() => '')}>click me</button>
@ -45,13 +52,13 @@
<button
onclick={handlers(
bubble('click'),
onclick,
foo,
()=>'',
once(preventDefault(trusted(()=>''))))}
onblur={handlers(
foo,
once(preventDefault(trusted(bubble('blur')))))}
once(preventDefault(trusted(onblur))))}
>
click me
</button>

Loading…
Cancel
Save