From 638483951a3a3a00fa2a03ae5d895a7a5e7c07ef Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Mon, 13 Nov 2023 16:11:00 +0000 Subject: [PATCH] Split $.each into $.each_keyed/$.each_indexed --- .github/PULL_REQUEST_TEMPLATE.md | 1 - .../3-transform/client/visitors/template.js | 39 +++++++++++----- .../svelte/src/internal/client/reconciler.js | 6 +-- packages/svelte/src/internal/client/render.js | 45 ++++++++++++------- 4 files changed, 60 insertions(+), 31 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e41d1e40c7..a4819f87ba 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -4,7 +4,6 @@ Please note that [the Svelte codebase is currently being rewritten for Svelte 5] If your PR concerns Svelte 4 (including updates to [svelte.dev.docs](https://svelte.dev/docs)), please ensure the base branch is `svelte-4` and not `main`. - ### Before submitting the PR, please make sure you do the following - [ ] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js index c80153a327..b830367776 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js @@ -2227,19 +2227,34 @@ export const template_visitors = { declarations.push(b.let(node.index, index)); } - context.state.after_update.push( - b.stmt( - b.call( - '$.each', - context.state.node, - each_node_meta.array_name ? each_node_meta.array_name : b.thunk(collection), - b.literal(each_type), - key_function, - b.arrow([b.id('$$anchor'), item, index], b.block(declarations.concat(children))), - else_block + if ((each_type & EACH_KEYED) !== 0) { + context.state.after_update.push( + b.stmt( + b.call( + '$.each_keyed', + context.state.node, + each_node_meta.array_name ? each_node_meta.array_name : b.thunk(collection), + b.literal(each_type), + key_function, + b.arrow([b.id('$$anchor'), item, index], b.block(declarations.concat(children))), + else_block + ) ) - ) - ); + ); + } else { + context.state.after_update.push( + b.stmt( + b.call( + '$.each_indexed', + context.state.node, + each_node_meta.array_name ? each_node_meta.array_name : b.thunk(collection), + b.literal(each_type), + b.arrow([b.id('$$anchor'), item, index], b.block(declarations.concat(children))), + else_block + ) + ) + ); + } }, IfBlock(node, context) { context.state.template.push(''); diff --git a/packages/svelte/src/internal/client/reconciler.js b/packages/svelte/src/internal/client/reconciler.js index f0b0fce7c2..ded5c7ec23 100644 --- a/packages/svelte/src/internal/client/reconciler.js +++ b/packages/svelte/src/internal/client/reconciler.js @@ -260,9 +260,9 @@ export function reconcile_indexed_array( * @param {Element | Comment | Text} dom * @param {boolean} is_controlled * @param {(anchor: null, item: V, index: number | import('./types.js').Signal) => void} render_fn - * @param {Array | null} keys * @param {number} flags * @param {boolean} apply_transitions + * @param {Array | null} keys * @returns {void} */ export function reconcile_tracked_array( @@ -271,9 +271,9 @@ export function reconcile_tracked_array( dom, is_controlled, render_fn, - keys, flags, - apply_transitions + apply_transitions, + keys ) { var a_blocks = each_block.items; const is_computed_key = keys !== null; diff --git a/packages/svelte/src/internal/client/render.js b/packages/svelte/src/internal/client/render.js index 2ef1033638..7ebf3d202a 100644 --- a/packages/svelte/src/internal/client/render.js +++ b/packages/svelte/src/internal/client/render.js @@ -2263,9 +2263,10 @@ export function each_item_block(item, key, index, render_fn, flags) { * @param {null | ((item: V) => string)} key_fn * @param {(anchor: null, item: V, index: import('./types.js').MaybeSignal) => void} render_fn * @param {null | ((anchor: Node) => void)} fallback_fn + * @param {typeof reconcile_indexed_array | reconcile_tracked_array} reconcile_fn * @returns {void} */ -export function each(anchor_node, collection, flags, key_fn, render_fn, fallback_fn) { +function each(anchor_node, collection, flags, key_fn, render_fn, fallback_fn, reconcile_fn) { const is_controlled = (flags & EACH_IS_CONTROLLED) !== 0; const block = create_each_block(flags, anchor_node); @@ -2385,20 +2386,7 @@ export function each(anchor_node, collection, flags, key_fn, render_fn, fallback const flags = block.flags; const is_controlled = (flags & EACH_IS_CONTROLLED) !== 0; const anchor_node = block.anchor; - if ((flags & EACH_KEYED) !== 0) { - reconcile_tracked_array( - array, - block, - anchor_node, - is_controlled, - render_fn, - keys, - flags, - true - ); - } else { - reconcile_indexed_array(array, block, anchor_node, is_controlled, render_fn, flags, true); - } + reconcile_fn(array, block, anchor_node, is_controlled, render_fn, flags, true, keys); }, block, true @@ -2426,6 +2414,33 @@ export function each(anchor_node, collection, flags, key_fn, render_fn, fallback block.effect = each; } +/** + * @template V + * @param {Element | Comment} anchor_node + * @param {() => V[]} collection + * @param {number} flags + * @param {null | ((item: V) => string)} key_fn + * @param {(anchor: null, item: V, index: import('./types.js').MaybeSignal) => void} render_fn + * @param {null | ((anchor: Node) => void)} fallback_fn + * @returns {void} + */ +export function each_keyed(anchor_node, collection, flags, key_fn, render_fn, fallback_fn) { + each(anchor_node, collection, flags, key_fn, render_fn, fallback_fn, reconcile_tracked_array); +} + +/** + * @template V + * @param {Element | Comment} anchor_node + * @param {() => V[]} collection + * @param {number} flags + * @param {(anchor: null, item: V, index: import('./types.js').MaybeSignal) => void} render_fn + * @param {null | ((anchor: Node) => void)} fallback_fn + * @returns {void} + */ +export function each_indexed(anchor_node, collection, flags, render_fn, fallback_fn) { + each(anchor_node, collection, flags, null, render_fn, fallback_fn, reconcile_indexed_array); +} + /** * @param {Element | Text | Comment} anchor * @param {boolean} is_html