Browse Source

feat: re-enable suspense

Jonathan Kelley 3 years ago
parent
commit
687cda1b6d

+ 12 - 8
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)
             }
         }
     }

+ 44 - 18
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<dyn $eventdata>);
 
                 // 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 {

+ 1 - 1
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

+ 5 - 4
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"

+ 131 - 27
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::<Element>().unwrap().remove();
+        }
+
         let old = old_nodes[0].clone();
         let arr: js_sys::Array = new_nodes.iter().collect();
         let el = old.dyn_into::<Element>().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<String> = (&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)