Sfoglia il codice sorgente

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 <ealmlof1@stumail.jccc.edu>
Attilio 2 anni fa
parent
commit
c645e1c6aa

+ 1 - 2
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

+ 1 - 1
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}}

+ 11 - 7
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();
             }
 

+ 8 - 4
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);