Merge branch 'master' into breaking
This commit is contained in:
commit
d17a04931b
9 files changed
+99
-80
No files matched your search
@@ -117,8 +117,13 @@ pub fn build(config: &CrateConfig, _: bool, skip_assets: bool) -> Result<BuildRe
|
|||||||
// [2] Establish the output directory structure
|
// [2] Establish the output directory structure
|
||||||
let bindgen_outdir = out_dir.join("assets").join("dioxus");
|
let bindgen_outdir = out_dir.join("assets").join("dioxus");
|
||||||
|
|
||||||
let build_profile = if config.custom_profile.is_some() {
|
let build_target = if config.custom_profile.is_some() {
|
||||||
config.custom_profile.as_ref().unwrap()
|
let build_profile = config.custom_profile.as_ref().unwrap();
|
||||||
|
if build_profile == "dev" {
|
||||||
|
"debug"
|
||||||
|
} else {
|
||||||
|
build_profile
|
||||||
|
}
|
||||||
} else if config.release {
|
} else if config.release {
|
||||||
"release"
|
"release"
|
||||||
} else {
|
} else {
|
||||||
@@ -127,11 +132,11 @@ pub fn build(config: &CrateConfig, _: bool, skip_assets: bool) -> Result<BuildRe
|
|||||||
|
|
||||||
let input_path = match executable {
|
let input_path = match executable {
|
||||||
ExecutableType::Binary(name) | ExecutableType::Lib(name) => target_dir
|
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)),
|
.join(format!("{}.wasm", name)),
|
||||||
|
|
||||||
ExecutableType::Example(name) => target_dir
|
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)),
|
.join(format!("{}.wasm", name)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -204,13 +204,27 @@ fn app() -> Element {
|
|||||||
r#"new FocusEvent("focusout",{bubbles: true})"#,
|
r#"new FocusEvent("focusout",{bubbles: true})"#,
|
||||||
);
|
);
|
||||||
|
|
||||||
if **received_events == 12 {
|
if **received_events == 13 {
|
||||||
println!("all events recieved");
|
println!("all events recieved");
|
||||||
desktop_context.close();
|
desktop_context.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
render! {
|
render! {
|
||||||
div {
|
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 {
|
button {
|
||||||
id: "button",
|
id: "button",
|
||||||
onclick: move |event| {
|
onclick: move |event| {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use crate::{
|
|||||||
LiveViewError,
|
LiveViewError,
|
||||||
};
|
};
|
||||||
use dioxus_core::prelude::*;
|
use dioxus_core::prelude::*;
|
||||||
use dioxus_html::{EventData, HtmlEvent, MountedData, PlatformEventData};
|
use dioxus_html::{EventData, HtmlEvent, PlatformEventData};
|
||||||
use dioxus_interpreter_js::MutationState;
|
use dioxus_interpreter_js::MutationState;
|
||||||
use futures_util::{pin_mut, SinkExt, StreamExt};
|
use futures_util::{pin_mut, SinkExt, StreamExt};
|
||||||
use serde::Serialize;
|
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());
|
let element = LiveviewElement::new(evt.element, query_engine.clone());
|
||||||
vdom.handle_event(
|
vdom.handle_event(
|
||||||
&evt.name,
|
&evt.name,
|
||||||
Rc::new(PlatformEventData::new(Box::new(MountedData::new(element)))),
|
Rc::new(PlatformEventData::new(Box::new(element))),
|
||||||
evt.element,
|
evt.element,
|
||||||
evt.bubbles,
|
evt.bubbles,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ pub struct WebsysDom {
|
|||||||
pub(crate) interpreter: Channel,
|
pub(crate) interpreter: Channel,
|
||||||
#[cfg(feature = "mounted")]
|
#[cfg(feature = "mounted")]
|
||||||
pub(crate) event_channel: mpsc::UnboundedSender<UiEvent>,
|
pub(crate) event_channel: mpsc::UnboundedSender<UiEvent>,
|
||||||
|
#[cfg(feature = "mounted")]
|
||||||
|
pub(crate) queued_mounted_events: Vec<ElementId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UiEvent {
|
pub struct UiEvent {
|
||||||
@@ -109,6 +111,8 @@ impl WebsysDom {
|
|||||||
max_template_id: 0,
|
max_template_id: 0,
|
||||||
#[cfg(feature = "mounted")]
|
#[cfg(feature = "mounted")]
|
||||||
event_channel,
|
event_channel,
|
||||||
|
#[cfg(feature = "mounted")]
|
||||||
|
queued_mounted_events: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ impl WebEvaluator {
|
|||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
dioxus,
|
dioxus,
|
||||||
channel_receiver: channel_receiver,
|
channel_receiver,
|
||||||
result: RefCell::new(Some(result)),
|
result: RefCell::new(Some(result)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
values
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -530,16 +536,17 @@ export function get_form_data(form) {
|
|||||||
const formData = new FormData(form);
|
const formData = new FormData(form);
|
||||||
|
|
||||||
for (let name of formData.keys()) {
|
for (let name of formData.keys()) {
|
||||||
const fieldType = target.elements[name].type;
|
const fieldType = form.elements[name].type;
|
||||||
|
console.log(fieldType);
|
||||||
|
|
||||||
switch (fieldType) {
|
switch (fieldType) {
|
||||||
case "select-multiple":
|
case "select-multiple":
|
||||||
contents.values[name] = formData.getAll(name);
|
values.set(name, formData.getAll(name));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// add cases for fieldTypes that can hold multiple values here
|
// add cases for fieldTypes that can hold multiple values here
|
||||||
default:
|
default:
|
||||||
contents.values[name] = formData.get(name);
|
values.set(name, formData.get(name));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -550,3 +557,21 @@ export function get_form_data(form) {
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
fn get_form_data(form: &web_sys::HtmlFormElement) -> js_sys::Map;
|
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>;
|
||||||
|
}
|
||||||
@@ -4,7 +4,6 @@ use dioxus_core::prelude::*;
|
|||||||
use dioxus_core::WriteMutations;
|
use dioxus_core::WriteMutations;
|
||||||
use dioxus_core::{AttributeValue, ElementId};
|
use dioxus_core::{AttributeValue, ElementId};
|
||||||
use dioxus_html::event_bubbles;
|
use dioxus_html::event_bubbles;
|
||||||
use dioxus_html::MountedData;
|
|
||||||
use dioxus_html::PlatformEventData;
|
use dioxus_html::PlatformEventData;
|
||||||
use dioxus_interpreter_js::get_node;
|
use dioxus_interpreter_js::get_node;
|
||||||
use dioxus_interpreter_js::minimal_bindings;
|
use dioxus_interpreter_js::minimal_bindings;
|
||||||
@@ -58,22 +57,27 @@ impl WebsysDom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn flush_edits(&mut self) {
|
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")]
|
#[cfg(feature = "mounted")]
|
||||||
pub(crate) fn send_mount_event(&self, id: ElementId) {
|
pub(crate) fn send_mount_event(&mut self, id: ElementId) {
|
||||||
let node = get_node(id.0 as u32);
|
self.queued_mounted_events.push(id);
|
||||||
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),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,29 +11,15 @@ fn app() -> Element {
|
|||||||
"hello axum! {num}"
|
"hello axum! {num}"
|
||||||
button { onclick: move |_| num += 1, "Increment" }
|
button { onclick: move |_| num += 1, "Increment" }
|
||||||
}
|
}
|
||||||
svg {
|
svg { circle { cx: 50, cy: 50, r: 40, stroke: "green", fill: "yellow" } }
|
||||||
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: "raw-attribute-div",
|
|
||||||
"raw-attribute": "raw-attribute-value",
|
|
||||||
}
|
|
||||||
div {
|
|
||||||
class: "hidden-attribute-div",
|
|
||||||
hidden: true,
|
|
||||||
}
|
|
||||||
div {
|
div {
|
||||||
class: "dangerous-inner-html-div",
|
class: "dangerous-inner-html-div",
|
||||||
dangerous_inner_html: "<p>hello dangerous inner html</p>",
|
dangerous_inner_html: "<p>hello dangerous inner html</p>"
|
||||||
}
|
|
||||||
input {
|
|
||||||
value: "hello input",
|
|
||||||
}
|
|
||||||
div {
|
|
||||||
class: "style-div",
|
|
||||||
color: "red",
|
|
||||||
"colored text"
|
|
||||||
}
|
}
|
||||||
|
input { value: "hello input" }
|
||||||
|
div { class: "style-div", color: "red", "colored text" }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,57 +11,38 @@ fn app() -> Element {
|
|||||||
rsx! {
|
rsx! {
|
||||||
div {
|
div {
|
||||||
"hello axum! {num}"
|
"hello axum! {num}"
|
||||||
button {
|
button { class: "increment-button", onclick: move |_| num += 1, "Increment" }
|
||||||
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,
|
|
||||||
}
|
}
|
||||||
|
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 {
|
div {
|
||||||
class: "dangerous-inner-html-div",
|
class: "dangerous-inner-html-div",
|
||||||
dangerous_inner_html: "<p>hello dangerous inner html</p>",
|
dangerous_inner_html: "<p>hello dangerous inner html</p>"
|
||||||
}
|
|
||||||
input {
|
|
||||||
value: "hello input",
|
|
||||||
}
|
|
||||||
div {
|
|
||||||
class: "style-div",
|
|
||||||
color: "red",
|
|
||||||
"colored text"
|
|
||||||
}
|
}
|
||||||
|
input { value: "hello input" }
|
||||||
|
div { class: "style-div", color: "red", "colored text" }
|
||||||
button {
|
button {
|
||||||
class: "eval-button",
|
class: "eval-button",
|
||||||
onclick: move |_| {
|
onclick: move |_| {
|
||||||
let eval = eval_provider(
|
let eval = eval_provider(
|
||||||
r#"
|
r#"
|
||||||
window.document.title = 'Hello from Dioxus Eval!';
|
window.document.title = 'Hello from Dioxus Eval!';
|
||||||
dioxus.send("returned eval value");
|
dioxus.send("returned eval value");
|
||||||
"#).unwrap();
|
"#,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
let setter = eval_result.setter();
|
let setter = eval_result.setter();
|
||||||
async move {
|
async move {
|
||||||
// Set the window title
|
|
||||||
let result = eval.recv().await;
|
let result = eval.recv().await;
|
||||||
if let Ok(serde_json::Value::String(string)) = result {
|
if let Ok(serde_json::Value::String(string)) = result {
|
||||||
setter(string);
|
setter(string);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}},
|
},
|
||||||
"Eval"
|
"Eval"
|
||||||
}
|
}
|
||||||
div {
|
div { class: "eval-result", "{eval_result}" }
|
||||||
class: "eval-result",
|
|
||||||
"{eval_result}"
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user