codify "platform" into resolution logic, server-fn/fullstack overhaul (#4596)
overhaul dioxus fullstack using a new implementation of server_fn This PR is a complete rewrite of dioxus fullstack designed to improve compatibility with axum and to fix a number of compilation errors based on feature flag unification plumbing through macros.
This commit is contained in:
1 parent
8421c3aef0
commit
f2b1c6d97f
424 files changed
+17284
-6624
No files matched your search
@@ -1,11 +1,13 @@
|
||||
use crate::{WebFileData, WebFileEngine};
|
||||
|
||||
use super::{Synthetic, WebEventExt};
|
||||
use dioxus_html::{
|
||||
geometry::{ClientPoint, ElementPoint, PagePoint, ScreenPoint},
|
||||
input_data::{decode_mouse_button_set, MouseButton},
|
||||
HasDragData, HasFileData, HasMouseData, InteractionElementOffset, InteractionLocation,
|
||||
Modifiers, ModifiersInteraction, PointerInteraction,
|
||||
FileData, HasDragData, HasFileData, HasMouseData, InteractionElementOffset,
|
||||
InteractionLocation, Modifiers, ModifiersInteraction, PointerInteraction,
|
||||
};
|
||||
use web_sys::DragEvent;
|
||||
use web_sys::{DragEvent, FileReader};
|
||||
|
||||
impl InteractionLocation for Synthetic<DragEvent> {
|
||||
fn client_coordinates(&self) -> ClientPoint {
|
||||
@@ -71,31 +73,35 @@ impl HasDragData for Synthetic<DragEvent> {
|
||||
}
|
||||
|
||||
impl HasFileData for Synthetic<DragEvent> {
|
||||
fn files(&self) -> Option<std::sync::Arc<dyn dioxus_html::FileEngine>> {
|
||||
#[cfg(feature = "file_engine")]
|
||||
{
|
||||
use wasm_bindgen::JsCast;
|
||||
let files = self
|
||||
.event
|
||||
.dyn_ref::<web_sys::DragEvent>()
|
||||
.and_then(|drag_event| {
|
||||
drag_event.data_transfer().and_then(|dt| {
|
||||
dt.files().and_then(|files| {
|
||||
#[allow(clippy::arc_with_non_send_sync)]
|
||||
crate::file_engine::WebFileEngine::new(files).map(|f| {
|
||||
std::sync::Arc::new(f)
|
||||
as std::sync::Arc<dyn dioxus_html::FileEngine>
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
||||
fn files(&self) -> Vec<FileData> {
|
||||
use wasm_bindgen::JsCast;
|
||||
|
||||
files
|
||||
}
|
||||
#[cfg(not(feature = "file_engine"))]
|
||||
{
|
||||
None
|
||||
if let Some(target) = self.event.dyn_ref::<web_sys::DragEvent>() {
|
||||
if let Some(data_transfer) = target.data_transfer() {
|
||||
if let Some(file_list) = data_transfer.files() {
|
||||
return WebFileEngine::new(file_list).to_files();
|
||||
} else {
|
||||
let items = data_transfer.items();
|
||||
let mut files = vec![];
|
||||
for i in 0..items.length() {
|
||||
if let Some(item) = items.get(i) {
|
||||
if item.kind() == "file" {
|
||||
if let Ok(Some(file)) = item.get_as_file() {
|
||||
let web_data =
|
||||
WebFileData::new(file, FileReader::new().unwrap());
|
||||
files.push(FileData::new(web_data));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tracing::warn!("DragEvent target was not a DragEvent");
|
||||
}
|
||||
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,30 +1,47 @@
|
||||
use dioxus_html::HasFileData;
|
||||
use dioxus_html::{FileData, HasFileData};
|
||||
use web_sys::FileReader;
|
||||
|
||||
use crate::{WebFileData, WebFileEngine};
|
||||
|
||||
use super::Synthetic;
|
||||
|
||||
impl HasFileData for Synthetic<web_sys::Event> {
|
||||
fn files(&self) -> Option<std::sync::Arc<dyn dioxus_html::FileEngine>> {
|
||||
#[cfg(feature = "file_engine")]
|
||||
{
|
||||
use wasm_bindgen::JsCast;
|
||||
fn files(&self) -> Vec<FileData> {
|
||||
use wasm_bindgen::JsCast;
|
||||
let target = self.event.target();
|
||||
|
||||
let files = self
|
||||
.event
|
||||
.dyn_ref()
|
||||
.and_then(|input: &web_sys::HtmlInputElement| {
|
||||
input.files().and_then(|files| {
|
||||
#[allow(clippy::arc_with_non_send_sync)]
|
||||
crate::file_engine::WebFileEngine::new(files).map(|f| {
|
||||
std::sync::Arc::new(f) as std::sync::Arc<dyn dioxus_html::FileEngine>
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
files
|
||||
}
|
||||
#[cfg(not(feature = "file_engine"))]
|
||||
if let Some(target) = target
|
||||
.clone()
|
||||
.and_then(|t| t.dyn_into::<web_sys::HtmlInputElement>().ok())
|
||||
{
|
||||
None
|
||||
if let Some(file_list) = target.files() {
|
||||
return WebFileEngine::new(file_list).to_files();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(target) = target.and_then(|t| t.dyn_into::<web_sys::DragEvent>().ok()) {
|
||||
if let Some(data_transfer) = target.data_transfer() {
|
||||
if let Some(file_list) = data_transfer.files() {
|
||||
return WebFileEngine::new(file_list).to_files();
|
||||
} else {
|
||||
let items = data_transfer.items();
|
||||
let mut files = vec![];
|
||||
for i in 0..items.length() {
|
||||
if let Some(item) = items.get(i) {
|
||||
if item.kind() == "file" {
|
||||
if let Ok(Some(file)) = item.get_as_file() {
|
||||
let web_data =
|
||||
WebFileData::new(file, FileReader::new().unwrap());
|
||||
files.push(FileData::new(web_data));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::{any::Any, collections::HashMap};
|
||||
|
||||
use dioxus_html::{FormValue, HasFileData, HasFormData};
|
||||
use dioxus_html::{FileData, FormValue, HasFileData, HasFormData};
|
||||
use js_sys::Array;
|
||||
use wasm_bindgen::JsValue;
|
||||
use wasm_bindgen::{prelude::wasm_bindgen, JsCast};
|
||||
@@ -10,7 +10,7 @@ use super::WebEventExt;
|
||||
|
||||
pub(crate) struct WebFormData {
|
||||
element: Element,
|
||||
raw: Event,
|
||||
event: Event,
|
||||
}
|
||||
|
||||
impl WebEventExt for dioxus_html::FormData {
|
||||
@@ -23,8 +23,8 @@ impl WebEventExt for dioxus_html::FormData {
|
||||
}
|
||||
|
||||
impl WebFormData {
|
||||
pub fn new(element: Element, raw: Event) -> Self {
|
||||
Self { element, raw }
|
||||
pub fn new(element: Element, event: Event) -> Self {
|
||||
Self { element, event }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,39 +32,39 @@ impl HasFormData for WebFormData {
|
||||
fn value(&self) -> String {
|
||||
let target = &self.element;
|
||||
target
|
||||
.dyn_ref()
|
||||
.map(|input: &web_sys::HtmlInputElement| {
|
||||
// todo: special case more input types
|
||||
match input.type_().as_str() {
|
||||
"checkbox" => {
|
||||
match input.checked() {
|
||||
true => "true".to_string(),
|
||||
false => "false".to_string(),
|
||||
.dyn_ref()
|
||||
.map(|input: &web_sys::HtmlInputElement| {
|
||||
// todo: special case more input types
|
||||
match input.type_().as_str() {
|
||||
"checkbox" => {
|
||||
match input.checked() {
|
||||
true => "true".to_string(),
|
||||
false => "false".to_string(),
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
input.value()
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
input.value()
|
||||
}
|
||||
}
|
||||
})
|
||||
.or_else(|| {
|
||||
target
|
||||
.dyn_ref()
|
||||
.map(|input: &web_sys::HtmlTextAreaElement| input.value())
|
||||
})
|
||||
// select elements are NOT input events - because - why woudn't they be??
|
||||
.or_else(|| {
|
||||
target
|
||||
.dyn_ref()
|
||||
.map(|input: &web_sys::HtmlSelectElement| input.value())
|
||||
})
|
||||
.or_else(|| {
|
||||
target
|
||||
.dyn_ref::<web_sys::HtmlElement>()
|
||||
.unwrap()
|
||||
.text_content()
|
||||
})
|
||||
.expect("only an InputElement or TextAreaElement or an element with contenteditable=true can have an oninput event listener")
|
||||
})
|
||||
.or_else(|| {
|
||||
target
|
||||
.dyn_ref()
|
||||
.map(|input: &web_sys::HtmlTextAreaElement| input.value())
|
||||
})
|
||||
// select elements are NOT input events - because - why woudn't they be??
|
||||
.or_else(|| {
|
||||
target
|
||||
.dyn_ref()
|
||||
.map(|input: &web_sys::HtmlSelectElement| input.value())
|
||||
})
|
||||
.or_else(|| {
|
||||
target
|
||||
.dyn_ref::<web_sys::HtmlElement>()
|
||||
.unwrap()
|
||||
.text_content()
|
||||
})
|
||||
.expect("only an InputElement or TextAreaElement or an element with contenteditable=true can have an oninput event listener")
|
||||
}
|
||||
|
||||
fn values(&self) -> HashMap<String, FormValue> {
|
||||
@@ -101,32 +101,20 @@ impl HasFormData for WebFormData {
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
&self.raw as &dyn Any
|
||||
&self.event as &dyn Any
|
||||
}
|
||||
}
|
||||
|
||||
impl HasFileData for WebFormData {
|
||||
fn files(&self) -> Option<std::sync::Arc<dyn dioxus_html::FileEngine>> {
|
||||
#[cfg(feature = "file_engine")]
|
||||
{
|
||||
let files = self
|
||||
.element
|
||||
.dyn_ref()
|
||||
.and_then(|input: &web_sys::HtmlInputElement| {
|
||||
input.files().and_then(|files| {
|
||||
#[allow(clippy::arc_with_non_send_sync)]
|
||||
crate::file_engine::WebFileEngine::new(files).map(|f| {
|
||||
std::sync::Arc::new(f) as std::sync::Arc<dyn dioxus_html::FileEngine>
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
files
|
||||
}
|
||||
#[cfg(not(feature = "file_engine"))]
|
||||
{
|
||||
None
|
||||
}
|
||||
fn files(&self) -> Vec<FileData> {
|
||||
use wasm_bindgen::JsCast;
|
||||
self.event
|
||||
.target()
|
||||
.and_then(|t| t.dyn_into::<web_sys::HtmlInputElement>().ok())
|
||||
.and_then(|input| input.files())
|
||||
.map(crate::files::WebFileEngine::new)
|
||||
.map(|engine| engine.to_files())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user