Explorar o código

Merge branch 'master' into breaking

Evan Almloff hai 1 ano
pai
achega
d17a04931b

+ 9 - 4
packages/cli/src/builder.rs

@@ -117,8 +117,13 @@ pub fn build(config: &CrateConfig, _: bool, skip_assets: bool) -> Result<BuildRe
     // [2] Establish the output directory structure
     let bindgen_outdir = out_dir.join("assets").join("dioxus");
 
-    let build_profile = if config.custom_profile.is_some() {
-        config.custom_profile.as_ref().unwrap()
+    let build_target = if config.custom_profile.is_some() {
+        let build_profile = config.custom_profile.as_ref().unwrap();
+        if build_profile == "dev" {
+            "debug"
+        } else {
+            build_profile
+        }
     } else if config.release {
         "release"
     } else {
@@ -127,11 +132,11 @@ pub fn build(config: &CrateConfig, _: bool, skip_assets: bool) -> Result<BuildRe
 
     let input_path = match executable {
         ExecutableType::Binary(name) | ExecutableType::Lib(name) => target_dir
-            .join(format!("wasm32-unknown-unknown/{}", build_profile))
+            .join(format!("wasm32-unknown-unknown/{}", build_target))
             .join(format!("{}.wasm", name)),
 
         ExecutableType::Example(name) => target_dir
-            .join(format!("wasm32-unknown-unknown/{}/examples", build_profile))
+            .join(format!("wasm32-unknown-unknown/{}/examples", build_target))
             .join(format!("{}.wasm", name)),
     };
 

+ 15 - 1
packages/desktop/headless_tests/events.rs

@@ -204,13 +204,27 @@ fn app() -> Element {
         r#"new FocusEvent("focusout",{bubbles: true})"#,
     );
 
-    if **received_events == 12 {
+    if **received_events == 13 {
         println!("all events recieved");
         desktop_context.close();
     }
 
     render! {
         div {
+            div {
+                width: "100px",
+                height: "100px",
+                onmounted: move |evt| {
+                    to_owned![received_events];
+                    async move {
+                        let rect = evt.get_client_rect().await.unwrap();
+                        println!("rect: {:?}", rect);
+                        assert_eq!(rect.width(), 100.0);
+                        assert_eq!(rect.height(), 100.0);
+                        received_events.modify(|x| *x + 1)
+                    }
+                }
+            }
             button {
                 id: "button",
                 onclick: move |event| {

+ 2 - 2
packages/liveview/src/pool.rs

@@ -6,7 +6,7 @@ use crate::{
     LiveViewError,
 };
 use dioxus_core::prelude::*;
-use dioxus_html::{EventData, HtmlEvent, MountedData, PlatformEventData};
+use dioxus_html::{EventData, HtmlEvent, PlatformEventData};
 use dioxus_interpreter_js::MutationState;
 use futures_util::{pin_mut, SinkExt, StreamExt};
 use serde::Serialize;
@@ -182,7 +182,7 @@ pub async fn run(mut vdom: VirtualDom, ws: impl LiveViewSocket) -> Result<(), Li
                                         let element = LiveviewElement::new(evt.element, query_engine.clone());
                                         vdom.handle_event(
                                             &evt.name,
-                                            Rc::new(PlatformEventData::new(Box::new(MountedData::new(element)))),
+                                            Rc::new(PlatformEventData::new(Box::new(element))),
                                             evt.element,
                                             evt.bubbles,
                                         );

+ 4 - 0
packages/web/src/dom.rs

@@ -25,6 +25,8 @@ pub struct WebsysDom {
     pub(crate) interpreter: Channel,
     #[cfg(feature = "mounted")]
     pub(crate) event_channel: mpsc::UnboundedSender<UiEvent>,
+    #[cfg(feature = "mounted")]
+    pub(crate) queued_mounted_events: Vec<ElementId>,
 }
 
 pub struct UiEvent {
@@ -109,6 +111,8 @@ impl WebsysDom {
             max_template_id: 0,
             #[cfg(feature = "mounted")]
             event_channel,
+            #[cfg(feature = "mounted")]
+            queued_mounted_events: Default::default(),
         }
     }
 

+ 1 - 1
packages/web/src/eval.rs

@@ -86,7 +86,7 @@ impl WebEvaluator {
 
         Ok(Self {
             dioxus,
-            channel_receiver: channel_receiver,
+            channel_receiver,
             result: RefCell::new(Some(result)),
         })
     }

+ 28 - 3
packages/web/src/event.rs

@@ -410,6 +410,12 @@ impl HasFormData for WebFormData {
             }
         }
 
+        // try to fill in select element values
+        if let Some(select) = self.element.dyn_ref::<web_sys::HtmlSelectElement>() {
+            let options = get_select_data(select);
+            values.insert("options".to_string(), FormValue::VecText(options));
+        }
+
         values
     }
 
@@ -530,16 +536,17 @@ export function get_form_data(form) {
     const formData = new FormData(form);
 
     for (let name of formData.keys()) {
-        const fieldType = target.elements[name].type;
+        const fieldType = form.elements[name].type;
+        console.log(fieldType);
 
         switch (fieldType) {
             case "select-multiple":
-                contents.values[name] = formData.getAll(name);
+                values.set(name, formData.getAll(name));
                 break;
 
             // add cases for fieldTypes that can hold multiple values here
             default:
-                contents.values[name] = formData.get(name);
+                values.set(name, formData.get(name));
                 break;
         }
     }
@@ -550,3 +557,21 @@ export function get_form_data(form) {
 extern "C" {
     fn get_form_data(form: &web_sys::HtmlFormElement) -> js_sys::Map;
 }
+
+// web-sys does not expose the keys api for select data, so we need to manually bind to it
+#[wasm_bindgen(inline_js = r#"
+export function get_select_data(select) {
+    let values = [];
+    for (let i = 0; i < select.options.length; i++) {
+      let option = select.options[i];
+      if (option.selected) {
+        values.push(option.value.toString());
+      }
+    }
+
+    return values;
+}
+"#)]
+extern "C" {
+    fn get_select_data(select: &web_sys::HtmlSelectElement) -> Vec<String>;
+}

+ 18 - 14
packages/web/src/mutations.rs

@@ -4,7 +4,6 @@ use dioxus_core::prelude::*;
 use dioxus_core::WriteMutations;
 use dioxus_core::{AttributeValue, ElementId};
 use dioxus_html::event_bubbles;
-use dioxus_html::MountedData;
 use dioxus_html::PlatformEventData;
 use dioxus_interpreter_js::get_node;
 use dioxus_interpreter_js::minimal_bindings;
@@ -58,22 +57,27 @@ impl WebsysDom {
     }
 
     pub fn flush_edits(&mut self) {
-        self.interpreter.flush()
+        self.interpreter.flush();
+        #[cfg(feature = "mounted")]
+        // Now that we've flushed the edits and the dom nodes exist, we can send the mounted events.
+        {
+            for id in self.queued_mounted_events.drain(..) {
+                let node = get_node(id.0 as u32);
+                if let Some(element) = node.dyn_ref::<web_sys::Element>() {
+                    let _ = self.event_channel.unbounded_send(UiEvent {
+                        name: "mounted".to_string(),
+                        bubbles: false,
+                        element: id,
+                        data: PlatformEventData::new(Box::new(element.clone())),
+                    });
+                }
+            }
+        }
     }
 
     #[cfg(feature = "mounted")]
-    pub(crate) fn send_mount_event(&self, id: ElementId) {
-        let node = get_node(id.0 as u32);
-        if let Some(element) = node.dyn_ref::<web_sys::Element>() {
-            let data: MountedData = element.into();
-            let data = Box::new(data);
-            let _ = self.event_channel.unbounded_send(UiEvent {
-                name: "mounted".to_string(),
-                bubbles: false,
-                element: id,
-                data: PlatformEventData::new(data),
-            });
-        }
+    pub(crate) fn send_mount_event(&mut self, id: ElementId) {
+        self.queued_mounted_events.push(id);
     }
 }
 

+ 6 - 20
playwright-tests/liveview/src/main.rs

@@ -11,29 +11,15 @@ fn app() -> Element {
             "hello axum! {num}"
             button { onclick: move |_| num += 1, "Increment" }
         }
-        svg {
-            circle { cx: 50, cy: 50, r: 40, stroke: "green", fill: "yellow" }
-        }
-        div {
-            class: "raw-attribute-div",
-            "raw-attribute": "raw-attribute-value",
-        }
-        div {
-            class: "hidden-attribute-div",
-            hidden: true,
-        }
+        svg { circle { cx: 50, cy: 50, r: 40, stroke: "green", fill: "yellow" } }
+        div { class: "raw-attribute-div", "raw-attribute": "raw-attribute-value" }
+        div { class: "hidden-attribute-div", hidden: true }
         div {
             class: "dangerous-inner-html-div",
-            dangerous_inner_html: "<p>hello dangerous inner html</p>",
-        }
-        input {
-            value: "hello input",
-        }
-        div {
-            class: "style-div",
-            color: "red",
-            "colored text"
+            dangerous_inner_html: "<p>hello dangerous inner html</p>"
         }
+        input { value: "hello input" }
+        div { class: "style-div", color: "red", "colored text" }
     })
 }
 

+ 16 - 35
playwright-tests/web/src/main.rs

@@ -11,57 +11,38 @@ fn app() -> Element {
     rsx! {
         div {
             "hello axum! {num}"
-            button {
-                class: "increment-button",
-                onclick: move |_| num += 1, "Increment"
-            }
-        }
-        svg {
-            circle { cx: 50, cy: 50, r: 40, stroke: "green", fill: "yellow" }
-        }
-        div {
-            class: "raw-attribute-div",
-            "raw-attribute": "raw-attribute-value",
-        }
-        div {
-            class: "hidden-attribute-div",
-            hidden: true,
+            button { class: "increment-button", onclick: move |_| num += 1, "Increment" }
         }
+        svg { circle { cx: 50, cy: 50, r: 40, stroke: "green", fill: "yellow" } }
+        div { class: "raw-attribute-div", "raw-attribute": "raw-attribute-value" }
+        div { class: "hidden-attribute-div", hidden: true }
         div {
             class: "dangerous-inner-html-div",
-            dangerous_inner_html: "<p>hello dangerous inner html</p>",
-        }
-        input {
-            value: "hello input",
-        }
-        div {
-            class: "style-div",
-            color: "red",
-            "colored text"
+            dangerous_inner_html: "<p>hello dangerous inner html</p>"
         }
+        input { value: "hello input" }
+        div { class: "style-div", color: "red", "colored text" }
         button {
             class: "eval-button",
             onclick: move |_| {
                 let eval = eval_provider(
-                    r#"
-                    window.document.title = 'Hello from Dioxus Eval!';
-                    dioxus.send("returned eval value");
-                "#).unwrap();
+                        r#"
+                            window.document.title = 'Hello from Dioxus Eval!';
+                            dioxus.send("returned eval value");
+                        "#,
+                    )
+                    .unwrap();
                 let setter = eval_result.setter();
                 async move {
-                    // Set the window title
                     let result = eval.recv().await;
                     if let Ok(serde_json::Value::String(string)) = result {
                         setter(string);
                     }
-
-            }},
+                }
+            },
             "Eval"
         }
-        div {
-            class: "eval-result",
-            "{eval_result}"
-        }
+        div { class: "eval-result", "{eval_result}" }
     })
 }