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
+34
-29
@@ -406,36 +406,44 @@ fn MyComponent() -> Element {{
|
|||||||
name = "VirtualDom::handle_bubbling_event"
|
name = "VirtualDom::handle_bubbling_event"
|
||||||
)]
|
)]
|
||||||
fn handle_bubbling_event(&self, parent: ElementRef, name: &str, uievent: Event<dyn Any>) {
|
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.
|
// 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.
|
// 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);
|
let mut parent = Some(parent);
|
||||||
while let Some(path) = parent {
|
while let Some(path) = parent {
|
||||||
let mut listeners = vec![];
|
let mut listeners = vec![];
|
||||||
|
let mount_id;
|
||||||
|
|
||||||
let Some(mount) = mounts.get(path.mount.0) else {
|
// We do this in its own block to prevent mounts from staying open while we call user code
|
||||||
// If the node is suspended and not mounted, we can just ignore the event
|
{
|
||||||
return;
|
let mounts = self.mounts.borrow();
|
||||||
};
|
let Some(mount) = mounts.get(path.mount.0) else {
|
||||||
let el_ref = &mount.node;
|
// If the node is suspended and not mounted, we can just ignore the event
|
||||||
let node_template = el_ref.template;
|
return;
|
||||||
let target_path = path.path;
|
};
|
||||||
|
|
||||||
// Accumulate listeners into the listener list bottom to top
|
let el_ref = &mount.node;
|
||||||
for (idx, this_path) in node_template.attr_paths.iter().enumerate() {
|
let node_template = el_ref.template;
|
||||||
let attrs = &*el_ref.dynamic_attrs[idx];
|
let target_path = path.path;
|
||||||
|
mount_id = el_ref.mount.get().as_usize();
|
||||||
|
|
||||||
for attr in attrs.iter() {
|
// Accumulate listeners into the listener list bottom to top
|
||||||
// Remove the "on" prefix if it exists, TODO, we should remove this and settle on one
|
for (idx, this_path) in node_template.attr_paths.iter().enumerate() {
|
||||||
if attr.name.get(2..) == Some(name) && target_path.is_descendant(this_path) {
|
let attrs = &*el_ref.dynamic_attrs[idx];
|
||||||
listeners.push(&attr.value);
|
|
||||||
|
|
||||||
// Break if this is the exact target element.
|
for attr in attrs.iter() {
|
||||||
// This means we won't call two listeners with the same name on the same element. This should be
|
// Remove the "on" prefix if it exists, TODO, we should remove this and settle on one
|
||||||
// documented, or be rejected from the rsx! macro outright
|
if attr.name.get(2..) == Some(name) && target_path.is_descendant(this_path)
|
||||||
if target_path == this_path {
|
{
|
||||||
break;
|
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
|
||||||
|
// documented, or be rejected from the rsx! macro outright
|
||||||
|
if target_path == this_path {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -449,18 +457,15 @@ fn MyComponent() -> Element {{
|
|||||||
listeners.len()
|
listeners.len()
|
||||||
);
|
);
|
||||||
for listener in listeners.into_iter().rev() {
|
for listener in listeners.into_iter().rev() {
|
||||||
if let AttributeValue::Listener(listener) = listener {
|
listener.call(uievent.clone());
|
||||||
listener.call(uievent.clone());
|
let metadata = uievent.metadata.borrow();
|
||||||
let metadata = uievent.metadata.borrow();
|
|
||||||
|
|
||||||
if !metadata.propagates {
|
if !metadata.propagates {
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mount = el_ref.mount.get().as_usize();
|
parent = mount_id.and_then(|id| self.mounts.borrow().get(id).and_then(|el| el.parent));
|
||||||
parent = mount.and_then(|id| mounts.get(id).and_then(|el| el.parent));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user