|
|
|
@ -202,117 +202,6 @@ export function each_indexed(anchor_node, collection, flags, render_fn, fallback
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @template V
|
|
|
|
|
* @param {Array<V>} array
|
|
|
|
|
* @param {import('../../types.js').EachBlock} each_block
|
|
|
|
|
* @param {Element | Comment | Text} dom
|
|
|
|
|
* @param {boolean} is_controlled
|
|
|
|
|
* @param {(anchor: null, item: V, index: number | import('../../types.js').Signal<number>) => void} render_fn
|
|
|
|
|
* @param {number} flags
|
|
|
|
|
* @param {boolean} apply_transitions
|
|
|
|
|
* @returns {void}
|
|
|
|
|
*/
|
|
|
|
|
function reconcile_indexed_array(
|
|
|
|
|
array,
|
|
|
|
|
each_block,
|
|
|
|
|
dom,
|
|
|
|
|
is_controlled,
|
|
|
|
|
render_fn,
|
|
|
|
|
flags,
|
|
|
|
|
apply_transitions
|
|
|
|
|
) {
|
|
|
|
|
var a_blocks = each_block.v;
|
|
|
|
|
var active_transitions = each_block.s;
|
|
|
|
|
|
|
|
|
|
/** @type {number | void} */
|
|
|
|
|
var a = a_blocks.length;
|
|
|
|
|
|
|
|
|
|
/** @type {number} */
|
|
|
|
|
var b = array.length;
|
|
|
|
|
var length = Math.max(a, b);
|
|
|
|
|
var index = 0;
|
|
|
|
|
|
|
|
|
|
/** @type {Array<import('../../types.js').EachItemBlock>} */
|
|
|
|
|
var b_blocks;
|
|
|
|
|
var block;
|
|
|
|
|
|
|
|
|
|
if (active_transitions.length !== 0) {
|
|
|
|
|
destroy_active_transition_blocks(active_transitions);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (b === 0) {
|
|
|
|
|
b_blocks = [];
|
|
|
|
|
// Remove old blocks
|
|
|
|
|
if (is_controlled && a !== 0) {
|
|
|
|
|
clear_text_content(dom);
|
|
|
|
|
}
|
|
|
|
|
while (index < length) {
|
|
|
|
|
block = a_blocks[index++];
|
|
|
|
|
destroy_each_item_block(block, active_transitions, apply_transitions, is_controlled);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
var item;
|
|
|
|
|
/** `true` if there was a hydration mismatch. Needs to be a `let` or else it isn't treeshaken out */
|
|
|
|
|
let mismatch = false;
|
|
|
|
|
b_blocks = Array(b);
|
|
|
|
|
if (hydrating) {
|
|
|
|
|
// Hydrate block
|
|
|
|
|
var hydration_list = /** @type {import('../../types.js').TemplateNode[]} */ (
|
|
|
|
|
current_hydration_fragment
|
|
|
|
|
);
|
|
|
|
|
var hydrating_node = hydration_list[0];
|
|
|
|
|
for (; index < length; index++) {
|
|
|
|
|
var fragment = get_hydration_fragment(hydrating_node);
|
|
|
|
|
set_current_hydration_fragment(fragment);
|
|
|
|
|
if (!fragment) {
|
|
|
|
|
// If fragment is null, then that means that the server rendered less items than what
|
|
|
|
|
// the client code specifies -> break out and continue with client-side node creation
|
|
|
|
|
mismatch = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
item = array[index];
|
|
|
|
|
block = each_item_block(item, null, index, render_fn, flags);
|
|
|
|
|
b_blocks[index] = block;
|
|
|
|
|
|
|
|
|
|
hydrating_node = /** @type {import('../../types.js').TemplateNode} */ (
|
|
|
|
|
/** @type {Node} */ (/** @type {Node} */ (fragment.at(-1)).nextSibling).nextSibling
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
remove_excess_hydration_nodes(hydration_list, hydrating_node);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (; index < length; index++) {
|
|
|
|
|
if (index >= a) {
|
|
|
|
|
// Add block
|
|
|
|
|
item = array[index];
|
|
|
|
|
block = each_item_block(item, null, index, render_fn, flags);
|
|
|
|
|
b_blocks[index] = block;
|
|
|
|
|
insert_each_item_block(block, dom, is_controlled, null);
|
|
|
|
|
} else if (index >= b) {
|
|
|
|
|
// Remove block
|
|
|
|
|
block = a_blocks[index];
|
|
|
|
|
destroy_each_item_block(block, active_transitions, apply_transitions);
|
|
|
|
|
} else {
|
|
|
|
|
// Update block
|
|
|
|
|
item = array[index];
|
|
|
|
|
block = a_blocks[index];
|
|
|
|
|
b_blocks[index] = block;
|
|
|
|
|
update_each_item_block(block, item, index, flags);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mismatch) {
|
|
|
|
|
// Server rendered less nodes than the client -> set empty array so that Svelte continues to operate in hydration mode
|
|
|
|
|
set_current_hydration_fragment([]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
each_block.v = b_blocks;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Reconcile arrays by the equality of the elements in the array. This algorithm
|
|
|
|
|
* is based on Ivi's reconcilation logic:
|
|
|
|
|