fix: more panic resilience (#5489)
* fix: more panic resilience * fix: panic typos
This commit is contained in:
1 parent
cb5abb48dd
commit
51b0cd3313
1 file changed
+13
-8
@@ -406,21 +406,25 @@ fn MyComponent() -> Element {{
|
||||
name = "VirtualDom::handle_bubbling_event"
|
||||
)]
|
||||
fn handle_bubbling_event(&self, parent: ElementRef, name: &str, uievent: Event<dyn Any>) {
|
||||
let mounts = self.mounts.borrow();
|
||||
|
||||
// If the event bubbles, we traverse through the tree until we find the target element.
|
||||
// Loop through each dynamic attribute (in a depth first order) in this template before moving up to the template's parent.
|
||||
let mut parent = Some(parent);
|
||||
while let Some(path) = parent {
|
||||
let mut listeners = vec![];
|
||||
let mount_id;
|
||||
|
||||
// We do this in its own block to prevent mounts from staying open while we call user code
|
||||
{
|
||||
let mounts = self.mounts.borrow();
|
||||
let Some(mount) = mounts.get(path.mount.0) else {
|
||||
// If the node is suspended and not mounted, we can just ignore the event
|
||||
return;
|
||||
};
|
||||
|
||||
let el_ref = &mount.node;
|
||||
let node_template = el_ref.template;
|
||||
let target_path = path.path;
|
||||
mount_id = el_ref.mount.get().as_usize();
|
||||
|
||||
// Accumulate listeners into the listener list bottom to top
|
||||
for (idx, this_path) in node_template.attr_paths.iter().enumerate() {
|
||||
@@ -428,8 +432,11 @@ fn MyComponent() -> Element {{
|
||||
|
||||
for attr in attrs.iter() {
|
||||
// Remove the "on" prefix if it exists, TODO, we should remove this and settle on one
|
||||
if attr.name.get(2..) == Some(name) && target_path.is_descendant(this_path) {
|
||||
listeners.push(&attr.value);
|
||||
if attr.name.get(2..) == Some(name) && target_path.is_descendant(this_path)
|
||||
{
|
||||
if let AttributeValue::Listener(listener) = &attr.value {
|
||||
listeners.push(listener.clone());
|
||||
}
|
||||
|
||||
// Break if this is the exact target element.
|
||||
// This means we won't call two listeners with the same name on the same element. This should be
|
||||
@@ -440,6 +447,7 @@ fn MyComponent() -> Element {{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we've accumulated all the parent attributes for the target element, call them in reverse order
|
||||
// We check the bubble state between each call to see if the event has been stopped from bubbling
|
||||
@@ -449,7 +457,6 @@ fn MyComponent() -> Element {{
|
||||
listeners.len()
|
||||
);
|
||||
for listener in listeners.into_iter().rev() {
|
||||
if let AttributeValue::Listener(listener) = listener {
|
||||
listener.call(uievent.clone());
|
||||
let metadata = uievent.metadata.borrow();
|
||||
|
||||
@@ -457,10 +464,8 @@ fn MyComponent() -> Element {{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mount = el_ref.mount.get().as_usize();
|
||||
parent = mount.and_then(|id| mounts.get(id).and_then(|el| el.parent));
|
||||
parent = mount_id.and_then(|id| self.mounts.borrow().get(id).and_then(|el| el.parent));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user