mirror of
https://github.com/DioxusLabs/dioxus
synced 2025-02-16 13:48:26 +00:00
Merge pull request #48 from DioxusLabs/jk/release
feat: more API updates
This commit is contained in:
commit
f24aae8787
17 changed files with 227 additions and 189 deletions
14
README.md
14
README.md
|
@ -49,7 +49,7 @@
|
|||
Dioxus is a portable, performant, and ergonomic framework for building cross-platform user experiences in Rust.
|
||||
|
||||
```rust
|
||||
fn app(cx: Scope<()>) -> Element {
|
||||
fn app(cx: Scope) -> Element {
|
||||
let mut count = use_state(&cx, || 0);
|
||||
|
||||
cx.render(rsx!(
|
||||
|
@ -85,18 +85,6 @@ If you know React, then you already know Dioxus.
|
|||
<tr>
|
||||
</table>
|
||||
|
||||
Available cargo features:
|
||||
- default: core (macro, hooks, html)
|
||||
- macro: support for `Props` and `rsx` macros
|
||||
- hooks: foundational hooks like `use_state`, `use_ref`, etc.
|
||||
- html: the entire namespace of `html` elements, their listeners, and attributes
|
||||
- router: a cross-platform (web and desktop) solution for global app routing
|
||||
- liveview: a threadpool to spawn new VirtualDoms and their handles in
|
||||
- ssr: render the virtualdom to a string
|
||||
- web: render the your app on the web
|
||||
- desktop: render your app locally rendered with webview
|
||||
- mobile: render your app on your device rendered with webview
|
||||
|
||||
## Examples:
|
||||
|
||||
| File Navigator (Desktop) | Bluetooth scanner (Desktop) | TodoMVC (All platforms) | Tailwind (Liveview) |
|
||||
|
|
|
@ -4,19 +4,19 @@ fn main() {}
|
|||
|
||||
type Element<'a> = ();
|
||||
|
||||
pub struct Scope<'a, T> {
|
||||
pub struct Scope<'a, T = ()> {
|
||||
props: &'a T,
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
pub fn component(
|
||||
cx: Scope,
|
||||
// #[inline_props]
|
||||
pub fn component<'a>(
|
||||
cx: Scope<'a>,
|
||||
chkk: String,
|
||||
chkk2: String,
|
||||
r: u32,
|
||||
cat: &'a str,
|
||||
drd: String,
|
||||
e: String,
|
||||
) -> Element {
|
||||
) -> Element<'a> {
|
||||
let r = chkk.len();
|
||||
}
|
||||
|
|
|
@ -92,13 +92,19 @@ impl ToTokens for InlinePropsBody {
|
|||
quote! { #[derive(Props)] }
|
||||
};
|
||||
|
||||
let lifetime = if generics.params.is_empty() {
|
||||
quote! {}
|
||||
} else {
|
||||
quote! { 'a, }
|
||||
};
|
||||
|
||||
out_tokens.append_all(quote! {
|
||||
#modifiers
|
||||
#vis struct #struct_name #generics {
|
||||
#(#fields),*
|
||||
}
|
||||
|
||||
#vis fn #ident #generics (#cx_token: Scope<'a, #struct_name #generics>) #output {
|
||||
#vis fn #ident #generics (#cx_token: Scope<#lifetime #struct_name #generics>) #output {
|
||||
let #struct_name { #(#field_names),* } = &cx.props;
|
||||
#block
|
||||
}
|
||||
|
|
|
@ -226,7 +226,7 @@ pub fn routable_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStrea
|
|||
/// # Example
|
||||
/// ```
|
||||
/// #[inline_props]
|
||||
/// fn app(cx: Scope<{ bob: String }>) -> Element {
|
||||
/// fn app(cx: Scope, bob: String) -> Element {
|
||||
/// cx.render(rsx!("hello, {bob}"))
|
||||
/// }
|
||||
///
|
||||
|
|
|
@ -609,7 +609,7 @@ impl ScopeState {
|
|||
///
|
||||
/// This is a "fundamental" operation and should only be called during initialization of a hook.
|
||||
///
|
||||
/// For a hook that provides the same functionality, use `use_provide_state` and `use_consume_state` instead.
|
||||
/// For a hook that provides the same functionality, use `use_provide_context` and `use_consume_context` instead.
|
||||
///
|
||||
/// When the component is dropped, so is the context. Be aware of this behavior when consuming
|
||||
/// the context via Rc/Weak.
|
||||
|
@ -620,7 +620,7 @@ impl ScopeState {
|
|||
/// struct SharedState(&'static str);
|
||||
///
|
||||
/// static App: Component<()> = |cx, props|{
|
||||
/// cx.use_hook(|_| cx.provide_state(SharedState("world")), |_| {}, |_| {});
|
||||
/// cx.use_hook(|_| cx.provide_context(SharedState("world")), |_| {}, |_| {});
|
||||
/// rsx!(cx, Child {})
|
||||
/// }
|
||||
///
|
||||
|
@ -629,7 +629,7 @@ impl ScopeState {
|
|||
/// rsx!(cx, div { "hello {state.0}" })
|
||||
/// }
|
||||
/// ```
|
||||
pub fn provide_state<T: 'static>(&self, value: T) {
|
||||
pub fn provide_context<T: 'static>(&self, value: T) {
|
||||
self.shared_contexts
|
||||
.borrow_mut()
|
||||
.insert(TypeId::of::<T>(), Rc::new(value))
|
||||
|
@ -638,7 +638,7 @@ impl ScopeState {
|
|||
}
|
||||
|
||||
/// Try to retrieve a SharedState with type T from the any parent Scope.
|
||||
pub fn consume_state<T: 'static>(&self) -> Option<Rc<T>> {
|
||||
pub fn consume_context<T: 'static>(&self) -> Option<Rc<T>> {
|
||||
if let Some(shared) = self.shared_contexts.borrow().get(&TypeId::of::<T>()) {
|
||||
Some(shared.clone().downcast::<T>().unwrap())
|
||||
} else {
|
||||
|
|
|
@ -14,12 +14,12 @@ fn shared_state_test() {
|
|||
struct MySharedState(&'static str);
|
||||
|
||||
static App: Component<()> = |cx| {
|
||||
cx.provide_state(MySharedState("world!"));
|
||||
cx.provide_context(MySharedState("world!"));
|
||||
cx.render(rsx!(Child {}))
|
||||
};
|
||||
|
||||
static Child: Component<()> = |cx| {
|
||||
let shared = cx.consume_state::<MySharedState>()?;
|
||||
let shared = cx.consume_context::<MySharedState>()?;
|
||||
cx.render(rsx!("Hello, {shared.0}"))
|
||||
};
|
||||
|
||||
|
|
|
@ -1,29 +1,30 @@
|
|||
//! Example: README.md showcase
|
||||
//!
|
||||
//! The example from the README.md.
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_core as dioxus;
|
||||
use dioxus_core_macro::*;
|
||||
use dioxus_hooks::*;
|
||||
use dioxus_html as dioxus_elements;
|
||||
use std::time::Duration;
|
||||
|
||||
fn main() {
|
||||
// simple_logger::init().unwrap();
|
||||
dioxus_desktop::launch(app);
|
||||
}
|
||||
|
||||
fn app(cx: Scope<()>) -> Element {
|
||||
let mut count = use_state(&cx, || 0);
|
||||
log::debug!("count is {:?}", count);
|
||||
let count = use_state(&cx, || 0);
|
||||
|
||||
cx.push_future(|| async move {
|
||||
tokio::time::sleep(Duration::from_millis(1000)).await;
|
||||
println!("count is now {:?}", count);
|
||||
count += 1;
|
||||
});
|
||||
// push the futureo on initialization
|
||||
cx.use_hook(
|
||||
|_| {
|
||||
cx.push_future({
|
||||
let count = count.for_async();
|
||||
async move {
|
||||
tokio::time::sleep(Duration::from_millis(1000)).await;
|
||||
*count.get_mut() += 1;
|
||||
}
|
||||
});
|
||||
},
|
||||
|_| {},
|
||||
);
|
||||
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
|
|
|
@ -59,11 +59,11 @@ impl<T> ProvidedStateInner<T> {
|
|||
///
|
||||
///
|
||||
///
|
||||
pub fn use_shared_state<'a, T: 'static>(cx: &'a ScopeState) -> Option<UseSharedState<'a, T>> {
|
||||
pub fn use_context<'a, T: 'static>(cx: &'a ScopeState) -> Option<UseSharedState<'a, T>> {
|
||||
cx.use_hook(
|
||||
|_| {
|
||||
let scope_id = cx.scope_id();
|
||||
let root = cx.consume_state::<ProvidedState<T>>();
|
||||
let root = cx.consume_context::<ProvidedState<T>>();
|
||||
|
||||
if let Some(root) = root.as_ref() {
|
||||
root.borrow_mut().consumers.insert(scope_id);
|
||||
|
@ -175,7 +175,7 @@ where
|
|||
///
|
||||
///
|
||||
///
|
||||
pub fn use_provide_state<'a, T: 'static>(cx: &'a ScopeState, f: impl FnOnce() -> T) {
|
||||
pub fn use_context_provider<'a, T: 'static>(cx: &'a ScopeState, f: impl FnOnce() -> T) {
|
||||
cx.use_hook(
|
||||
|_| {
|
||||
let state: ProvidedState<T> = RefCell::new(ProvidedStateInner {
|
||||
|
@ -183,7 +183,7 @@ pub fn use_provide_state<'a, T: 'static>(cx: &'a ScopeState, f: impl FnOnce() ->
|
|||
notify_any: cx.schedule_update_any(),
|
||||
consumers: HashSet::new(),
|
||||
});
|
||||
cx.provide_state(state)
|
||||
cx.provide_context(state)
|
||||
},
|
||||
|_inner| {},
|
||||
)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -2,6 +2,7 @@ use dioxus_core::prelude::*;
|
|||
use dioxus_core_macro::*;
|
||||
use dioxus_html as dioxus_elements;
|
||||
use dioxus_router::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
fn main() {
|
||||
console_error_panic_hook::set_once();
|
||||
|
@ -10,18 +11,19 @@ fn main() {
|
|||
}
|
||||
|
||||
static APP: Component<()> = |cx| {
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
enum Route {
|
||||
Home,
|
||||
About,
|
||||
NotFound,
|
||||
}
|
||||
impl Default for Route {
|
||||
fn default() -> Self {
|
||||
Route::Home
|
||||
}
|
||||
}
|
||||
|
||||
let route = use_router(&cx, |s| match s {
|
||||
"/" => Route::Home,
|
||||
"/about" => Route::About,
|
||||
_ => Route::NotFound,
|
||||
});
|
||||
let route = use_router(&cx, |c| {});
|
||||
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
|
@ -31,8 +33,8 @@ static APP: Component<()> = |cx| {
|
|||
Route::NotFound => rsx!(h1 { "NotFound" }),
|
||||
}}
|
||||
nav {
|
||||
Link { to: Route::Home, href: |_| "/".to_string() }
|
||||
Link { to: Route::About, href: |_| "/about".to_string() }
|
||||
Link { to: Route::Home, href: "/" }
|
||||
Link { to: Route::About, href: "/about" }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,72 +1,56 @@
|
|||
//! Dioxus-Router
|
||||
//!
|
||||
//! A simple match-based router and router service for most routing needs.
|
||||
//!
|
||||
//! Dioxus-Router is not a *declarative* router. Instead it uses a simple parse-match
|
||||
//! pattern which can be derived via a macro.
|
||||
//!
|
||||
//! ```rust
|
||||
//! fn app(cx: Scope) -> Element {
|
||||
//! let route = use_router(&cx, |svc, path| {
|
||||
//! match path {
|
||||
//! "/about" => Route::About,
|
||||
//! _ => Route::Home,
|
||||
//! }
|
||||
//! });
|
||||
//!
|
||||
//! match route {
|
||||
//! Route::Home => rsx!(cx, h1 { "Home" }),
|
||||
//! Route::About => rsx!(cx, h1 { "About" }),
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
|
||||
mod link;
|
||||
mod platform;
|
||||
mod service;
|
||||
mod userouter;
|
||||
mod utils;
|
||||
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
pub use link::*;
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
pub use service::*;
|
||||
pub use userouter::*;
|
||||
|
||||
use dioxus::Attribute;
|
||||
use dioxus_core as dioxus;
|
||||
|
||||
use dioxus_core::prelude::*;
|
||||
use dioxus_core_macro::{format_args_f, rsx, Props};
|
||||
use dioxus_html as dioxus_elements;
|
||||
// use wasm_bindgen::{JsCast, JsValue};
|
||||
|
||||
use crate::utils::strip_slash_suffix;
|
||||
|
||||
/// Initialize the app's router service and provide access to `Link` components
|
||||
pub fn use_router<R: 'static>(cx: &ScopeState, f: impl Fn(&str) -> R) -> &R {
|
||||
let r = f("/");
|
||||
cx.use_hook(
|
||||
|_| {
|
||||
//
|
||||
r
|
||||
},
|
||||
|f| f,
|
||||
)
|
||||
pub trait Routable:
|
||||
'static + Send + Clone + PartialEq + Serialize + DeserializeOwned + Default
|
||||
{
|
||||
}
|
||||
|
||||
pub trait Routable: 'static + Send + Clone + PartialEq {}
|
||||
impl<T> Routable for T where T: 'static + Send + Clone + PartialEq {}
|
||||
|
||||
#[derive(Props)]
|
||||
pub struct LinkProps<'a, R: Routable> {
|
||||
to: R,
|
||||
|
||||
/// The url that gets pushed to the history stack
|
||||
///
|
||||
/// You can either put it your own inline method or just autoderive the route using `derive(Routable)`
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// Link { to: Route::Home, href: |_| "home".to_string() }
|
||||
///
|
||||
/// // or
|
||||
///
|
||||
/// Link { to: Route::Home, href: Route::as_url }
|
||||
///
|
||||
/// ```
|
||||
#[props(default, setter(strip_option))]
|
||||
href: Option<&'a str>,
|
||||
|
||||
#[props(default, setter(strip_option))]
|
||||
class: Option<&'a str>,
|
||||
|
||||
children: Element<'a>,
|
||||
|
||||
#[props(default)]
|
||||
attributes: Option<&'a [Attribute<'a>]>,
|
||||
}
|
||||
|
||||
pub fn Link<'a, R: Routable>(cx: Scope<'a, LinkProps<'a, R>>) -> Element {
|
||||
// let service = todo!();
|
||||
// let service: todo!() = use_router_service::<R>(&cx)?;
|
||||
let class = cx.props.class.unwrap_or("");
|
||||
cx.render(rsx! {
|
||||
a {
|
||||
href: "#",
|
||||
class: "{class}",
|
||||
{&cx.props.children}
|
||||
// onclick: move |_| service.push_route(cx.props.to.clone()),
|
||||
// href: format_args!("{}", (cx.props.href)(&cx.props.to)),
|
||||
}
|
||||
})
|
||||
impl<T> Routable for T where
|
||||
T: 'static + Send + Clone + PartialEq + Serialize + DeserializeOwned + Default
|
||||
{
|
||||
}
|
||||
|
|
48
packages/router/src/link.rs
Normal file
48
packages/router/src/link.rs
Normal file
|
@ -0,0 +1,48 @@
|
|||
use crate::{Routable, RouterService};
|
||||
use dioxus::Attribute;
|
||||
use dioxus_core as dioxus;
|
||||
use dioxus_core::prelude::*;
|
||||
use dioxus_core_macro::{format_args_f, rsx, Props};
|
||||
use dioxus_html as dioxus_elements;
|
||||
|
||||
#[derive(Props)]
|
||||
pub struct LinkProps<'a, R: Routable> {
|
||||
to: R,
|
||||
|
||||
/// The url that gets pushed to the history stack
|
||||
///
|
||||
/// You can either put it your own inline method or just autoderive the route using `derive(Routable)`
|
||||
///
|
||||
/// ```rust
|
||||
///
|
||||
/// Link { to: Route::Home, href: |_| "home".to_string() }
|
||||
///
|
||||
/// // or
|
||||
///
|
||||
/// Link { to: Route::Home, href: Route::as_url }
|
||||
///
|
||||
/// ```
|
||||
#[props(default, setter(strip_option))]
|
||||
href: Option<&'a str>,
|
||||
|
||||
#[props(default, setter(strip_option))]
|
||||
class: Option<&'a str>,
|
||||
|
||||
children: Element<'a>,
|
||||
|
||||
#[props(default)]
|
||||
attributes: Option<&'a [Attribute<'a>]>,
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Link<'a, R: Routable>(cx: Scope<'a, LinkProps<'a, R>>) -> Element {
|
||||
let service = cx.consume_context::<RouterService<R>>()?;
|
||||
cx.render(rsx! {
|
||||
a {
|
||||
href: "#",
|
||||
class: format_args!("{}", cx.props.class.unwrap_or("")),
|
||||
{&cx.props.children}
|
||||
onclick: move |_| service.push_route(cx.props.to.clone()),
|
||||
}
|
||||
})
|
||||
}
|
|
@ -1 +1,7 @@
|
|||
pub fn parse_current_route() -> String {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub(crate) fn get_base_route() -> String {
|
||||
todo!()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
use crate::Routable;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
pub struct RouterService<R: Routable> {
|
||||
pub(crate) regen_route: Rc<dyn Fn()>,
|
||||
pub(crate) pending_routes: RefCell<Vec<R>>,
|
||||
}
|
||||
|
||||
impl<R: Routable> RouterService<R> {
|
||||
pub fn current_path(&self) -> &str {
|
||||
todo!()
|
||||
}
|
||||
pub fn push_route(&self, route: R) {
|
||||
self.pending_routes.borrow_mut().push(route);
|
||||
(self.regen_route)();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RouterCfg {
|
||||
initial_route: String,
|
||||
}
|
||||
|
||||
impl RouterCfg {
|
||||
pub fn new(initial_route: String) -> Self {
|
||||
Self { initial_route }
|
||||
}
|
||||
}
|
36
packages/router/src/userouter.rs
Normal file
36
packages/router/src/userouter.rs
Normal file
|
@ -0,0 +1,36 @@
|
|||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use crate::{Routable, RouterCfg, RouterService};
|
||||
use dioxus_core::ScopeState;
|
||||
|
||||
/// Initialize the app's router service and provide access to `Link` components
|
||||
pub fn use_router<'a, R: Routable>(cx: &'a ScopeState, cfg: impl FnOnce(&mut RouterCfg)) -> &'a R {
|
||||
cx.use_hook(
|
||||
|_| {
|
||||
let svc: RouterService<R> = RouterService {
|
||||
regen_route: cx.schedule_update(),
|
||||
pending_routes: RefCell::new(Vec::new()),
|
||||
};
|
||||
let first_path = R::default();
|
||||
cx.provide_context(svc);
|
||||
UseRouterInner {
|
||||
svc: cx.consume_context::<RouterService<R>>().unwrap(),
|
||||
history: vec![first_path],
|
||||
}
|
||||
},
|
||||
|f| {
|
||||
let mut pending_routes = f.svc.pending_routes.borrow_mut();
|
||||
|
||||
for route in pending_routes.drain(..) {
|
||||
f.history.push(route);
|
||||
}
|
||||
|
||||
f.history.last().unwrap()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
struct UseRouterInner<R: Routable> {
|
||||
svc: Rc<RouterService<R>>,
|
||||
history: Vec<R>,
|
||||
}
|
|
@ -144,7 +144,7 @@ static App: Component<()> = |cx| {
|
|||
{items.read().iter().enumerate().map(|(id, item)| {
|
||||
let [adj, col, noun] = item.labels;
|
||||
let is_in_danger = if (*selected).map(|s| s == id).unwrap_or(false) {"danger"} else {""};
|
||||
rsx!(tr {
|
||||
rsx!(tr {
|
||||
class: "{is_in_danger}",
|
||||
key: "{id}",
|
||||
td { class:"col-md-1" }
|
||||
|
|
|
@ -246,7 +246,6 @@ impl WebsysDom {
|
|||
.unwrap(),
|
||||
};
|
||||
|
||||
use smallstr;
|
||||
use smallstr::SmallString;
|
||||
use std::fmt::Write;
|
||||
|
||||
|
@ -260,7 +259,7 @@ impl WebsysDom {
|
|||
self.nodes[(id as usize)] = Some(el);
|
||||
}
|
||||
|
||||
fn new_event_listener(&mut self, event: &'static str, scope: ScopeId, real_id: u64) {
|
||||
fn new_event_listener(&mut self, event: &'static str, _scope: ScopeId, _real_id: u64) {
|
||||
let event = wasm_bindgen::intern(event);
|
||||
|
||||
// attach the correct attributes to the element
|
||||
|
@ -271,24 +270,9 @@ impl WebsysDom {
|
|||
let el = self.stack.top();
|
||||
|
||||
let el = el.dyn_ref::<Element>().unwrap();
|
||||
// let el = el.dyn_ref::<Element>().unwrap();
|
||||
// .expect(&format!("not an element: {:?}", el));
|
||||
|
||||
// let scope_id = scope.data().as_ffi();
|
||||
// let scope_id = scope.0 as u64;
|
||||
// "dioxus-event-click",
|
||||
// "1.10"
|
||||
// &format!("", scope_id, real_id),
|
||||
// &format!("dioxus-event-{}", event),
|
||||
// &format!("{}.{}", scope_id, real_id),
|
||||
// &format!("dioxus-event-{}", event),
|
||||
// &format!("{}.{}", scope_id, real_id),
|
||||
|
||||
el.set_attribute("dioxus-event", event).unwrap();
|
||||
|
||||
// el.set_attribute(&format!("dioxus-event"), &format!("{}", event))
|
||||
// .unwrap();
|
||||
|
||||
// Register the callback to decode
|
||||
|
||||
if let Some(entry) = self.listeners.get_mut(event) {
|
||||
|
@ -487,20 +471,17 @@ impl Stack {
|
|||
}
|
||||
|
||||
pub struct DioxusWebsysEvent(web_sys::Event);
|
||||
|
||||
// safety: currently the web is not multithreaded and our VirtualDom exists on the same thread
|
||||
unsafe impl Send for DioxusWebsysEvent {}
|
||||
unsafe impl Sync for DioxusWebsysEvent {}
|
||||
|
||||
// trait MyTrait {}
|
||||
// impl MyTrait for web_sys::Event {}
|
||||
|
||||
// todo: some of these events are being casted to the wrong event type.
|
||||
// We need tests that simulate clicks/etc and make sure every event type works.
|
||||
fn virtual_event_from_websys_event(event: web_sys::Event) -> Arc<dyn Any + Send + Sync> {
|
||||
use dioxus_html::on::*;
|
||||
use dioxus_html::KeyCode;
|
||||
// event.prevent_default();
|
||||
|
||||
// use dioxus_core::events::on::*;
|
||||
match event.type_().as_str() {
|
||||
"copy" | "cut" | "paste" => Arc::new(ClipboardEvent {}),
|
||||
"compositionend" | "compositionstart" | "compositionupdate" => {
|
||||
|
@ -525,11 +506,7 @@ fn virtual_event_from_websys_event(event: web_sys::Event) -> Arc<dyn Any + Send
|
|||
which: evt.which() as usize,
|
||||
})
|
||||
}
|
||||
"focus" | "blur" => {
|
||||
//
|
||||
Arc::new(FocusEvent {})
|
||||
}
|
||||
// "change" => SyntheticEvent::GenericEvent(DioxusEvent::new((), DioxusWebsysEvent(event))),
|
||||
"focus" | "blur" => Arc::new(FocusEvent {}),
|
||||
|
||||
// todo: these handlers might get really slow if the input box gets large and allocation pressure is heavy
|
||||
// don't have a good solution with the serialized event problem
|
||||
|
@ -623,7 +600,6 @@ fn virtual_event_from_websys_event(event: web_sys::Event) -> Arc<dyn Any + Send
|
|||
})
|
||||
}
|
||||
"select" => Arc::new(SelectionEvent {}),
|
||||
|
||||
"touchcancel" | "touchend" | "touchmove" | "touchstart" => {
|
||||
let evt: &web_sys::TouchEvent = event.dyn_ref().unwrap();
|
||||
Arc::new(TouchEvent {
|
||||
|
@ -633,9 +609,7 @@ fn virtual_event_from_websys_event(event: web_sys::Event) -> Arc<dyn Any + Send
|
|||
shift_key: evt.shift_key(),
|
||||
})
|
||||
}
|
||||
|
||||
"scroll" => Arc::new(()),
|
||||
|
||||
"wheel" => {
|
||||
let evt: &web_sys::WheelEvent = event.dyn_ref().unwrap();
|
||||
Arc::new(WheelEvent {
|
||||
|
@ -645,7 +619,6 @@ fn virtual_event_from_websys_event(event: web_sys::Event) -> Arc<dyn Any + Send
|
|||
delta_mode: evt.delta_mode(),
|
||||
})
|
||||
}
|
||||
|
||||
"animationstart" | "animationend" | "animationiteration" => {
|
||||
let evt: &web_sys::AnimationEvent = event.dyn_ref().unwrap();
|
||||
Arc::new(AnimationEvent {
|
||||
|
@ -654,7 +627,6 @@ fn virtual_event_from_websys_event(event: web_sys::Event) -> Arc<dyn Any + Send
|
|||
pseudo_element: evt.pseudo_element(),
|
||||
})
|
||||
}
|
||||
|
||||
"transitionend" => {
|
||||
let evt: &web_sys::TransitionEvent = event.dyn_ref().unwrap();
|
||||
Arc::new(TransitionEvent {
|
||||
|
@ -663,20 +635,11 @@ fn virtual_event_from_websys_event(event: web_sys::Event) -> Arc<dyn Any + Send
|
|||
pseudo_element: evt.pseudo_element(),
|
||||
})
|
||||
}
|
||||
|
||||
"abort" | "canplay" | "canplaythrough" | "durationchange" | "emptied" | "encrypted"
|
||||
| "ended" | "error" | "loadeddata" | "loadedmetadata" | "loadstart" | "pause" | "play"
|
||||
| "playing" | "progress" | "ratechange" | "seeked" | "seeking" | "stalled" | "suspend"
|
||||
| "timeupdate" | "volumechange" | "waiting" => {
|
||||
//
|
||||
Arc::new(MediaEvent {})
|
||||
}
|
||||
|
||||
"toggle" => {
|
||||
//
|
||||
Arc::new(ToggleEvent {})
|
||||
}
|
||||
|
||||
| "timeupdate" | "volumechange" | "waiting" => Arc::new(MediaEvent {}),
|
||||
"toggle" => Arc::new(ToggleEvent {}),
|
||||
_ => Arc::new(()),
|
||||
}
|
||||
}
|
||||
|
@ -684,6 +647,8 @@ fn virtual_event_from_websys_event(event: web_sys::Event) -> Arc<dyn Any + Send
|
|||
/// This function decodes a websys event and produces an EventTrigger
|
||||
/// With the websys implementation, we attach a unique key to the nodes
|
||||
fn decode_trigger(event: &web_sys::Event) -> anyhow::Result<UserEvent> {
|
||||
use anyhow::Context;
|
||||
|
||||
let target = event
|
||||
.target()
|
||||
.expect("missing target")
|
||||
|
@ -692,42 +657,16 @@ fn decode_trigger(event: &web_sys::Event) -> anyhow::Result<UserEvent> {
|
|||
|
||||
let typ = event.type_();
|
||||
|
||||
use anyhow::Context;
|
||||
|
||||
let element_id = target
|
||||
.get_attribute("dioxus-id")
|
||||
.context("Could not find element id on event target")?
|
||||
.parse()?;
|
||||
|
||||
// The error handling here is not very descriptive and needs to be replaced with a zero-cost error system
|
||||
let val: String = target
|
||||
.get_attribute("dioxus-event")
|
||||
.context(format!("wrong format - received {:#?}", typ))?;
|
||||
// .get_attribute(&format!("dioxus-event-{}", typ))
|
||||
// .context(format!("wrong format - received {:#?}", typ))?;
|
||||
|
||||
let mut fields = val.splitn(3, ".");
|
||||
|
||||
// let gi_id = fields
|
||||
// .next()
|
||||
// .and_then(|f| f.parse::<u64>().ok())
|
||||
// .context("failed to parse gi id")?;
|
||||
|
||||
// let real_id = fields
|
||||
// .next()
|
||||
// .and_then(|raw_id| raw_id.parse::<u64>().ok())
|
||||
// .context("failed to parse real id")?;
|
||||
|
||||
// let triggered_scope = gi_id;
|
||||
|
||||
Ok(UserEvent {
|
||||
name: event_name_from_typ(&typ),
|
||||
data: virtual_event_from_websys_event(event.clone()),
|
||||
element: Some(ElementId(element_id)),
|
||||
scope_id: None,
|
||||
// scope_id: Some(ScopeId(triggered_scope as usize)),
|
||||
// element: Some(ElementId(real_id as usize)),
|
||||
// scope_id: Some(ScopeId(triggered_scope as usize)),
|
||||
priority: dioxus_core::EventPriority::Medium,
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue