From 45d386810b156e008e3b016735a1ef0be69e27c7 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Fri, 28 Jul 2023 15:38:07 -0700 Subject: [PATCH] create features for large web-sys events/types --- packages/html/Cargo.toml | 41 ++++++++------- packages/html/src/web_sys_bind/events.rs | 41 ++++++++------- packages/web/Cargo.toml | 63 ++++++++---------------- packages/web/src/dom.rs | 12 +++-- packages/web/src/hot_reload.rs | 16 ++---- packages/web/src/lib.rs | 41 +++++++++++---- 6 files changed, 107 insertions(+), 107 deletions(-) diff --git a/packages/html/Cargo.toml b/packages/html/Cargo.toml index 23d215154..f63825291 100644 --- a/packages/html/Cargo.toml +++ b/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"] diff --git a/packages/html/src/web_sys_bind/events.rs b/packages/html/src/web_sys_bind/events.rs index bcbe80dda..e5a6c0d78 100644 --- a/packages/html/src/web_sys_bind/events.rs +++ b/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>>>> { + ) -> std::pin::Pin< + Box>>>, + > { 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>>> { + behavior: crate::ScrollBehavior, + ) -> std::pin::Pin>>> { 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>>> { + fn set_focus( + &self, + focus: bool, + ) -> std::pin::Pin>>> { let result = self .dyn_ref::() - .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 }) } diff --git a/packages/web/Cargo.toml b/packages/web/Cargo.toml index 3b9b6c89d..bc37c0406 100644 --- a/packages/web/Cargo.toml +++ b/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 } diff --git a/packages/web/src/dom.rs b/packages/web/src/dom.rs index 754bb1605..9d0d837c5 100644 --- a/packages/web/src/dom.rs +++ b/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 { } } + #[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) + crate::file_engine::WebFileEngine::new(files) + .map(|f| std::sync::Arc::new(f) as std::sync::Arc) }) }); diff --git a/packages/web/src/hot_reload.rs b/packages/web/src/hot_reload.rs index cf73dc219..6256cc935 100644 --- a/packages/web/src/hot_reload.rs +++ b/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> { - let (tx, rx) = futures_channel::mpsc::unbounded(); - - std::mem::forget(tx); - - rx -} - -#[cfg(debug_assertions)] pub(crate) fn init() -> UnboundedReceiver> { use std::convert::TryInto; + use wasm_bindgen::closure::Closure; + use wasm_bindgen::JsCast; + use web_sys::{MessageEvent, WebSocket}; use serde::Deserialize; diff --git a/packages/web/src/lib.rs b/packages/web/src/lib.rs index b8a9c57b3..8bea4a460 100644 --- a/packages/web/src/lib.rs +++ b/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(root: fn(Scope) -> 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(root: fn(Scope) -> 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), } };