Ver Fonte

Merge pull request #1021 from Demonthos/fix-web-event-bubbling-on-text-nodes

Fix web events starting on a text node
Jon Kelley há 2 anos atrás
pai
commit
7f74927d82
1 ficheiros alterados com 28 adições e 12 exclusões
  1. 28 12
      packages/web/src/dom.rs

+ 28 - 12
packages/web/src/dom.rs

@@ -380,22 +380,38 @@ extern "C" {
 }
 
 fn walk_event_for_id(event: &web_sys::Event) -> Option<(ElementId, web_sys::Element)> {
-    let mut target = event
+    let target = event
         .target()
         .expect("missing target")
-        .dyn_into::<web_sys::Element>()
-        .expect("not a valid element");
+        .dyn_into::<web_sys::Node>()
+        .expect("not a valid node");
+    let mut current_target_element = target.dyn_ref::<web_sys::Element>().cloned();
 
     loop {
-        match target.get_attribute("data-dioxus-id").map(|f| f.parse()) {
-            Some(Ok(id)) => return Some((ElementId(id), target)),
-            Some(Err(_)) => return None,
-
-            // walk the tree upwards until we actually find an event target
-            None => match target.parent_element() {
-                Some(parent) => target = parent,
-                None => return None,
-            },
+        match (
+            current_target_element
+                .as_ref()
+                .and_then(|el| el.get_attribute("data-dioxus-id").map(|f| f.parse())),
+            current_target_element,
+        ) {
+            // This node is an element, and has a dioxus id, so we can stop walking
+            (Some(Ok(id)), Some(target)) => return Some((ElementId(id), target)),
+
+            // Walk the tree upwards until we actually find an event target
+            (None, target_element) => {
+                let parent = match target_element.as_ref() {
+                    Some(el) => el.parent_element(),
+                    // if this is the first node and not an element, we need to get the parent from the target node
+                    None => target.parent_element(),
+                };
+                match parent {
+                    Some(parent) => current_target_element = Some(parent),
+                    _ => return None,
+                }
+            }
+
+            // This node is an element with an invalid dioxus id, give up
+            _ => return None,
         }
     }
 }