Browse Source

Update to newer version of blitz_dom::Document trait

Signed-off-by: Nico Burns <nico@nicoburns.com>
Nico Burns 1 day ago
parent
commit
651a702f94
1 changed files with 55 additions and 17 deletions
  1. 55 17
      packages/native-dom/src/dioxus_document.rs

+ 55 - 17
packages/native-dom/src/dioxus_document.rs

@@ -3,21 +3,21 @@ use crate::events::{BlitzKeyboardData, NativeClickData, NativeConverter, NativeF
 use crate::mutation_writer::{DioxusState, MutationWriter};
 use crate::qual_name;
 use crate::NodeId;
-
-use blitz_dom::Attribute;
 use blitz_dom::{
-    net::Resource, BaseDocument, Document, EventDriver, EventHandler, Node, DEFAULT_CSS,
+    net::Resource, Attribute, BaseDocument, Document, EventDriver, EventHandler, Node, DEFAULT_CSS,
 };
 use blitz_traits::{
     events::{DomEvent, DomEventData, EventState, UiEvent},
     net::NetProvider,
     shell::{ColorScheme, Viewport},
 };
-
 use dioxus_core::{ElementId, Event, VirtualDom};
 use dioxus_html::{set_event_converter, PlatformEventData};
+use futures_util::task::noop_waker;
 use futures_util::{pin_mut, FutureExt};
 use std::ops::{Deref, DerefMut};
+use std::sync::LazyLock;
+use std::task::{Context as TaskContext, Waker};
 use std::{any::Any, collections::HashMap, rc::Rc, sync::Arc};
 
 fn wrap_event_data<T: Any>(value: T) -> Rc<dyn Any> {
@@ -34,6 +34,30 @@ fn get_dioxus_id(node: &Node) -> Option<ElementId> {
         .map(ElementId)
 }
 
+/// Integrates [`BaseDocument`] from  [`blitz-dom`](blitz_dom)  with [`VirtualDom`] from [`dioxus-core`](dioxus_core)
+///
+/// ### Example
+///
+/// ```rust
+/// // Example Dioxus app
+/// fn app() -> Element {
+///     rsx! {
+///         div { "Hello, world!" }
+///     }
+/// }
+///
+/// fn main() {
+///    let vdom = VirtualDom::new(app);
+///    let mut doc = DioxusDocument::new(vdom, None);
+///    doc.set_viewport(Viewport::new(WIDTH, HEIGHT, SCALE_FACTOR, COLOR_SCHEME));
+///    doc.inital_build();
+///
+/// }
+/// ```
+///
+/// You can just push events into the [`DioxusDocument`] with [`doc.handle_ui_event(..)`](Self::handle_ui_event)
+/// and then flush the changes with [`doc.poll(..)`](Self::poll)
+
 pub struct DioxusDocument {
     pub inner: BaseDocument,
     pub vdom: VirtualDom,
@@ -50,16 +74,33 @@ pub struct DioxusDocument {
 }
 
 impl DioxusDocument {
+    /// Create a new [`DioxusDocument`] from a [`VirtualDom`].
     pub fn new(vdom: VirtualDom, net_provider: Option<Arc<dyn NetProvider<Resource>>>) -> Self {
         let viewport = Viewport::new(0, 0, 1.0, ColorScheme::Light);
         let mut doc = BaseDocument::new(viewport);
 
+        // Set base_url
+        doc.set_base_url("dioxus://index.html");
+
         // Set net provider
         if let Some(net_provider) = net_provider {
             doc.set_net_provider(net_provider);
         }
 
+        // Include default stylesheet
+        doc.add_user_agent_stylesheet(DEFAULT_CSS);
+
         // Create some minimal HTML to render the app into.
+        // HTML is equivalent to:
+        //
+        // <html>
+        // <head></head>
+        // <body>
+        //    <div id="main"></div>
+        // </body>
+        // </html>
+        //
+        // TODO: Support arbitrary "index.html" templates
 
         // Create the html element
         let mut mutr = doc.mutate();
@@ -84,11 +125,8 @@ impl DioxusDocument {
 
         drop(mutr);
 
-        // Include default and user-specified stylesheets
-        doc.add_user_agent_stylesheet(DEFAULT_CSS);
-
         let vdom_state = DioxusState::create(main_element_id);
-        let mut doc = Self {
+        Self {
             vdom,
             vdom_state,
             inner: doc,
@@ -96,20 +134,18 @@ impl DioxusDocument {
             head_element_id,
             body_element_id,
             main_element_id,
-        };
-
-        doc.inner.set_base_url("dioxus://index.html");
-        //doc.initial_build();
-        doc.inner.print_tree();
-
-        doc
+        }
     }
 
+    /// Run an initial build of the Dioxus vdom
     pub fn initial_build(&mut self) {
         let mut writer = MutationWriter::new(&mut self.inner, &mut self.vdom_state);
         self.vdom.rebuild(&mut writer);
     }
 
+    /// Used to respond to a `CreateHeadElement` event generated by Dioxus. These
+    /// events allow Dioxus to create elements in the `<head>` of the document.
+    #[doc(hidden)]
     pub fn create_head_element(
         &mut self,
         name: &str,
@@ -150,11 +186,13 @@ impl Document for DioxusDocument {
         self
     }
 
-    fn poll(&mut self, mut cx: std::task::Context) -> bool {
+    fn poll(&mut self, cx: Option<TaskContext>) -> bool {
         {
             let fut = self.vdom.wait_for_work();
             pin_mut!(fut);
 
+            static NOOP_WAKER: LazyLock<Waker> = LazyLock::new(noop_waker);
+            let mut cx = cx.unwrap_or_else(|| TaskContext::from_waker(&NOOP_WAKER));
             match fut.poll_unpin(&mut cx) {
                 std::task::Poll::Ready(_) => {}
                 std::task::Poll::Pending => return false,
@@ -167,7 +205,7 @@ impl Document for DioxusDocument {
         true
     }
 
-    fn handle_event(&mut self, event: UiEvent) {
+    fn handle_ui_event(&mut self, event: UiEvent) {
         set_event_converter(Box::new(NativeConverter {}));
         let handler = DioxusEventHandler {
             vdom: &mut self.vdom,