pull/10798/head
Rich Harris 2 years ago
parent d8a4778c98
commit b2b10a755c

@ -354,18 +354,15 @@ function reconcile_indexed_array(array, each_block, dom, is_controlled, render_f
function reconcile_tracked_array(array, each_block, dom, is_controlled, render_fn, flags, keys) {
var a_blocks = each_block.v;
/** @type {number | void} */
var a = a_blocks.length;
/** @type {number} */
var b = array.length;
/** @type {Array<import('#client').EachItemBlock>} */
var b_blocks;
var block;
if (b === 0) {
b_blocks = [];
// Remove old blocks
if (is_controlled && a !== 0) {
clear_text_content(dom);
@ -374,21 +371,23 @@ function reconcile_tracked_array(array, each_block, dom, is_controlled, render_f
block = a_blocks[--a];
destroy_each_item_block(block, is_controlled);
}
b_blocks = [];
} else {
var a_end = a - 1;
var b_end = b - 1;
var key;
var item;
var idx;
var i;
b_blocks = Array(b);
if (a === 0) {
// Create new blocks
while (b > 0) {
idx = b_end - --b;
block = each_item_block(array[idx], keys[idx], idx, render_fn, flags);
b_blocks[idx] = block;
i = b_end - --b;
block = each_item_block(array[i], keys[i], i, render_fn, flags);
b_blocks[i] = block;
insert_each_item_block(block, dom, is_controlled, null);
}
} else {
@ -401,24 +400,31 @@ function reconcile_tracked_array(array, each_block, dom, is_controlled, render_f
var sibling = null;
item = array[b_end];
key = keys[b_end];
// Step 1
outer: while (true) {
// From the end
while (a_blocks[a_end].k === key) {
block = a_blocks[a_end--];
item = array[b_end];
if (should_update_block) {
update_each_item_block(block, item, b_end, flags);
}
sibling = get_first_child(block);
b_blocks[b_end] = block;
if (start > --b_end || start > a_end) {
break outer;
}
key = keys[b_end];
}
item = array[start];
key = keys[start];
// At the start
while (start <= a_end && start <= b_end && a_blocks[start].k === key) {
item = array[start];
@ -430,8 +436,10 @@ function reconcile_tracked_array(array, each_block, dom, is_controlled, render_f
++start;
key = keys[start];
}
break;
}
// Step 2
if (start > a_end) {
while (b_end >= start) {
@ -441,6 +449,7 @@ function reconcile_tracked_array(array, each_block, dom, is_controlled, render_f
}
} else if (start > b_end) {
b = start;
do {
if ((block = a_blocks[b++]) !== null) {
destroy_each_item_block(block);
@ -458,6 +467,7 @@ function reconcile_tracked_array(array, each_block, dom, is_controlled, render_f
item = array[a];
map_set(item_index, keys[a], a);
}
// If keys are animated, we need to do updates before actual moves
if (is_animated) {
for (b = start; b <= a_end; ++b) {
@ -469,6 +479,7 @@ function reconcile_tracked_array(array, each_block, dom, is_controlled, render_f
}
}
}
for (b = start; b <= a_end; ++b) {
a = map_get(item_index, /** @type {V} */ (a_blocks[b].k));
block = a_blocks[b];
@ -480,18 +491,22 @@ function reconcile_tracked_array(array, each_block, dom, is_controlled, render_f
destroy_each_item_block(block);
}
}
// Step 4
if (pos === MOVED_BLOCK) {
mark_lis(sources);
}
var last_block;
var last_sibling;
var should_create;
while (b_length-- > 0) {
b_end = b_length + start;
a = sources[b_length];
should_create = a === -1;
item = array[b_end];
if (should_create) {
block = each_item_block(item, keys[b_end], b_end, render_fn, flags);
} else {
@ -500,10 +515,12 @@ function reconcile_tracked_array(array, each_block, dom, is_controlled, render_f
update_each_item_block(block, item, b_end, flags);
}
}
if (should_create || (pos === MOVED_BLOCK && a !== LIS_BLOCK)) {
last_sibling = last_block === undefined ? sibling : get_first_child(last_block);
sibling = insert_each_item_block(block, dom, is_controlled, last_sibling);
}
b_blocks[b_end] = block;
last_block = block;
}

Loading…
Cancel
Save