From 5a7f7a00ece49b51ace7e645ebe78f1b2c7938df Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 21 Mar 2018 11:31:45 -0400 Subject: [PATCH] reinstate previous code from before i ballsed it up --- src/shared/keyed-each.js | 69 +++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/src/shared/keyed-each.js b/src/shared/keyed-each.js index 384a96f6ed..40ad3f302c 100644 --- a/src/shared/keyed-each.js +++ b/src/shared/keyed-each.js @@ -20,22 +20,36 @@ export function outroAndDestroyIteration(iteration, lookup) { // TODO is it possible to avoid mounting iterations that are // already in the right place? export function updateKeyedEach(component, key, changed, key_prop, dynamic, list, head, lookup, node, has_outro, create_each_block, intro_method, get_context) { + var expected = head; + var keep = {}; + var mounts = {}; - var i = list.length; - while (i--) { + for (var i = 0; i < list.length; i += 1) { var key = list[i][key_prop]; var iteration = lookup[key]; + var next_data = list[i+1]; + var next = next_data && lookup[next_data[key_prop]]; + + if (dynamic && iteration) iteration.p(changed, get_context(i)); // TODO should this be deferred? could it be redundant? - if (iteration) { - if (dynamic) iteration.p(changed, get_context(i)); + if (expected && (key === expected.key)) { + var first = iteration && iteration.first; + var parentNode = first && first.parentNode + if (!parentNode || (iteration && iteration.next) != next) mounts[key] = iteration; + expected = iteration.next; + } else if (iteration) { + mounts[key] = iteration; + expected = iteration.next; } else { + // key is being inserted iteration = lookup[key] = create_each_block(component, key, get_context(i)); iteration.c(); + mounts[key] = iteration; } - lookup[key] = iteration; - keep[key] = 1; + keep[iteration.key] = iteration; + // last = iteration; } var destroy = has_outro @@ -49,32 +63,35 @@ export function updateKeyedEach(component, key, changed, key_prop, dynamic, list } var next = null; + var next_iteration = null; - i = list.length; - while (i--) { - key = list[i][key_prop]; + for (i = list.length - 1; i >= 0; i -= 1) { + var data = list[i]; + var key = data[key_prop]; iteration = lookup[key]; - var anchor; - - if (has_outro) { - var next_key = next && next.key; - var neighbour = iteration.next; - var anchor_key; + var block = mounts[key]; + if (block) { + var anchor; - while (neighbour && anchor_key != next_key && !keep[anchor_key]) { - anchor = neighbour && neighbour.first; - neighbour = neighbour.next; - anchor_key = neighbour && neighbour.key; + if (has_outro) { + var key_next_iteration = next_iteration && next_iteration.key; + var iteration_anchor = iteration.next; + var key_anchor; + do { + anchor = iteration_anchor && iteration_anchor.first; + iteration_anchor = iteration_anchor && iteration_anchor.next; + key_anchor = iteration_anchor && iteration_anchor.key; + } while(iteration_anchor && key_anchor != key_next_iteration && !keep[key_anchor]) + } else { + anchor = next_iteration && next_iteration.first; } - } else { - anchor = next && next.first; - } - iteration[intro_method](node, anchor); + block[intro_method](node, anchor); + } - iteration.next = next; - if (next) next.last = iteration; - next = iteration; + iteration.next = next_iteration; + if (next_iteration) next_iteration.last = iteration; + next_iteration = iteration; } } \ No newline at end of file