Skip to content

chore: follow-up to #11197 #11213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 17 additions & 19 deletions packages/svelte/src/internal/client/dom/blocks/each.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
import { source, mutable_source, set } from '../../reactivity/sources.js';
import { is_array, is_frozen } from '../../utils.js';
import { INERT, STATE_SYMBOL } from '../../constants.js';
import { push_template_node } from '../template.js';

/**
* The row of a keyed each block that is currently updating. We track this
Expand Down Expand Up @@ -168,10 +169,11 @@ export function each(anchor, flags, get_collection, get_key, render_fn, fallback
break;
}

var child_open = /** @type {Comment} */ (child_anchor);
child_anchor = hydrate_anchor(child_anchor);
var value = array[i];
var key = get_key(value, i);
item = create_item(child_anchor, prev, null, value, key, i, render_fn, flags);
item = create_item(child_open, child_anchor, prev, null, value, key, i, render_fn, flags);
state.items.set(key, item);
child_anchor = /** @type {Comment} */ (child_anchor.nextSibling);

Expand Down Expand Up @@ -278,8 +280,14 @@ function reconcile(array, state, anchor, render_fn, flags, get_key) {
item = items.get(key);

if (item === undefined) {
var child_open = /** @type {Text} */ (push_template_node(empty()));
var child_anchor = current ? current.o : anchor;

child_anchor.before(child_open);

prev = create_item(
current ? get_first_child(current) : anchor,
child_open,
child_anchor,
prev,
prev.next,
value,
Expand Down Expand Up @@ -312,7 +320,7 @@ function reconcile(array, state, anchor, render_fn, flags, get_key) {
if (matched.length < stashed.length) {
// more efficient to move later items to the front
var start = stashed[0];
var local_anchor = get_first_child(start);
var local_anchor = start.o;
var j;

prev = start.prev;
Expand Down Expand Up @@ -341,7 +349,7 @@ function reconcile(array, state, anchor, render_fn, flags, get_key) {
} else {
// more efficient to move earlier items to the back
seen.delete(item);
move(item, current ? get_first_child(current) : anchor);
move(item, current ? current.o : anchor);

link(item.prev, item.next);
link(item, prev.next);
Expand Down Expand Up @@ -402,20 +410,6 @@ function reconcile(array, state, anchor, render_fn, flags, get_key) {
}
}

/**
* @param {import('#client').EachItem} item
* @returns {Text | Element | Comment}
*/
function get_first_child(item) {
var current = item.e.dom;

if (is_array(current)) {
return /** @type {Text | Element | Comment} */ (current[0]);
}

return /** @type {Text | Element | Comment} */ (current);
}

/**
* @param {import('#client').EachItem} item
* @param {any} value
Expand All @@ -437,6 +431,7 @@ function update_item(item, value, index, type) {

/**
* @template V
* @param {Comment | Text} open
* @param {Node} anchor
* @param {import('#client').EachItem | import('#client').EachState} prev
* @param {import('#client').EachItem | null} next
Expand All @@ -447,7 +442,7 @@ function update_item(item, value, index, type) {
* @param {number} flags
* @returns {import('#client').EachItem}
*/
function create_item(anchor, prev, next, value, key, index, render_fn, flags) {
function create_item(open, anchor, prev, next, value, key, index, render_fn, flags) {
var previous_each_item = current_each_item;

try {
Expand All @@ -465,6 +460,7 @@ function create_item(anchor, prev, next, value, key, index, render_fn, flags) {
a: null,
// @ts-expect-error
e: null,
o: open,
prev,
next
};
Expand All @@ -486,6 +482,8 @@ function create_item(anchor, prev, next, value, key, index, render_fn, flags) {
* @param {Text | Element | Comment} anchor
*/
function move(item, anchor) {
anchor.before(item.o);

var dom = item.e.dom;

if (dom !== null) {
Expand Down
4 changes: 2 additions & 2 deletions packages/svelte/src/internal/client/dom/blocks/html.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function html_to_dom(target, effect, value, svg) {
var child = /** @type {Text | Element | Comment} */ (node.firstChild);
target.before(child);
if (effect !== null) {
push_template_node(effect, child);
push_template_node(child, effect);
}
return child;
}
Expand All @@ -95,7 +95,7 @@ function html_to_dom(target, effect, value, svg) {
}

if (effect !== null) {
push_template_node(effect, nodes);
push_template_node(nodes, effect);
}

return nodes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export function element(anchor, get_tag, is_svg, render_fn) {
swap_block_dom(parent_effect, prev_element, element);
prev_element.remove();
} else if (!hydrating) {
push_template_node(parent_effect, element);
push_template_node(element, parent_effect);
}
});
}
Expand Down
59 changes: 20 additions & 39 deletions packages/svelte/src/internal/client/dom/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,26 @@ import { effect } from '../reactivity/effects.js';
import { is_array } from '../utils.js';

/**
* @param {import("#client").Effect} effect
* @param {import("#client").TemplateNode | import("#client").TemplateNode[]} dom
* @param {import("#client").Effect} effect
*/
export function push_template_node(effect, dom) {
export function push_template_node(
dom,
effect = /** @type {import('#client').Effect} */ (current_effect)
) {
var current_dom = effect.dom;
if (current_dom === null) {
effect.dom = dom;
} else {
if (!is_array(current_dom)) {
current_dom = effect.dom = [current_dom];
}
var anchor;
// If we're working with an anchor, then remove it and put it at the end.
if (current_dom[0].nodeType === 8) {
anchor = current_dom.pop();
}

if (is_array(dom)) {
current_dom.push(...dom);
} else {
current_dom.push(dom);
}
if (anchor !== undefined) {
current_dom.push(anchor);
}
}
return dom;
}
Expand All @@ -49,12 +45,8 @@ export function template(content, flags) {
var node;

return () => {
var effect = /** @type {import('#client').Effect} */ (current_effect);
if (hydrating) {
var hydration_content = push_template_node(
effect,
is_fragment ? hydrate_nodes : hydrate_nodes[0]
);
var hydration_content = push_template_node(is_fragment ? hydrate_nodes : hydrate_nodes[0]);
return /** @type {Node} */ (hydration_content);
}

Expand All @@ -64,14 +56,11 @@ export function template(content, flags) {
}
var clone = use_import_node ? document.importNode(node, true) : clone_node(node, true);

if (is_fragment) {
push_template_node(
effect,
/** @type {import('#client').TemplateNode[]} */ ([...clone.childNodes])
);
} else {
push_template_node(effect, /** @type {import('#client').TemplateNode} */ (clone));
}
push_template_node(
is_fragment
? /** @type {import('#client').TemplateNode[]} */ ([...clone.childNodes])
: /** @type {import('#client').TemplateNode} */ (clone)
);

return clone;
};
Expand Down Expand Up @@ -115,12 +104,8 @@ export function svg_template(content, flags) {
var node;

return () => {
var effect = /** @type {import('#client').Effect} */ (current_effect);
if (hydrating) {
var hydration_content = push_template_node(
effect,
is_fragment ? hydrate_nodes : hydrate_nodes[0]
);
var hydration_content = push_template_node(is_fragment ? hydrate_nodes : hydrate_nodes[0]);
return /** @type {Node} */ (hydration_content);
}

Expand All @@ -139,14 +124,11 @@ export function svg_template(content, flags) {

var clone = clone_node(node, true);

if (is_fragment) {
push_template_node(
effect,
/** @type {import('#client').TemplateNode[]} */ ([...clone.childNodes])
);
} else {
push_template_node(effect, /** @type {import('#client').TemplateNode} */ (clone));
}
push_template_node(
is_fragment
? /** @type {import('#client').TemplateNode[]} */ ([...clone.childNodes])
: /** @type {import('#client').TemplateNode} */ (clone)
);

return clone;
};
Expand Down Expand Up @@ -213,8 +195,7 @@ function run_scripts(node) {
*/
/*#__NO_SIDE_EFFECTS__*/
export function text(anchor) {
var effect = /** @type {import('#client').Effect} */ (current_effect);
if (!hydrating) return push_template_node(effect, empty());
if (!hydrating) return push_template_node(empty());

var node = hydrate_nodes[0];

Expand All @@ -224,7 +205,7 @@ export function text(anchor) {
anchor.before((node = empty()));
}

return push_template_node(effect, node);
return push_template_node(node);
}

export const comment = template('<!>', TEMPLATE_FRAGMENT);
Expand Down
2 changes: 2 additions & 0 deletions packages/svelte/src/internal/client/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ export type EachItem = {
i: number | Source<number>;
/** key */
k: unknown;
/** anchor for items inserted before this */
o: Comment | Text;
prev: EachItem | EachState;
next: EachItem | null;
};
Expand Down