Parcourir la source

fix onclick event

Evan Almloff il y a 2 ans
Parent
commit
f044bb2128

+ 4 - 1
packages/desktop/src/file_upload.rs

@@ -4,7 +4,8 @@ use serde::Deserialize;
 
 #[derive(Debug, Deserialize)]
 pub(crate) struct FileDiologRequest {
-    accept: String,
+    #[serde(default)]
+    accept: Option<String>,
     multiple: bool,
     pub event: String,
     pub target: usize,
@@ -16,6 +17,8 @@ pub(crate) fn get_file_event(request: &FileDiologRequest) -> Vec<PathBuf> {
 
     let filters: Vec<_> = request
         .accept
+        .as_deref()
+        .unwrap_or_default()
         .split(',')
         .filter_map(|s| Filters::from_str(s).ok())
         .collect();

+ 8 - 8
packages/desktop/src/protocol.rs

@@ -15,12 +15,12 @@ fn module_loader(root_name: &str) -> String {
     let inputs = document.querySelectorAll("input");
     for (let input of inputs) {
       if (!input.getAttribute("data-dioxus-file-listener")) {
-        input.setAttribute("data-dioxus-file-listener", true);
-        input.addEventListener("click", (event) => {
-          let target = event.target;
-          // prevent file inputs from opening the file dialog on click
-          const type = target.getAttribute("type");
-          if (type === "file") {
+        // prevent file inputs from opening the file dialog on click
+        const type = input.getAttribute("type");
+        if (type === "file") {
+          input.setAttribute("data-dioxus-file-listener", true);
+          input.addEventListener("click", (event) => {
+            let target = event.target;
             let target_id = find_real_id(target);
             if (target_id !== null) {
               const send = (event_name) => {
@@ -30,8 +30,8 @@ fn module_loader(root_name: &str) -> String {
               send("change&input");
             }
             event.preventDefault();
-          }
-        });
+          });
+        }
       }
     }"#,
     );

+ 20 - 109
packages/interpreter/src/interpreter.js

@@ -346,106 +346,9 @@ class Interpreter {
       case "NewEventListener":
         let bubbles = event_bubbles(edit.name);
 
-        // this handler is only provided on desktop implementations since this
-        // method is not used by the web implementation
-        let handler = (event) => {
-          let target = event.target;
-          if (target != null) {
-            let realId = target.getAttribute(`data-dioxus-id`);
-            let preventDefaultRequests = target.getAttribute(
-              `dioxus-prevent-default`
-            );
-
-            if (event.type === "click") {
-              // todo call prevent default if it's the right type of event
-              let a_element = target.closest("a");
-              if (a_element != null) {
-                event.preventDefault();
-
-                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(
-                      serializeIpcMessage("browser_open", { href })
-                    );
-                  }
-                }
-              }
-
-              // also prevent buttons from submitting
-              if (target.tagName === "BUTTON" && event.type == "submit") {
-                event.preventDefault();
-              }
-            }
-            // walk the tree to find the real element
-            while (realId == null) {
-              // we've reached the root we don't want to send an event
-              if (target.parentElement === null) {
-                return;
-              }
-
-              target = target.parentElement;
-              realId = target.getAttribute(`data-dioxus-id`);
-            }
-
-            preventDefaultRequests = target.getAttribute(
-              `dioxus-prevent-default`
-            );
-
-            let contents = serialize_event(event);
-
-            if (preventDefaultRequests.includes(`on${event.type}`)) {
-              event.preventDefault();
-            }
-
-            if (event.type === "submit") {
-              event.preventDefault();
-            }
-
-            if (
-              target.tagName === "FORM" &&
-              (event.type === "submit" || event.type === "input")
-            ) {
-              for (let x = 0; x < target.elements.length; x++) {
-                let element = target.elements[x];
-                let name = element.getAttribute("name");
-                if (name != null) {
-                  if (element.getAttribute("type") === "checkbox") {
-                    // @ts-ignore
-                    contents.values[name] = element.checked ? "true" : "false";
-                  } else if (element.getAttribute("type") === "radio") {
-                    if (element.checked) {
-                      contents.values[name] = element.value;
-                    }
-                  } else {
-                    // @ts-ignore
-                    contents.values[name] =
-                      element.value ?? element.textContent;
-                  }
-                }
-              }
-            }
-
-            if (realId === null) {
-              return;
-            }
-            window.ipc.postMessage(
-              serializeIpcMessage("user_event", {
-                name: edit.name,
-                element: parseInt(realId),
-                data: contents,
-                bubbles,
-              })
-            );
-          }
-        };
-        this.NewEventListener(edit.name, edit.id, bubbles, handler);
+        this.NewEventListener(edit.name, edit.id, bubbles, (event) => {
+          handler(event, edit.name, bubbles);
+        });
         break;
     }
   }
@@ -456,17 +359,24 @@ class Interpreter {
 function handler(event, name, bubbles) {
   let target = event.target;
   if (target != null) {
-    let shouldPreventDefault = target.getAttribute(`dioxus-prevent-default`);
+    let preventDefaultRequests = target.getAttribute(`dioxus-prevent-default`);
 
     if (event.type === "click") {
-      // Prevent redirects from links
+      // todo call prevent default if it's the right type of event
       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 && preventDefaultRequests.includes(`onclick`);
+        let aElementShouldPreventDefault = a_element.getAttribute(
+          `dioxus-prevent-default`
+        );
+        let linkShouldPreventDefault =
+          aElementShouldPreventDefault &&
+          aElementShouldPreventDefault.includes(`onclick`);
+
+        if (!elementShouldPreventDefault && !linkShouldPreventDefault) {
           const href = a_element.getAttribute("href");
           if (href !== "" && href !== null && href !== undefined) {
             window.ipc.postMessage(
@@ -484,9 +394,10 @@ function handler(event, name, bubbles) {
 
     const realId = find_real_id(target);
 
-    shouldPreventDefault = target.getAttribute(`dioxus-prevent-default`);
-
-    if (shouldPreventDefault === `on${event.type}`) {
+    if (
+      preventDefaultRequests &&
+      preventDefaultRequests.includes(`on${event.type}`)
+    ) {
       event.preventDefault();
     }