From 4717d2ad23487dc2e27693979919205c35d7d9a4 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Thu, 7 Dec 2023 17:07:26 +0000 Subject: [PATCH] fix: handle event hoisting props referencing (#9846) * fix: handle event hoisting props referencing --- .changeset/clever-rockets-burn.md | 5 +++++ .../phases/3-transform/client/utils.js | 14 +++++++++++++ .../samples/event-prop-reference/_config.js | 21 +++++++++++++++++++ .../samples/event-prop-reference/log.js | 2 ++ .../samples/event-prop-reference/main.svelte | 13 ++++++++++++ 5 files changed, 55 insertions(+) create mode 100644 .changeset/clever-rockets-burn.md create mode 100644 packages/svelte/tests/runtime-runes/samples/event-prop-reference/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/event-prop-reference/log.js create mode 100644 packages/svelte/tests/runtime-runes/samples/event-prop-reference/main.svelte diff --git a/.changeset/clever-rockets-burn.md b/.changeset/clever-rockets-burn.md new file mode 100644 index 0000000000..eced64e637 --- /dev/null +++ b/.changeset/clever-rockets-burn.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: handle event hoisting props referencing diff --git a/packages/svelte/src/compiler/phases/3-transform/client/utils.js b/packages/svelte/src/compiler/phases/3-transform/client/utils.js index 90f5c6ec29..f22bf8065b 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/utils.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/utils.js @@ -316,6 +316,7 @@ function get_hoistable_params(node, context) { /** @type {import('estree').Pattern[]} */ const params = []; + let added_props = false; for (const [reference] of scope.references) { const binding = scope.get(reference); @@ -325,6 +326,19 @@ function get_hoistable_params(node, context) { // We need both the subscription for getting the value and the store for updating params.push(b.id(binding.node.name.slice(1))); params.push(b.id(binding.node.name)); + } else if ( + // If we are referencing a simple $$props value, then we need to reference the object property instead + binding.kind === 'prop' && + !binding.reassigned && + binding.initial === null && + !context.state.analysis.accessors && + context.state.analysis.runes + ) { + // Handle $$props.something use-cases + if (!added_props) { + added_props = true; + params.push(b.id('$$props')); + } } else { // create a copy to remove start/end tags which would mess up source maps params.push(b.id(binding.node.name)); diff --git a/packages/svelte/tests/runtime-runes/samples/event-prop-reference/_config.js b/packages/svelte/tests/runtime-runes/samples/event-prop-reference/_config.js new file mode 100644 index 0000000000..3b801f6b7b --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/event-prop-reference/_config.js @@ -0,0 +1,21 @@ +import { test } from '../../test'; +import { log } from './log.js'; + +export default test({ + before_test() { + log.length = 0; + }, + + get props() { + return { item: { name: 'Dominic' } }; + }, + + async test({ assert, target }) { + const [b1] = target.querySelectorAll('button'); + + b1?.click(); + await Promise.resolve(); + + assert.deepEqual(log, ['Dominic']); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/event-prop-reference/log.js b/packages/svelte/tests/runtime-runes/samples/event-prop-reference/log.js new file mode 100644 index 0000000000..d3df521f4d --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/event-prop-reference/log.js @@ -0,0 +1,2 @@ +/** @type {any[]} */ +export const log = []; diff --git a/packages/svelte/tests/runtime-runes/samples/event-prop-reference/main.svelte b/packages/svelte/tests/runtime-runes/samples/event-prop-reference/main.svelte new file mode 100644 index 0000000000..697338d97b --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/event-prop-reference/main.svelte @@ -0,0 +1,13 @@ + + +