Merge pull request #187 from DioxusLabs/jk/prevent-default-for-real
fix: dioxus web prevents default in nested targets
This commit is contained in:
1 file changed
+47
-53
+47
-53
@@ -28,17 +28,54 @@ impl WebsysDom {
|
|||||||
pub fn new(cfg: WebConfig, sender_callback: Rc<dyn Fn(SchedulerMsg)>) -> Self {
|
pub fn new(cfg: WebConfig, sender_callback: Rc<dyn Fn(SchedulerMsg)>) -> Self {
|
||||||
// eventually, we just want to let the interpreter do all the work of decoding events into our event type
|
// eventually, we just want to let the interpreter do all the work of decoding events into our event type
|
||||||
let callback: Box<dyn FnMut(&Event)> = Box::new(move |event: &web_sys::Event| {
|
let callback: Box<dyn FnMut(&Event)> = Box::new(move |event: &web_sys::Event| {
|
||||||
if let Ok(synthetic_event) = decode_trigger(event) {
|
let mut target = event
|
||||||
|
.target()
|
||||||
|
.expect("missing target")
|
||||||
|
.dyn_into::<Element>()
|
||||||
|
.expect("not a valid element");
|
||||||
|
|
||||||
|
let typ = event.type_();
|
||||||
|
|
||||||
|
let decoded: anyhow::Result<UserEvent> = loop {
|
||||||
|
match target.get_attribute("data-dioxus-id").map(|f| f.parse()) {
|
||||||
|
Some(Ok(id)) => {
|
||||||
|
break Ok(UserEvent {
|
||||||
|
name: event_name_from_typ(&typ),
|
||||||
|
data: virtual_event_from_websys_event(event.clone()),
|
||||||
|
element: Some(ElementId(id)),
|
||||||
|
scope_id: None,
|
||||||
|
priority: dioxus_core::EventPriority::Medium,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Some(Err(e)) => {
|
||||||
|
break Err(e.into());
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
// walk the tree upwards until we actually find an event target
|
||||||
|
if let Some(parent) = target.parent_element() {
|
||||||
|
target = parent;
|
||||||
|
} else {
|
||||||
|
break Ok(UserEvent {
|
||||||
|
name: event_name_from_typ(&typ),
|
||||||
|
data: virtual_event_from_websys_event(event.clone()),
|
||||||
|
element: None,
|
||||||
|
scope_id: None,
|
||||||
|
priority: dioxus_core::EventPriority::Low,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Ok(synthetic_event) = decoded {
|
||||||
// Try to prevent default if the attribute is set
|
// Try to prevent default if the attribute is set
|
||||||
if let Some(target) = event.target() {
|
if let Some(node) = target.dyn_ref::<HtmlElement>() {
|
||||||
if let Some(node) = target.dyn_ref::<HtmlElement>() {
|
if let Some(name) = node.get_attribute("dioxus-prevent-default") {
|
||||||
if let Some(name) = node.get_attribute("dioxus-prevent-default") {
|
if name == synthetic_event.name
|
||||||
if name == synthetic_event.name
|
|| name.trim_start_matches("on") == synthetic_event.name
|
||||||
|| name.trim_start_matches("on") == synthetic_event.name
|
{
|
||||||
{
|
log::trace!("Preventing default");
|
||||||
log::trace!("Preventing default");
|
event.prevent_default();
|
||||||
event.prevent_default();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,49 +311,6 @@ fn virtual_event_from_websys_event(event: web_sys::Event) -> Arc<dyn Any + Send
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function decodes a websys event and produces an EventTrigger
|
|
||||||
/// With the websys implementation, we attach a unique key to the nodes
|
|
||||||
fn decode_trigger(event: &web_sys::Event) -> anyhow::Result<UserEvent> {
|
|
||||||
let mut target = event
|
|
||||||
.target()
|
|
||||||
.expect("missing target")
|
|
||||||
.dyn_into::<Element>()
|
|
||||||
.expect("not a valid element");
|
|
||||||
|
|
||||||
let typ = event.type_();
|
|
||||||
|
|
||||||
loop {
|
|
||||||
match target.get_attribute("data-dioxus-id").map(|f| f.parse()) {
|
|
||||||
Some(Ok(id)) => {
|
|
||||||
return Ok(UserEvent {
|
|
||||||
name: event_name_from_typ(&typ),
|
|
||||||
data: virtual_event_from_websys_event(event.clone()),
|
|
||||||
element: Some(ElementId(id)),
|
|
||||||
scope_id: None,
|
|
||||||
priority: dioxus_core::EventPriority::Medium,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Some(Err(e)) => {
|
|
||||||
return Err(e.into());
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
// walk the tree upwards until we actually find an event target
|
|
||||||
if let Some(parent) = target.parent_element() {
|
|
||||||
target = parent;
|
|
||||||
} else {
|
|
||||||
return Ok(UserEvent {
|
|
||||||
name: event_name_from_typ(&typ),
|
|
||||||
data: virtual_event_from_websys_event(event.clone()),
|
|
||||||
element: None,
|
|
||||||
scope_id: None,
|
|
||||||
priority: dioxus_core::EventPriority::Low,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn load_document() -> Document {
|
pub(crate) fn load_document() -> Document {
|
||||||
web_sys::window()
|
web_sys::window()
|
||||||
.expect("should have access to the Window")
|
.expect("should have access to the Window")
|
||||||
|
|||||||
Reference in new issue
Block a user