Explorar o código

create features for large web-sys events/types

Evan Almloff hai 1 ano
pai
achega
45d386810b

+ 22 - 19
packages/html/Cargo.toml

@@ -29,31 +29,26 @@ serde_json = { version = "1", optional = true }
 optional = true
 version = "0.3.56"
 features = [
-    "TouchEvent",
-    "MouseEvent",
-    "InputEvent",
-    "ClipboardEvent",
-    "KeyboardEvent",
-    "TouchEvent",
-    "WheelEvent",
-    "AnimationEvent",
-    "TransitionEvent",
-    "PointerEvent",
-    "FocusEvent",
-    "CompositionEvent",
-    "ClipboardEvent",
-    "Element",
-    "DomRect",
-    "ScrollIntoViewOptions",
-    "ScrollLogicalPosition",
-    "ScrollBehavior",
+     "TouchEvent",
+     "MouseEvent",
+     "InputEvent",
+     "ClipboardEvent",
+     "KeyboardEvent",
+     "TouchEvent",
+     "WheelEvent",
+     "AnimationEvent",
+     "TransitionEvent",
+     "PointerEvent",
+     "FocusEvent",
+     "CompositionEvent",
+     "ClipboardEvent",
 ]
 
 [dev-dependencies]
 serde_json = "1"
 
 [features]
