Skip to content

Commit

Permalink
fix: Clicking on label triggers infinite loop
Browse files Browse the repository at this point in the history
  • Loading branch information
luoxiaozero committed Jan 9, 2025
1 parent 3745cf9 commit 1ad85ff
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 4 deletions.
22 changes: 21 additions & 1 deletion packages/blitz-dom/src/events/mouse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,27 @@ pub(crate) fn handle_mousedown(doc: &mut BaseDocument, target: usize, x: f32, y:
}
}

pub(crate) fn handle_click(doc: &mut BaseDocument, _target: usize, x: f32, y: f32) {
pub(crate) fn handle_click(doc: &mut BaseDocument, target: usize, x: f32, y: f32) {
let node = &mut doc.nodes[target];
let Some(el) = node.raw_dom_data.downcast_element_mut() else {
return;
};

let disabled = el.attr(local_name!("disabled")).is_some();
if disabled {
return;
}

if el.name.local == local_name!("input")
&& matches!(el.attr(local_name!("type")), Some("checkbox"))
{
BaseDocument::toggle_checkbox(el);
// doc.set_focus_to(hit.node_id);
// return;
}
}

pub(crate) fn old_handle_click(doc: &mut BaseDocument, _target: usize, x: f32, y: f32) {
let mut maybe_hit = doc.hit(x, y);

while let Some(hit) = maybe_hit {
Expand Down
25 changes: 22 additions & 3 deletions packages/blitz-event/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ impl<Doc: Document<Doc = D>> Event<Doc> {
let chain = self.call_node_chain(node_id, DomEventData::Click(event_data.clone()));

if let Some(chain) = chain {
let element = self.doc.as_ref().tree()[node_id].element_data().unwrap();
let root_input = element.name.local == local_name!("input");

for target in chain.iter() {
let element = self.doc.as_ref().tree()[*target].element_data().unwrap();

Expand All @@ -116,7 +119,7 @@ impl<Doc: Document<Doc = D>> Event<Doc> {

if triggers_input_event {
self.input();
} else if trigger_label {
} else if trigger_label && !root_input {
if let Some(input_id) = self.label_bound_input_element(*target) {
self.click(event_data.clone(), input_id, "left");
}
Expand Down Expand Up @@ -167,8 +170,24 @@ impl<Doc: Document<Doc = D>> Event<Doc> {
fn label_bound_input_element(&self, label_node_id: usize) -> Option<usize> {
let bound_input_elements = self.doc.as_ref().label_bound_input_elements(label_node_id);

// Filter down bound elements to those which have dioxus id
bound_input_elements.into_iter().map(|n| n.id).next()
// Find the first node that is not uninstalled.
let root_node_id = self.doc.as_ref().root_node().id;
bound_input_elements.into_iter().find_map(|n| {
let mut next_node_id = n.id;
loop {
let node = &self.doc.as_ref().tree()[next_node_id];
if let Some(node_id) = node.parent {
next_node_id = node_id;
} else {
break;
}
}
if next_node_id == root_node_id {
Some(n.id)
} else {
None
}
})
}

fn call_node_chain(&mut self, target: usize, event_data: DomEventData) -> Option<Vec<usize>> {
Expand Down

0 comments on commit 1ad85ff

Please sign in to comment.