From 25316580465304ff461fe10f6ccad8bb91bbfa41 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Fri, 27 Sep 2024 11:57:34 +0100 Subject: [PATCH] fix: ensure use directives execute in the correct sequence (#13384) Fixes #13382. This PR ensures that action directives are now executed in the same sequence as Svelte 4, so child element before parent element. --- .changeset/afraid-trainers-occur.md | 5 +++++ .../client/visitors/RegularElement.js | 17 +++++++++++++---- .../samples/action-sequence/_config.js | 7 +++++++ .../samples/action-sequence/main.svelte | 18 ++++++++++++++++++ 4 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 .changeset/afraid-trainers-occur.md create mode 100644 packages/svelte/tests/runtime-runes/samples/action-sequence/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/action-sequence/main.svelte diff --git a/.changeset/afraid-trainers-occur.md b/.changeset/afraid-trainers-occur.md new file mode 100644 index 000000000000..144bbdf7c9b7 --- /dev/null +++ b/.changeset/afraid-trainers-occur.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure use directives execute in the correct sequence diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js index 911991b90a82..9be435156353 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js @@ -157,15 +157,18 @@ export function RegularElement(node, context) { } } + /** @type {typeof state} */ + const element_after_update_state = { ...context.state, after_update: [] }; + for (const attribute of other_directives) { if (attribute.type === 'OnDirective') { const handler = /** @type {Expression} */ (context.visit(attribute)); - context.state.after_update.push( + element_after_update_state.after_update.push( b.stmt(has_use ? b.call('$.effect', b.thunk(handler)) : handler) ); } else { - context.visit(attribute); + context.visit(attribute, element_after_update_state); } } @@ -401,13 +404,19 @@ export function RegularElement(node, context) { b.block([ ...child_state.init, child_state.update.length > 0 ? build_render_statement(child_state.update) : b.empty, - ...child_state.after_update + ...child_state.after_update, + ...element_after_update_state.after_update ]) ); } else if (node.fragment.metadata.dynamic) { context.state.init.push(...child_state.init); context.state.update.push(...child_state.update); - context.state.after_update.push(...child_state.after_update); + context.state.after_update.push( + ...child_state.after_update, + ...element_after_update_state.after_update + ); + } else { + context.state.after_update.push(...element_after_update_state.after_update); } if (lookup.has('dir')) { diff --git a/packages/svelte/tests/runtime-runes/samples/action-sequence/_config.js b/packages/svelte/tests/runtime-runes/samples/action-sequence/_config.js new file mode 100644 index 000000000000..b42492a69d63 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/action-sequence/_config.js @@ -0,0 +1,7 @@ +import { test } from '../../test'; + +export default test({ + async test({ assert, logs }) { + assert.deepEqual(logs, ['1', '2', '3', '4', '5', '6']); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/action-sequence/main.svelte b/packages/svelte/tests/runtime-runes/samples/action-sequence/main.svelte new file mode 100644 index 000000000000..1e2442164854 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/action-sequence/main.svelte @@ -0,0 +1,18 @@ + + +
+
+
+
+
+
+
+
+
+
+
+