From 687cda1b6d9595357d1dc8720ebe921f61098d8f Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Fri, 30 Jul 2021 22:14:06 -0400 Subject: [PATCH] feat: re-enable suspense --- packages/core/src/diff.rs | 20 ++-- packages/core/src/events.rs | 62 ++++++++---- packages/core/src/virtual_dom.rs | 2 +- packages/web/Cargo.toml | 9 +- packages/web/src/dom.rs | 158 +++++++++++++++++++++++++------ 5 files changed, 193 insertions(+), 58 deletions(-) diff --git a/packages/core/src/diff.rs b/packages/core/src/diff.rs index 72e7f0e80..f640e1f4c 100644 --- a/packages/core/src/diff.rs +++ b/packages/core/src/diff.rs @@ -338,9 +338,15 @@ impl<'real, 'bump> DiffMachine<'real, 'bump> { } // TODO - (VNodeKind::Suspended(_), new) => todo!(), + (VNodeKind::Suspended(old), new) => { + // + self.replace_and_create_many_with_many([old_node], [new_node]); + } // a node that was once real is now suspended - (old, VNodeKind::Suspended(_)) => todo!(), + (old, VNodeKind::Suspended(_)) => { + // + self.replace_and_create_many_with_many([old_node], [new_node]); + } } } @@ -512,12 +518,10 @@ impl<'real, 'bump> DiffMachine<'real, 'bump> { VNodeKind::Fragment(frag) => self.create_children(frag.children), VNodeKind::Suspended(VSuspended { node: real_node }) => { - todo!("wip on adding suspense back in"); - // let id = self.vdom.reserve_node(); - // self.edit_create_placeholder(id); - // node.dom_id.set(Some(id)); - // real_node.set(Some(id)); - // CreateMeta::new(false, 1) + let id = self.vdom.reserve_node(); + self.edit_create_placeholder(id); + real_node.set(Some(id)); + CreateMeta::new(false, 1) } } } diff --git a/packages/core/src/events.rs b/packages/core/src/events.rs index 59c520f49..3c8cc13c8 100644 --- a/packages/core/src/events.rs +++ b/packages/core/src/events.rs @@ -91,7 +91,6 @@ impl EventTrigger { } } -#[derive(Debug)] pub enum VirtualEvent { // Real events ClipboardEvent(on::ClipboardEvent), @@ -135,6 +134,34 @@ pub enum VirtualEvent { // GarbageCollection {} } +impl std::fmt::Debug for VirtualEvent { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let name = match self { + VirtualEvent::ClipboardEvent(_) => "ClipboardEvent", + VirtualEvent::CompositionEvent(_) => "CompositionEvent", + VirtualEvent::KeyboardEvent(_) => "KeyboardEvent", + VirtualEvent::FocusEvent(_) => "FocusEvent", + VirtualEvent::FormEvent(_) => "FormEvent", + VirtualEvent::SelectionEvent(_) => "SelectionEvent", + VirtualEvent::TouchEvent(_) => "TouchEvent", + VirtualEvent::UIEvent(_) => "UIEvent", + VirtualEvent::WheelEvent(_) => "WheelEvent", + VirtualEvent::MediaEvent(_) => "MediaEvent", + VirtualEvent::AnimationEvent(_) => "AnimationEvent", + VirtualEvent::TransitionEvent(_) => "TransitionEvent", + VirtualEvent::ToggleEvent(_) => "ToggleEvent", + VirtualEvent::MouseEvent(_) => "MouseEvent", + VirtualEvent::PointerEvent(_) => "PointerEvent", + VirtualEvent::GarbageCollection => "GarbageCollection", + VirtualEvent::SetStateEvent { .. } => "SetStateEvent", + VirtualEvent::AsyncEvent { .. } => "AsyncEvent", + VirtualEvent::SuspenseEvent { .. } => "SuspenseEvent", + }; + + f.debug_struct("VirtualEvent").field("type", &name).finish() + } +} + pub mod on { //! This module defines the synthetic events that all Dioxus apps enable. No matter the platform, every dioxus renderer //! will implement the same events and same behavior (bubbling, cancelation, etc). @@ -169,7 +196,6 @@ pub mod on { )* ) => { $( $(#[$attr])* - #[derive(Debug)] pub struct $wrapper(pub Rc); // todo: derefing to the event is fine (and easy) but breaks some IDE stuff like (go to source) @@ -523,15 +549,15 @@ pub mod on { fn time_stamp(&self) -> usize; } - pub trait ClipboardEventInner: Debug + GenericEventInner { + pub trait ClipboardEventInner { // DOMDataTransfer clipboardData } - pub trait CompositionEventInner: Debug { + pub trait CompositionEventInner { fn data(&self) -> String; } - pub trait KeyboardEventInner: Debug { + pub trait KeyboardEventInner { fn char_code(&self) -> u32; /// Get the key code as an enum Variant. @@ -588,15 +614,15 @@ pub mod on { fn get_modifier_state(&self, key_code: usize) -> bool; } - pub trait FocusEventInner: Debug { + pub trait FocusEventInner { /* DOMEventInnerTarget relatedTarget */ } - pub trait FormEventInner: Debug { + pub trait FormEventInner { fn value(&self) -> String; } - pub trait MouseEventInner: Debug { + pub trait MouseEventInner { fn alt_key(&self) -> bool; fn button(&self) -> i16; fn buttons(&self) -> u16; @@ -613,7 +639,7 @@ pub mod on { fn get_modifier_state(&self, key_code: &str) -> bool; } - pub trait PointerEventInner: Debug { + pub trait PointerEventInner { // Mouse only fn alt_key(&self) -> bool; fn button(&self) -> usize; @@ -640,9 +666,9 @@ pub mod on { fn is_primary(&self) -> bool; } - pub trait SelectionEventInner: Debug {} + pub trait SelectionEventInner {} - pub trait TouchEventInner: Debug { + pub trait TouchEventInner { fn alt_key(&self) -> bool; fn ctrl_key(&self) -> bool; fn meta_key(&self) -> bool; @@ -653,37 +679,37 @@ pub mod on { // touches: DOMTouchList, } - pub trait UIEventInner: Debug { + pub trait UIEventInner { // DOMAbstractView view fn detail(&self) -> i32; } - pub trait WheelEventInner: Debug { + pub trait WheelEventInner { fn delta_mode(&self) -> i32; fn delta_x(&self) -> i32; fn delta_y(&self) -> i32; fn delta_z(&self) -> i32; } - pub trait MediaEventInner: Debug {} + pub trait MediaEventInner {} - pub trait ImageEventInner: Debug { + pub trait ImageEventInner { // load error } - pub trait AnimationEventInner: Debug { + pub trait AnimationEventInner { fn animation_name(&self) -> String; fn pseudo_element(&self) -> String; fn elapsed_time(&self) -> f32; } - pub trait TransitionEventInner: Debug { + pub trait TransitionEventInner { fn property_name(&self) -> String; fn pseudo_element(&self) -> String; fn elapsed_time(&self) -> f32; } - pub trait ToggleEventInner: Debug {} + pub trait ToggleEventInner {} pub use util::KeyCode; mod util { diff --git a/packages/core/src/virtual_dom.rs b/packages/core/src/virtual_dom.rs index 5d4aa11bb..e3dbd2ab2 100644 --- a/packages/core/src/virtual_dom.rs +++ b/packages/core/src/virtual_dom.rs @@ -334,7 +334,7 @@ impl VirtualDom { log::warn!("Suspense event came through, but there was no mounted node to update >:("); } Some(nodes) => { - todo!("using the wrong frame"); + // todo!("using the wrong frame"); let nodes = scope.frames.finished_frame().bump.alloc(nodes); // push the old node's root onto the stack diff --git a/packages/web/Cargo.toml b/packages/web/Cargo.toml index 82b9e85d0..3b25700dd 100644 --- a/packages/web/Cargo.toml +++ b/packages/web/Cargo.toml @@ -27,7 +27,7 @@ anyhow = "1.0" futures-util = "0.3.15" [dependencies.web-sys] -version = "0.3.50" +version = "0.3.51" features = [ "Comment", "Attr", @@ -56,6 +56,7 @@ features = [ "PointerEvent", "FocusEvent", "CompositionEvent", + "ClipboardEvent", "DocumentType", "CharacterData", "SvgElement", @@ -78,7 +79,7 @@ uuid = { version = "0.8.2", features = ["v4", "wasm-bindgen"] } dioxus-hooks = { path = "../hooks" } gloo-timers = { version = "0.2.1", features = ["futures"] } serde = { version = "1.0.126", features = ["derive"] } -# surf = { git = "https://github.com/http-rs/surf", default-features = false, features = [ -# "wasm-client", -# ] } +surf = { git = "https://github.com/http-rs/surf", rev = "1ffaba8873", default-features = false, features = [ + "wasm-client", +] } # wasm-timer = "0.2.5" diff --git a/packages/web/src/dom.rs b/packages/web/src/dom.rs index 0567a53b8..5223fdc36 100644 --- a/packages/web/src/dom.rs +++ b/packages/web/src/dom.rs @@ -186,6 +186,10 @@ impl WebsysDom { old_nodes.push(self.stack.pop()); } + for node in &old_nodes[1..] { + node.dyn_ref::().unwrap().remove(); + } + let old = old_nodes[0].clone(); let arr: js_sys::Array = new_nodes.iter().collect(); let el = old.dyn_into::().unwrap(); @@ -466,30 +470,140 @@ fn virtual_event_from_websys_event(event: &web_sys::Event) -> VirtualEvent { use dioxus_core::events::on::*; match event.type_().as_str() { "copy" | "cut" | "paste" => { - // let evt: web_sys::ClipboardEvent = event.clone().dyn_into().unwrap(); - - todo!() + struct WebsysClipboardEvent(); + impl ClipboardEventInner for WebsysClipboardEvent {} + VirtualEvent::ClipboardEvent(ClipboardEvent(Rc::new(WebsysClipboardEvent()))) } "compositionend" | "compositionstart" | "compositionupdate" => { let evt: web_sys::CompositionEvent = event.clone().dyn_into().unwrap(); - todo!() + struct WebsysCompositionEvent(web_sys::CompositionEvent); + impl CompositionEventInner for WebsysCompositionEvent { + fn data(&self) -> String { + todo!() + } + } + VirtualEvent::CompositionEvent(CompositionEvent(Rc::new(WebsysCompositionEvent(evt)))) } "keydown" | "keypress" | "keyup" => { + struct Event(web_sys::KeyboardEvent); + impl KeyboardEventInner for Event { + fn char_code(&self) -> u32 { + todo!() + } + fn key_code(&self) -> KeyCode { + todo!() + } + fn ctrl_key(&self) -> bool { + todo!() + } + + fn key(&self) -> String { + todo!() + } + + fn locale(&self) -> String { + todo!() + } + + fn location(&self) -> usize { + todo!() + } + + fn meta_key(&self) -> bool { + todo!() + } + + fn repeat(&self) -> bool { + todo!() + } + + fn shift_key(&self) -> bool { + todo!() + } + + fn which(&self) -> usize { + todo!() + } + + fn get_modifier_state(&self, key_code: usize) -> bool { + todo!() + } + } let evt: web_sys::KeyboardEvent = event.clone().dyn_into().unwrap(); - todo!() + VirtualEvent::KeyboardEvent(KeyboardEvent(Rc::new(Event(evt)))) } "focus" | "blur" => { + struct Event(web_sys::FocusEvent); + impl FocusEventInner for Event {} let evt: web_sys::FocusEvent = event.clone().dyn_into().unwrap(); - todo!() + VirtualEvent::FocusEvent(FocusEvent(Rc::new(Event(evt)))) } "change" => { - let evt: web_sys::Event = event.clone().dyn_into().expect("wrong error typ"); + // struct Event(web_sys::Event); + // impl GenericEventInner for Event { + // fn bubbles(&self) -> bool { + // todo!() + // } + + // fn cancel_bubble(&self) { + // todo!() + // } + + // fn cancelable(&self) -> bool { + // todo!() + // } + + // fn composed(&self) -> bool { + // todo!() + // } + + // fn composed_path(&self) -> String { + // todo!() + // } + + // fn current_target(&self) { + // todo!() + // } + + // fn default_prevented(&self) -> bool { + // todo!() + // } + + // fn event_phase(&self) -> usize { + // todo!() + // } + + // fn is_trusted(&self) -> bool { + // todo!() + // } + + // fn prevent_default(&self) { + // todo!() + // } + + // fn stop_immediate_propagation(&self) { + // todo!() + // } + + // fn stop_propagation(&self) { + // todo!() + // } + + // fn target(&self) { + // todo!() + // } + + // fn time_stamp(&self) -> usize { + // todo!() + // } + // } + // let evt: web_sys::Event = event.clone().dyn_into().expect("wrong error typ"); + // VirtualEvent::Event(GenericEvent(Rc::new(Event(evt)))) todo!() - // VirtualEvent::FormEvent(FormEvent {value:}) } "input" | "invalid" | "reset" | "submit" => { @@ -513,15 +627,6 @@ fn virtual_event_from_websys_event(event: &web_sys::Event) -> VirtualEvent { }) .expect("only an InputElement or TextAreaElement or an element with contenteditable=true can have an oninput event listener"); - // let p2 = evt.data_transfer(); - - // let value: Option = (&evt).data(); - // let value = val; - // let value = value.unwrap_or_default(); - // let value = (&evt).data().expect("No data to unwrap"); - - // todo - this needs to be a "controlled" event - // these events won't carry the right data with them todo!() // VirtualEvent::FormEvent(FormEvent { value }) } @@ -606,6 +711,15 @@ fn virtual_event_from_websys_event(event: &web_sys::Event) -> VirtualEvent { let evt: web_sys::WheelEvent = event.clone().dyn_into().unwrap(); todo!() } + "animationstart" | "animationend" | "animationiteration" => { + let evt: web_sys::AnimationEvent = event.clone().dyn_into().unwrap(); + todo!() + } + + "transitionend" => { + let evt: web_sys::TransitionEvent = event.clone().dyn_into().unwrap(); + todo!() + } "abort" | "canplay" | "canplaythrough" | "durationchange" | "emptied" | "encrypted" | "ended" | "error" | "loadeddata" | "loadedmetadata" | "loadstart" | "pause" | "play" @@ -618,16 +732,6 @@ fn virtual_event_from_websys_event(event: &web_sys::Event) -> VirtualEvent { todo!() } - "animationstart" | "animationend" | "animationiteration" => { - let evt: web_sys::AnimationEvent = event.clone().dyn_into().unwrap(); - todo!() - } - - "transitionend" => { - let evt: web_sys::TransitionEvent = event.clone().dyn_into().unwrap(); - todo!() - } - "toggle" => { // not required to construct anything special beyond standard event stuff (target)