|
|
|
|
@ -22,13 +22,25 @@ export function fix_and_outro_and_destroy_block(block, lookup) {
|
|
|
|
|
outro_and_destroy_block(block, lookup);
|
|
|
|
|
}
|
|
|
|
|
/** @returns {any[]} */
|
|
|
|
|
export function update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block, next, get_context) {
|
|
|
|
|
export function update_keyed_each(
|
|
|
|
|
old_blocks,
|
|
|
|
|
dirty,
|
|
|
|
|
get_key,
|
|
|
|
|
dynamic,
|
|
|
|
|
ctx,
|
|
|
|
|
list,
|
|
|
|
|
lookup,
|
|
|
|
|
node,
|
|
|
|
|
destroy,
|
|
|
|
|
create_each_block,
|
|
|
|
|
next,
|
|
|
|
|
get_context
|
|
|
|
|
) {
|
|
|
|
|
let o = old_blocks.length;
|
|
|
|
|
let n = list.length;
|
|
|
|
|
let i = o;
|
|
|
|
|
const old_indexes = {};
|
|
|
|
|
while (i--)
|
|
|
|
|
old_indexes[old_blocks[i].key] = i;
|
|
|
|
|
while (i--) old_indexes[old_blocks[i].key] = i;
|
|
|
|
|
const new_blocks = [];
|
|
|
|
|
const new_lookup = new Map();
|
|
|
|
|
const deltas = new Map();
|
|
|
|
|
@ -41,14 +53,12 @@ export function update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list
|
|
|
|
|
if (!block) {
|
|
|
|
|
block = create_each_block(key, child_ctx);
|
|
|
|
|
block.c();
|
|
|
|
|
}
|
|
|
|
|
else if (dynamic) {
|
|
|
|
|
} else if (dynamic) {
|
|
|
|
|
// defer updates until all the DOM shuffling is done
|
|
|
|
|
updates.push(() => block.p(child_ctx, dirty));
|
|
|
|
|
}
|
|
|
|
|
new_lookup.set(key, (new_blocks[i] = block));
|
|
|
|
|
if (key in old_indexes)
|
|
|
|
|
deltas.set(key, Math.abs(i - old_indexes[key]));
|
|
|
|
|
if (key in old_indexes) deltas.set(key, Math.abs(i - old_indexes[key]));
|
|
|
|
|
}
|
|
|
|
|
const will_move = new Set();
|
|
|
|
|
const did_move = new Set();
|
|
|
|
|
@ -70,34 +80,27 @@ export function update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list
|
|
|
|
|
next = new_block.first;
|
|
|
|
|
o--;
|
|
|
|
|
n--;
|
|
|
|
|
}
|
|
|
|
|
else if (!new_lookup.has(old_key)) {
|
|
|
|
|
} else if (!new_lookup.has(old_key)) {
|
|
|
|
|
// remove old block
|
|
|
|
|
destroy(old_block, lookup);
|
|
|
|
|
o--;
|
|
|
|
|
}
|
|
|
|
|
else if (!lookup.has(new_key) || will_move.has(new_key)) {
|
|
|
|
|
} else if (!lookup.has(new_key) || will_move.has(new_key)) {
|
|
|
|
|
insert(new_block);
|
|
|
|
|
}
|
|
|
|
|
else if (did_move.has(old_key)) {
|
|
|
|
|
} else if (did_move.has(old_key)) {
|
|
|
|
|
o--;
|
|
|
|
|
}
|
|
|
|
|
else if (deltas.get(new_key) > deltas.get(old_key)) {
|
|
|
|
|
} else if (deltas.get(new_key) > deltas.get(old_key)) {
|
|
|
|
|
did_move.add(new_key);
|
|
|
|
|
insert(new_block);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
} else {
|
|
|
|
|
will_move.add(old_key);
|
|
|
|
|
o--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
while (o--) {
|
|
|
|
|
const old_block = old_blocks[o];
|
|
|
|
|
if (!new_lookup.has(old_block.key))
|
|
|
|
|
destroy(old_block, lookup);
|
|
|
|
|
if (!new_lookup.has(old_block.key)) destroy(old_block, lookup);
|
|
|
|
|
}
|
|
|
|
|
while (n)
|
|
|
|
|
insert(new_blocks[n - 1]);
|
|
|
|
|
while (n) insert(new_blocks[n - 1]);
|
|
|
|
|
run_all(updates);
|
|
|
|
|
return new_blocks;
|
|
|
|
|
}
|
|
|
|
|
@ -110,16 +113,15 @@ export function validate_each_keys(ctx, list, get_context, get_key) {
|
|
|
|
|
let value = '';
|
|
|
|
|
try {
|
|
|
|
|
value = `with value '${String(key)}' `;
|
|
|
|
|
}
|
|
|
|
|
catch (e) {
|
|
|
|
|
} catch (e) {
|
|
|
|
|
// can't stringify
|
|
|
|
|
}
|
|
|
|
|
throw new Error(`Cannot have duplicate keys in a keyed each: Keys at index ${keys.get(key)} and ${i} ${value}are duplicates`);
|
|
|
|
|
throw new Error(
|
|
|
|
|
`Cannot have duplicate keys in a keyed each: Keys at index ${keys.get(
|
|
|
|
|
key
|
|
|
|
|
)} and ${i} ${value}are duplicates`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
keys.set(key, i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|