-default = ["serialize"]
+default = ["serialize", "mounted"]
 serialize = [
     "serde",
     "serde_repr",
@@ -62,6 +57,14 @@ serialize = [
     "keyboard-types/serde",
     "dioxus-core/serialize",
 ]
+mounted = [
+    "web-sys/Element",
+    "web-sys/DomRect",
+    "web-sys/ScrollIntoViewOptions",
+    "web-sys/ScrollLogicalPosition",
+    "web-sys/ScrollBehavior",
+    "web-sys/HtmlElement",
+]
 wasm-bind = ["web-sys", "wasm-bindgen"]
 native-bind = ["tokio"]
 hot-reload-context = ["dioxus-rsx"]

+ 22 - 19
packages/html/src/web_sys_bind/events.rs

@@ -4,18 +4,14 @@ use crate::events::{
 };
 use crate::geometry::{ClientPoint, Coordinates, ElementPoint, PagePoint, ScreenPoint};
 use crate::input_data::{decode_key_location, decode_mouse_button_set, MouseButton};
-use crate::{
-    DragData, MountedData, MountedError, MountedResult, RenderedElementBacking, ScrollBehavior,
-};
+use crate::{DragData, MountedData};
 use keyboard_types::{Code, Key, Modifiers};
 use std::convert::TryInto;
-use std::future::Future;
-use std::pin::Pin;
 use std::str::FromStr;
 use wasm_bindgen::{JsCast, JsValue};
 use web_sys::{
-    AnimationEvent, CompositionEvent, Event, KeyboardEvent, MouseEvent, PointerEvent,
-    ScrollIntoViewOptions, TouchEvent, TransitionEvent, WheelEvent,
+    AnimationEvent, CompositionEvent, Event, KeyboardEvent, MouseEvent, PointerEvent, TouchEvent,
+    TransitionEvent, WheelEvent,
 };
 
 macro_rules! uncheck_convert {
@@ -198,16 +194,20 @@ impl From<&TransitionEvent> for TransitionData {
     }
 }
 
+#[cfg(feature = "mounted")]
 impl From<&web_sys::Element> for MountedData {
     fn from(e: &web_sys::Element) -> Self {
         MountedData::new(e.clone())
     }
 }
 
-impl RenderedElementBacking for web_sys::Element {
+#[cfg(feature = "mounted")]
+impl crate::RenderedElementBacking for web_sys::Element {
     fn get_client_rect(
         &self,
-    ) -> Pin<Box<dyn Future<Output = MountedResult<euclid::Rect<f64, f64>>>>> {
+    ) -> std::pin::Pin<
+        Box<dyn std::future::Future<Output = crate::MountedResult<euclid::Rect<f64, f64>>>>,
+    > {
         let rect = self.get_bounding_client_rect();
         let result = Ok(euclid::Rect::new(
             euclid::Point2D::new(rect.left(), rect.top()),
@@ -216,33 +216,36 @@ impl RenderedElementBacking for web_sys::Element {
         Box::pin(async { result })
     }
 
-    fn get_raw_element(&self) -> MountedResult<&dyn std::any::Any> {
+    fn get_raw_element(&self) -> crate::MountedResult<&dyn std::any::Any> {
         Ok(self)
     }
 
     fn scroll_to(
         &self,
-        behavior: ScrollBehavior,
-    ) -> Pin<Box<dyn Future<Output = MountedResult<()>>>> {
+        behavior: crate::ScrollBehavior,
+    ) -> std::pin::Pin<Box<dyn std::future::Future<Output = crate::MountedResult<()>>>> {
         match behavior {
-            ScrollBehavior::Instant => self.scroll_into_view_with_scroll_into_view_options(
-                ScrollIntoViewOptions::new().behavior(web_sys::ScrollBehavior::Instant),
+            crate::ScrollBehavior::Instant => self.scroll_into_view_with_scroll_into_view_options(
+                web_sys::ScrollIntoViewOptions::new().behavior(web_sys::ScrollBehavior::Instant),
             ),
-            ScrollBehavior::Smooth => self.scroll_into_view_with_scroll_into_view_options(
-                ScrollIntoViewOptions::new().behavior(web_sys::ScrollBehavior::Smooth),
+            crate::ScrollBehavior::Smooth => self.scroll_into_view_with_scroll_into_view_options(
+                web_sys::ScrollIntoViewOptions::new().behavior(web_sys::ScrollBehavior::Smooth),
             ),
         }
 
         Box::pin(async { Ok(()) })
     }
 
-    fn set_focus(&self, focus: bool) -> Pin<Box<dyn Future<Output = MountedResult<()>>>> {
+    fn set_focus(
+        &self,
+        focus: bool,
+    ) -> std::pin::Pin<Box<dyn std::future::Future<Output = crate::MountedResult<()>>>> {
         let result = self
             .dyn_ref::<web_sys::HtmlElement>()
-            .ok_or_else(|| MountedError::OperationFailed(Box::new(FocusError(self.into()))))
+            .ok_or_else(|| crate::MountedError::OperationFailed(Box::new(FocusError(self.into()))))
             .and_then(|e| {
                 (if focus { e.focus() } else { e.blur() })
-                    .map_err(|err| MountedError::OperationFailed(Box::new(FocusError(err))))
+                    .map_err(|err| crate::MountedError::OperationFailed(Box::new(FocusError(err))))
             });
         Box::pin(async { result })
     }

+ 21 - 42
packages/web/Cargo.toml

@@ -11,7 +11,7 @@ keywords = ["dom", "ui", "gui", "react", "wasm"]
 
 [dependencies]
 dioxus-core = { workspace = true, features = ["serialize"] }
-dioxus-html = { workspace = true, features = ["wasm-bind"] }
+dioxus-html = { workspace = true, features = ["wasm-bind"], default-features = false }
 dioxus-interpreter-js = { workspace = true, features = [
     "sledgehammer",
     "minimal_bindings",
@@ -23,11 +23,7 @@ wasm-bindgen-futures = "0.4.29"
 log = { workspace = true }
 rustc-hash = { workspace = true }
 console_error_panic_hook = { version = "0.1.7", optional = true }
-once_cell = "1.9.0"
-anyhow = "1.0.53"
-gloo-timers = { version = "0.2.3", features = ["futures"] }
 futures-util = { workspace = true, features = ["std", "async-await", "async-await-macro"] }
-smallstr = "0.2.0"
 futures-channel = { workspace = true }
 serde_json = { version = "1.0" }
 serde = { version = "1.0" }
@@ -38,55 +34,38 @@ async-channel = "1.8.0"
 [dependencies.web-sys]
 version = "0.3.56"
 features = [
-    "Comment",
-    "Attr",
     "Document",
-    "Element",
-    "CssStyleDeclaration",
     "HtmlElement",
     "HtmlInputElement",
     "HtmlSelectElement",
     "HtmlTextAreaElement",
     "HtmlFormElement",
-    "EventTarget",
-    "HtmlCollection",
-    "Node",
-    "NodeList",
     "Text",
     "Window",
-    "Event",
-    "MouseEvent",
-    "InputEvent",
-    "ClipboardEvent",
-    "NamedNodeMap",
-    "KeyboardEvent",
-    "TouchEvent",
-    "WheelEvent",
-    "AnimationEvent",
-    "TransitionEvent",
-    "PointerEvent",
-    "FocusEvent",
-    "CompositionEvent",
-    "ClipboardEvent",
-    "DocumentType",
-    "CharacterData",
-    "SvgElement",
-    "SvgAnimatedString",
-    "HtmlOptionElement",
-    "IdleDeadline",
-    "WebSocket",
-    "Location",
-    "MessageEvent",
-    "console",
-    "FileList",
-    "File",
-    "FileReader"
 ]
 
 [features]
-default = ["panic_hook"]
+default = ["panic_hook", "mounted", "file_engine", "hot_reload", "eval"]
 panic_hook = ["console_error_panic_hook"]
-hydrate = []
+hydrate = [
+    "web-sys/Comment",
+    "web-sys/console",
+]
+mounted = [
+    "web-sys/Element",
+    "dioxus-html/mounted"
+]
+file_engine = [
+    "web-sys/File",
+    "web-sys/FileList",
+    "web-sys/FileReader",
+]
+hot_reload = [
+    "web-sys/MessageEvent",
+    "web-sys/WebSocket",
+    "web-sys/Location",
+]
+eval = []
 
 [dev-dependencies]
 dioxus = { workspace = true }

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

@@ -10,16 +10,16 @@
 use dioxus_core::{
     BorrowedAttributeValue, ElementId, Mutation, Template, TemplateAttribute, TemplateNode,
 };
-use dioxus_html::{event_bubbles, CompositionData, FileEngine, FormData, MountedData};
+use dioxus_html::{event_bubbles, CompositionData, FormData, MountedData};
 use dioxus_interpreter_js::{get_node, minimal_bindings, save_template, Channel};
 use futures_channel::mpsc;
 use js_sys::Array;
 use rustc_hash::FxHashMap;
-use std::{any::Any, rc::Rc, sync::Arc};
+use std::{any::Any, rc::Rc};
 use wasm_bindgen::{closure::Closure, prelude::wasm_bindgen, JsCast, JsValue};
 use web_sys::{Document, Element, Event};
 
-use crate::{file_engine::WebFileEngine, Config};
+use crate::Config;
 
 pub struct WebsysDom {
     document: Document,
@@ -385,11 +385,15 @@ fn read_input_to_data(target: Element) -> Rc<FormData> {
         }
     }
 
+    #[cfg(not(feature = "file_engine"))]
+    let files = None;
+    #[cfg(feature = "file_engine")]
     let files = target
         .dyn_ref()
         .and_then(|input: &web_sys::HtmlInputElement| {
             input.files().and_then(|files| {
-                WebFileEngine::new(files).map(|f| Arc::new(f) as Arc<dyn FileEngine>)
+                crate::file_engine::WebFileEngine::new(files)
+                    .map(|f| std::sync::Arc::new(f) as std::sync::Arc<dyn dioxus_html::FileEngine>)
             })
         });
 

+ 3 - 13
packages/web/src/hot_reload.rs

@@ -3,22 +3,12 @@
 use futures_channel::mpsc::UnboundedReceiver;
 
 use dioxus_core::Template;
-use wasm_bindgen::closure::Closure;
-use wasm_bindgen::JsCast;
-use web_sys::{MessageEvent, WebSocket};
 
-#[cfg(not(debug_assertions))]
-pub(crate) fn init() -> UnboundedReceiver<Template<'static>> {
-    let (tx, rx) = futures_channel::mpsc::unbounded();
-
-    std::mem::forget(tx);
-
-    rx
-}
-
-#[cfg(debug_assertions)]
 pub(crate) fn init() -> UnboundedReceiver<Template<'static>> {
     use std::convert::TryInto;
+    use wasm_bindgen::closure::Closure;
+    use wasm_bindgen::JsCast;
+    use web_sys::{MessageEvent, WebSocket};
 
     use serde::Deserialize;
 

+ 31 - 10
packages/web/src/lib.rs

@@ -55,13 +55,19 @@
 
 pub use crate::cfg::Config;
 use dioxus_core::{Element, Scope, VirtualDom};
-use futures_util::{pin_mut, FutureExt, StreamExt};
+use futures_util::{
+    future::{select, Either},
+    pin_mut, FutureExt, StreamExt,
+};
 
 mod cache;
 mod cfg;
 mod dom;
+#[cfg(feature = "eval")]
 mod eval;
+#[cfg(feature = "file_engine")]
 mod file_engine;
+#[cfg(all(feature = "hot_reload", debug_assertions))]
 mod hot_reload;
 #[cfg(feature = "hydrate")]
 mod rehydrate;
@@ -167,15 +173,19 @@ pub async fn run_with_props<T: 'static>(root: fn(Scope<T>) -> Element, root_prop
 
     let mut dom = VirtualDom::new_with_props(root, root_props);
 
-    // Eval
-    let cx = dom.base_scope();
-    eval::init_eval(cx);
+    #[cfg(feature = "eval")]
+    {
+        // Eval
+        let cx = dom.base_scope();
+        eval::init_eval(cx);
+    }
 
     #[cfg(feature = "panic_hook")]
     if cfg.default_panic_hook {
         console_error_panic_hook::set_once();
     }
 
+    #[cfg(all(feature = "hot_reload", debug_assertions))]
     let mut hotreload_rx = hot_reload::init();
 
     for s in crate::cache::BUILTIN_INTERNED_STRINGS {
@@ -237,12 +247,23 @@ pub async fn run_with_props<T: 'static>(root: fn(Scope<T>) -> Element, root_prop
             let work = dom.wait_for_work().fuse();
             pin_mut!(work);
 
-            futures_util::select! {
-                _ = work => (None, None),
-                new_template = hotreload_rx.next() => {
-                    (None, new_template)
-                }
-                evt = rx.next() => (evt, None)
+            #[cfg(all(feature = "hot_reload", debug_assertions))]
+            // futures_util::select! {
+            //     _ = work => (None, None),
+            //     new_template = hotreload_rx.next() => {
+            //         (None, new_template)
+            //     }
+            //     evt = rx.next() =>
+            // }
+            match select(work, select(hotreload_rx.next(), rx.next())).await {
+                Either::Left((_, _)) => (None, None),
+                Either::Right((Either::Left((new_template, _)), _)) => (None, new_template),
+                Either::Right((Either::Right((evt, _)), _)) => (evt, None),
+            }
+            #[cfg(not(all(feature = "hot_reload", debug_assertions)))]
+            match select(work, rx.next()).await {
+                Either::Left((_, _)) => (None, None),
+                Either::Right((evt, _)) => (evt, None),
             }
         };