From c645e1c6aaa44829b38f273d97f5ae274a5671f5 Mon Sep 17 00:00:00 2001 From: Attilio <75045331+attilio-oliva@users.noreply.github.com> Date: Thu, 27 Apr 2023 18:26:04 +0200 Subject: [PATCH] Allow multiple prevent default for Web, Desktop and LiveView (#987) * Allow multiple prevent default in dioxus_web * Use SplitWhitespace for prevent default requests * Add multiple prevent default option to liveview and desktop * Update docs about prevent_default attribute * cargo clippy * update prevent default guide example --------- Co-authored-by: Evan Almloff --- docs/guide/examples/event_prevent_default.rs | 3 +-- .../src/en/interactivity/event_handlers.md | 2 +- packages/interpreter/src/interpreter.js | 18 +++++++++++------- packages/web/src/dom.rs | 12 ++++++++---- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/docs/guide/examples/event_prevent_default.rs b/docs/guide/examples/event_prevent_default.rs index b109700bf..32443d017 100644 --- a/docs/guide/examples/event_prevent_default.rs +++ b/docs/guide/examples/event_prevent_default.rs @@ -10,8 +10,7 @@ fn App(cx: Scope) -> Element { // ANCHOR: prevent_default cx.render(rsx! { input { - prevent_default: "oninput", - prevent_default: "onclick", + prevent_default: "oninput onclick", } }) // ANCHOR_END: prevent_default diff --git a/docs/guide/src/en/interactivity/event_handlers.md b/docs/guide/src/en/interactivity/event_handlers.md index bee0175e2..317038923 100644 --- a/docs/guide/src/en/interactivity/event_handlers.md +++ b/docs/guide/src/en/interactivity/event_handlers.md @@ -41,7 +41,7 @@ If you want to prevent this behavior, you can call `stop_propagation()` on the e Some events have a default behavior. For keyboard events, this might be entering the typed character. For mouse events, this might be selecting some text. -In some instances, might want to avoid this default behavior. For this, you can add the `prevent_default` attribute with the name of the handler whose default behavior you want to stop. This attribute is special: you can attach it multiple times for multiple attributes: +In some instances, might want to avoid this default behavior. For this, you can add the `prevent_default` attribute with the name of the handler whose default behavior you want to stop. This attribute can be used for multiple handlers using their name separated by spaces: ```rust {{#include ../../../examples/event_prevent_default.rs:prevent_default}} diff --git a/packages/interpreter/src/interpreter.js b/packages/interpreter/src/interpreter.js index 9b93ec9e3..d7b74a63e 100644 --- a/packages/interpreter/src/interpreter.js +++ b/packages/interpreter/src/interpreter.js @@ -352,7 +352,7 @@ class Interpreter { let target = event.target; if (target != null) { let realId = target.getAttribute(`data-dioxus-id`); - let shouldPreventDefault = target.getAttribute( + let preventDefaultRequests = target.getAttribute( `dioxus-prevent-default` ); @@ -361,10 +361,14 @@ class Interpreter { let a_element = target.closest("a"); if (a_element != null) { event.preventDefault(); - if ( - shouldPreventDefault !== `onclick` && - a_element.getAttribute(`dioxus-prevent-default`) !== `onclick` - ) { + + let elementShouldPreventDefault = + preventDefaultRequests.includes(`onclick`); + let linkShouldPreventDefault = a_element + .getAttribute(`dioxus-prevent-default`) + .includes(`onclick`); + + if (!elementShouldPreventDefault && !linkShouldPreventDefault) { const href = a_element.getAttribute("href"); if (href !== "" && href !== null && href !== undefined) { window.ipc.postMessage( @@ -390,13 +394,13 @@ class Interpreter { realId = target.getAttribute(`data-dioxus-id`); } - shouldPreventDefault = target.getAttribute( + preventDefaultRequests = target.getAttribute( `dioxus-prevent-default` ); let contents = serialize_event(event); - if (shouldPreventDefault === `on${event.type}`) { + if (preventDefaultRequests.includes(`on${event.type}`)) { event.preventDefault(); } diff --git a/packages/web/src/dom.rs b/packages/web/src/dom.rs index e1e3b6365..20119dd25 100644 --- a/packages/web/src/dom.rs +++ b/packages/web/src/dom.rs @@ -55,13 +55,17 @@ impl WebsysDom { let element = walk_event_for_id(event); let bubbles = dioxus_html::event_bubbles(name.as_str()); if let Some((element, target)) = element { - if target + if let Some(prevent_requests) = target .get_attribute("dioxus-prevent-default") .as_deref() - .map(|f| f.trim_start_matches("on")) - == Some(&name) + .map(|f| f.split_whitespace()) { - event.prevent_default(); + if prevent_requests + .map(|f| f.trim_start_matches("on")) + .any(|f| f == name) + { + event.prevent_default(); + } } let data = virtual_event_from_websys_event(event.clone(), target);