Merge pull request #1265 from Demonthos/dioxus-web-features

Create default enabled features for large web events
This commit is contained in:
Jonathan Kelley authored and GitHub committed 2023-07-31 17:14:07 -07:00
commit 8cf59fe52e
6 files changed
+107 -107

No files matched your search

+22 -19
View File
@@ -29,31 +29,26 @@ serde_json = { version = "1", optional = true }
optional = true optional = true
version = "0.3.56" version = "0.3.56"
features = [ features = [
"TouchEvent", "TouchEvent",
"MouseEvent", "MouseEvent",
"InputEvent", "InputEvent",
"ClipboardEvent", "ClipboardEvent",
"KeyboardEvent", "KeyboardEvent",
"TouchEvent", "TouchEvent",
"WheelEvent", "WheelEvent",
"AnimationEvent", "AnimationEvent",
"TransitionEvent", "TransitionEvent",
"PointerEvent", "PointerEvent",
"FocusEvent", "FocusEvent",
"CompositionEvent", "CompositionEvent",
"ClipboardEvent", "ClipboardEvent",
"Element",
"DomRect",
"ScrollIntoViewOptions",
"ScrollLogicalPosition",
"ScrollBehavior",
] ]
[dev-dependencies] [dev-dependencies]
serde_json = "1" serde_json = "1"
[features] [features]
default = ["serialize"] default = ["serialize", "mounted"]
serialize = [ serialize = [
"serde", "serde",
"serde_repr", "serde_repr",
@@ -62,6 +57,14 @@ serialize = [
"keyboard-types/serde", "keyboard-types/serde",
"dioxus-core/serialize", "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"] wasm-bind = ["web-sys", "wasm-bindgen"]
native-bind = ["tokio"] native-bind = ["tokio"]
hot-reload-context = ["dioxus-rsx"] hot-reload-context = ["dioxus-rsx"]
+22 -19
View File
@@ -4,18 +4,14 @@ use crate::events::{
}; };
use crate::geometry::{ClientPoint, Coordinates, ElementPoint, PagePoint, ScreenPoint}; use crate::geometry::{ClientPoint, Coordinates, ElementPoint, PagePoint, ScreenPoint};
use crate::input_data::{decode_key_location, decode_mouse_button_set, MouseButton}; use crate::input_data::{decode_key_location, decode_mouse_button_set, MouseButton};
use crate::{ use crate::{DragData, MountedData};
DragData, MountedData, MountedError, MountedResult, RenderedElementBacking, ScrollBehavior,
};
use keyboard_types::{Code, Key, Modifiers}; use keyboard_types::{Code, Key, Modifiers};
use std::convert::TryInto; use std::convert::TryInto;
use std::future::Future;
use std::pin::Pin;
use std::str::FromStr; use std::str::FromStr;
use wasm_bindgen::{JsCast, JsValue}; use wasm_bindgen::{JsCast, JsValue};
use web_sys::{ use web_sys::{
AnimationEvent, CompositionEvent, Event, KeyboardEvent, MouseEvent, PointerEvent, AnimationEvent, CompositionEvent, Event, KeyboardEvent, MouseEvent, PointerEvent, TouchEvent,
ScrollIntoViewOptions, TouchEvent, TransitionEvent, WheelEvent, TransitionEvent, WheelEvent,
}; };
macro_rules! uncheck_convert { macro_rules! uncheck_convert {
@@ -198,16 +194,20 @@ impl From<&TransitionEvent> for TransitionData {
} }
} }
#[cfg(feature = "mounted")]
impl From<&web_sys::Element> for MountedData { impl From<&web_sys::Element> for MountedData {
fn from(e: &web_sys::Element) -> Self { fn from(e: &web_sys::Element) -> Self {
MountedData::new(e.clone()) MountedData::new(e.clone())
} }
} }
impl RenderedElementBacking for web_sys::Element { #[cfg(feature = "mounted")]
impl crate::RenderedElementBacking for web_sys::Element {
fn get_client_rect( fn get_client_rect(
&self, &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 rect = self.get_bounding_client_rect();
let result = Ok(euclid::Rect::new( let result = Ok(euclid::Rect::new(
euclid::Point2D::new(rect.left(), rect.top()), euclid::Point2D::new(rect.left(), rect.top()),
@@ -216,33 +216,36 @@ impl RenderedElementBacking for web_sys::Element {
Box::pin(async { result }) 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) Ok(self)
} }
fn scroll_to( fn scroll_to(
&self, &self,
behavior: ScrollBehavior, behavior: crate::ScrollBehavior,
) -> Pin<Box<dyn Future<Output = MountedResult<()>>>> { ) -> std::pin::Pin<Box<dyn std::future::Future<Output = crate::MountedResult<()>>>> {
match behavior { match behavior {
ScrollBehavior::Instant => self.scroll_into_view_with_scroll_into_view_options( crate::ScrollBehavior::Instant => self.scroll_into_view_with_scroll_into_view_options(
ScrollIntoViewOptions::new().behavior(web_sys::ScrollBehavior::Instant), web_sys::ScrollIntoViewOptions::new().behavior(web_sys::ScrollBehavior::Instant),
), ),
ScrollBehavior::Smooth => self.scroll_into_view_with_scroll_into_view_options( crate::ScrollBehavior::Smooth => self.scroll_into_view_with_scroll_into_view_options(
ScrollIntoViewOptions::new().behavior(web_sys::ScrollBehavior::Smooth), web_sys::ScrollIntoViewOptions::new().behavior(web_sys::ScrollBehavior::Smooth),
), ),
} }
Box::pin(async { Ok(()) }) 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 let result = self
.dyn_ref::<web_sys::HtmlElement>() .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| { .and_then(|e| {
(if focus { e.focus() } else { e.blur() }) (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 }) Box::pin(async { result })
} }
+21 -42
View File
@@ -11,7 +11,7 @@ keywords = ["dom", "ui", "gui", "react", "wasm"]
[dependencies] [dependencies]
dioxus-core = { workspace = true, features = ["serialize"] } 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 = [ dioxus-interpreter-js = { workspace = true, features = [
"sledgehammer", "sledgehammer",
"minimal_bindings", "minimal_bindings",
@@ -23,11 +23,7 @@ wasm-bindgen-futures = "0.4.29"
log = { workspace = true } log = { workspace = true }
rustc-hash = { workspace = true } rustc-hash = { workspace = true }
console_error_panic_hook = { version = "0.1.7", optional = 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"] } futures-util = { workspace = true, features = ["std", "async-await", "async-await-macro"] }
smallstr = "0.2.0"
futures-channel = { workspace = true } futures-channel = { workspace = true }
serde_json = { version = "1.0" } serde_json = { version = "1.0" }
serde = { version = "1.0" } serde = { version = "1.0" }
@@ -38,55 +34,38 @@ async-channel = "1.8.0"
[dependencies.web-sys] [dependencies.web-sys]
version = "0.3.56" version = "0.3.56"
features = [ features = [
"Comment",
"Attr",
"Document", "Document",
"Element",
"CssStyleDeclaration",
"HtmlElement", "HtmlElement",
"HtmlInputElement", "HtmlInputElement",
"HtmlSelectElement", "HtmlSelectElement",
"HtmlTextAreaElement", "HtmlTextAreaElement",
"HtmlFormElement", "HtmlFormElement",
"EventTarget",
"HtmlCollection",
"Node",
"NodeList",
"Text", "Text",
"Window", "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] [features]
default = ["panic_hook"] default = ["panic_hook", "mounted", "file_engine", "hot_reload", "eval"]
panic_hook = ["console_error_panic_hook"] 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] [dev-dependencies]
dioxus = { workspace = true } dioxus = { workspace = true }
+8 -4
View File
@@ -10,16 +10,16 @@
use dioxus_core::{ use dioxus_core::{
BorrowedAttributeValue, ElementId, Mutation, Template, TemplateAttribute, TemplateNode, 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 dioxus_interpreter_js::{get_node, minimal_bindings, save_template, Channel};
use futures_channel::mpsc; use futures_channel::mpsc;
use js_sys::Array; use js_sys::Array;
use rustc_hash::FxHashMap; 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 wasm_bindgen::{closure::Closure, prelude::wasm_bindgen, JsCast, JsValue};
use web_sys::{Document, Element, Event}; use web_sys::{Document, Element, Event};
use crate::{file_engine::WebFileEngine, Config}; use crate::Config;
pub struct WebsysDom { pub struct WebsysDom {
document: Document, 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 let files = target
.dyn_ref() .dyn_ref()
.and_then(|input: &web_sys::HtmlInputElement| { .and_then(|input: &web_sys::HtmlInputElement| {
input.files().and_then(|files| { 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
View File
@@ -3,22 +3,12 @@
use futures_channel::mpsc::UnboundedReceiver; use futures_channel::mpsc::UnboundedReceiver;
use dioxus_core::Template; 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>> { pub(crate) fn init() -> UnboundedReceiver<Template<'static>> {
use std::convert::TryInto; use std::convert::TryInto;
use wasm_bindgen::closure::Closure;
use wasm_bindgen::JsCast;
use web_sys::{MessageEvent, WebSocket};
use serde::Deserialize; use serde::Deserialize;
+31 -10
View File
@@ -55,13 +55,19 @@
pub use crate::cfg::Config; pub use crate::cfg::Config;
use dioxus_core::{Element, Scope, VirtualDom}; 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 cache;
mod cfg; mod cfg;
mod dom; mod dom;
#[cfg(feature = "eval")]
mod eval; mod eval;
#[cfg(feature = "file_engine")]
mod file_engine; mod file_engine;
#[cfg(all(feature = "hot_reload", debug_assertions))]
mod hot_reload; mod hot_reload;
#[cfg(feature = "hydrate")] #[cfg(feature = "hydrate")]
mod rehydrate; 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); let mut dom = VirtualDom::new_with_props(root, root_props);
// Eval #[cfg(feature = "eval")]
let cx = dom.base_scope(); {
eval::init_eval(cx); // Eval
let cx = dom.base_scope();
eval::init_eval(cx);
}
#[cfg(feature = "panic_hook")] #[cfg(feature = "panic_hook")]
if cfg.default_panic_hook { if cfg.default_panic_hook {
console_error_panic_hook::set_once(); console_error_panic_hook::set_once();
} }
#[cfg(all(feature = "hot_reload", debug_assertions))]
let mut hotreload_rx = hot_reload::init(); let mut hotreload_rx = hot_reload::init();
for s in crate::cache::BUILTIN_INTERNED_STRINGS { 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(); let work = dom.wait_for_work().fuse();
pin_mut!(work); pin_mut!(work);
futures_util::select! { #[cfg(all(feature = "hot_reload", debug_assertions))]
_ = work => (None, None), // futures_util::select! {
new_template = hotreload_rx.next() => { // _ = work => (None, None),
(None, new_template) // new_template = hotreload_rx.next() => {
} // (None, new_template)
evt = rx.next() => (evt, None) // }
// 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),
} }
}; };