ensure modifier order is stable and matches svelte 4

pull/13362/head
Rich Harris 2 years ago
parent 821fc5f255
commit ca34d384d6

@ -699,6 +699,16 @@ function extract_type_and_comment(declarator, str, path) {
return { type: 'any', comment }; return { type: 'any', comment };
} }
// Ensure modifiers are applied in the same order as Svelte 4
const modifier_order = [
'preventDefault',
'stopPropagation',
'stopImmediatePropagation',
'self',
'trusted',
'once'
];
/** /**
* @param {AST.RegularElement | AST.SvelteElement | AST.SvelteWindow | AST.SvelteDocument | AST.SvelteBody} element * @param {AST.RegularElement | AST.SvelteElement | AST.SvelteWindow | AST.SvelteDocument | AST.SvelteBody} element
* @param {State} state * @param {State} state
@ -734,11 +744,6 @@ function handle_events(element, state) {
const needs_line_delete = const needs_line_delete =
state.str.original.substring(new_line_index, node.start).trim() === '' && i !== 0; state.str.original.substring(new_line_index, node.start).trim() === '' && i !== 0;
// 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.names.bubble}('${node.name}')`; let body = `${state.names.bubble}('${node.name}')`;
if (node.expression) { if (node.expression) {
@ -753,26 +758,22 @@ function handle_events(element, state) {
); );
} }
let has_passive = false; const has_passive = node.modifiers.includes('passive');
let has_nonpassive = false; const has_nonpassive = node.modifiers.includes('nonpassive');
for (const modifier of sorted_modifier) { const modifiers = modifier_order.filter((modifier) => node.modifiers.includes(modifier));
has_passive ||= modifier === 'passive';
has_nonpassive ||= modifier === 'nonpassive'; for (const modifier of modifiers) {
if (modifier !== 'capture' && modifier !== 'passive' && modifier !== 'nonpassive') { state.legacy_imports.add(modifier);
state.legacy_imports.add(modifier); body = `${state.names[modifier]}(${body})`;
body = `${state.names[modifier]}(${body})`;
}
} }
if (has_passive || has_nonpassive) { if (has_passive || has_nonpassive) {
if (has_passive) { const action = has_passive ? 'passive' : 'nonpassive';
state.legacy_imports.add('passive'); state.legacy_imports.add(action);
}
if (has_nonpassive) {
state.legacy_imports.add('nonpassive');
}
explicit_passive_handlers.push({ explicit_passive_handlers.push({
handler: `use:${has_nonpassive ? state.names.nonpassive : state.names.passive}={['${node.name}', () => ${body}]}`, handler: `use:${action}={['${node.name}', () => ${body}]}`,
indent, indent,
needs_line_delete needs_line_delete
}); });

@ -24,6 +24,7 @@
<button on:click|stopPropagation|stopImmediatePropagation={() => {}}>click me</button> <button on:click|stopPropagation|stopImmediatePropagation={() => {}}>click me</button>
<button on:click|stopImmediatePropagation|self={() => ''}>click me</button> <button on:click|stopImmediatePropagation|self={() => ''}>click me</button>
<button on:click|self|trusted={() => ''}>click me</button> <button on:click|self|trusted={() => ''}>click me</button>
<button on:click|trusted|self={() => ''}>click me</button>
<button on:click|trusted|once={() => ''}>click me</button> <button on:click|trusted|once={() => ''}>click me</button>
<button on:click|once|preventDefault={() => ''}>click me</button> <button on:click|once|preventDefault={() => ''}>click me</button>

@ -39,6 +39,7 @@
<button onclick={stopImmediatePropagation(stopPropagation(() => {}))}>click me</button> <button onclick={stopImmediatePropagation(stopPropagation(() => {}))}>click me</button>
<button onclick={self(stopImmediatePropagation(() => ''))}>click me</button> <button onclick={self(stopImmediatePropagation(() => ''))}>click me</button>
<button onclick={trusted(self(() => ''))}>click me</button> <button onclick={trusted(self(() => ''))}>click me</button>
<button onclick={trusted(self(() => ''))}>click me</button>
<button onclick={once(trusted(() => ''))}>click me</button> <button onclick={once(trusted(() => ''))}>click me</button>
<button onclick={once(preventDefault(() => ''))}>click me</button> <button onclick={once(preventDefault(() => ''))}>click me</button>

Loading…
Cancel
Save