Fix mount use after removal/Simplify mounts a bit (#2834)

* remove clone mounted; mounted nodes should never leak into components?

* Remove the mount from vnodes after unmounting them

* Fix use after removal in iterator diffing

* remove logs

* Re-fix keyed list diffing

* Use new.len for diffing keyed lens and remove redundant check

* simplify core list diffing logic a bit

* remove println

* add proper asserts for new tests

---------

Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
Evan AlmloffandJonathan Kelley authored and GitHub committed 2024-08-13 22:47:12 -07:00
1 parent 959ab67624
commit d649b0c54d
13 files changed
+310 -221

No files matched your search

+37 -27
View File
@@ -133,29 +133,17 @@ impl VirtualDom {
let new_middle = &new[left_offset..(new.len() - right_offset)];
debug_assert!(
!((old_middle.len() == new_middle.len()) && old_middle.is_empty()),
"keyed children must have the same number of children"
!old_middle.is_empty(),
"Old middle returned from `diff_keyed_ends` should not be empty"
);
debug_assert!(
!new_middle.is_empty(),
"New middle returned from `diff_keyed_ends` should not be empty"
);
// A few nodes in the middle were removed, just remove the old nodes
if new_middle.is_empty() {
// remove the old elements
self.remove_nodes(to, old_middle, None);
} else if old_middle.is_empty() {
// there were no old elements, so just create the new elements
// we need to find the right "foothold" though - we shouldn't use the "append" at all
if left_offset == 0 {
// insert at the beginning of the old list
let foothold = &old[old.len() - right_offset];
self.create_and_insert_before(to, new_middle, foothold, parent);
} else if right_offset == 0 {
// insert at the end the old list
let foothold = old.last().unwrap();
self.create_and_insert_after(to, new_middle, foothold, parent);
} else {
// inserting in the middle
let foothold = &old[left_offset - 1];
self.create_and_insert_after(to, new_middle, foothold, parent);
}
} else {
self.diff_keyed_middle(to, old_middle, new_middle, parent);
}
@@ -187,14 +175,7 @@ impl VirtualDom {
// If that was all of the old children, then create and append the remaining
// new children and we're finished.
if left_offset == old.len() {
self.create_and_insert_after(to, &new[left_offset..], old.last().unwrap(), parent);
return None;
}
// And if that was all of the new children, then remove all of the remaining
// old children and we're finished.
if left_offset == new.len() {
self.remove_nodes(to, &old[left_offset..], None);
self.create_and_insert_after(to, &new[left_offset..], &new[left_offset - 1], parent);
return None;
}
@@ -209,6 +190,35 @@ impl VirtualDom {
right_offset += 1;
}
// If that was all of the old children, then create and prepend the remaining
// new children and we're finished.
if right_offset == old.len() {
self.create_and_insert_before(
to,
&new[..new.len() - right_offset],
&new[new.len() - right_offset],
parent,
);
return None;
}
// If the right offset + the left offset is the same as the new length, then we just need to remove the old nodes
if right_offset + left_offset == new.len() {
self.remove_nodes(to, &old[left_offset..old.len() - right_offset], None);
return None;
}
// If the right offset + the left offset is the same as the old length, then we just need to add the new nodes
if right_offset + left_offset == old.len() {
self.create_and_insert_before(
to,
&new[left_offset..new.len() - right_offset],
&new[new.len() - right_offset],
parent,
);
return None;
}
Some((left_offset, right_offset))
}