瀏覽代碼

Merge branch 'master' into jk/templates-v3

Jonathan Kelley 2 年之前
父節點
當前提交
112c954e00

+ 1 - 0
packages/autofmt/src/buffer.rs

@@ -69,6 +69,7 @@ impl Buffer {
             BodyNode::Component(component) => self.write_component(component),
             BodyNode::Component(component) => self.write_component(component),
             BodyNode::DynamicText(text) => self.write_text(text),
             BodyNode::DynamicText(text) => self.write_text(text),
             BodyNode::RawExpr(exp) => self.write_raw_expr(exp),
             BodyNode::RawExpr(exp) => self.write_raw_expr(exp),
+            _ => Ok(()),
         }
         }
     }
     }
 
 

+ 3 - 0
packages/core/Cargo.toml

@@ -37,6 +37,9 @@ serde = { version = "1", features = ["derive"], optional = true }
 [dev-dependencies]
 [dev-dependencies]
 tokio = { version = "*", features = ["full"] }
 tokio = { version = "*", features = ["full"] }
 
 
+[dev-dependencies]
+dioxus = { path = "../dioxus" }
+
 [features]
 [features]
 default = []
 default = []
 serialize = ["serde"]
 serialize = ["serde"]

+ 4 - 0
packages/desktop/Cargo.toml

@@ -36,6 +36,10 @@ dunce = "1.0.2"
 interprocess = { version = "1.1.1" }
 interprocess = { version = "1.1.1" }
 futures-util = "0.3.25"
 futures-util = "0.3.25"
 
 
+[target.'cfg(target_os = "ios")'.dependencies]
+objc = "0.2.7"
+objc_id = "0.1.1"
+
 [target.'cfg(target_os = "macos")'.dependencies]
 [target.'cfg(target_os = "macos")'.dependencies]
 core-foundation = "0.9.3"
 core-foundation = "0.9.3"
 
 

+ 6 - 0
packages/desktop/src/controller.rs

@@ -3,6 +3,8 @@ use crate::events::{decode_event, EventMessage};
 use dioxus_core::*;
 use dioxus_core::*;
 use futures_channel::mpsc::UnboundedReceiver;
 use futures_channel::mpsc::UnboundedReceiver;
 use futures_util::StreamExt;
 use futures_util::StreamExt;
+#[cfg(target_os = "ios")]
+use objc::runtime::Object;
 use std::{
 use std::{
     collections::HashMap,
     collections::HashMap,
     sync::Arc,
     sync::Arc,
@@ -20,6 +22,8 @@ pub(super) struct DesktopController {
     pub(super) pending_edits: Arc<Mutex<Vec<String>>>,
     pub(super) pending_edits: Arc<Mutex<Vec<String>>>,
     pub(super) quit_app_on_close: bool,
     pub(super) quit_app_on_close: bool,
     pub(super) is_ready: Arc<AtomicBool>,
     pub(super) is_ready: Arc<AtomicBool>,
+    #[cfg(target_os = "ios")]
+    pub(super) views: Vec<*mut Object>,
 }
 }
 
 
 impl DesktopController {
 impl DesktopController {
@@ -88,6 +92,8 @@ impl DesktopController {
             webviews: HashMap::new(),
             webviews: HashMap::new(),
             is_ready: Arc::new(AtomicBool::new(false)),
             is_ready: Arc::new(AtomicBool::new(false)),
             quit_app_on_close: true,
             quit_app_on_close: true,
+            #[cfg(target_os = "ios")]
+            views: vec![],
         }
         }
     }
     }
 
 

+ 55 - 0
packages/desktop/src/desktop_context.rs

@@ -4,6 +4,8 @@ use crate::controller::DesktopController;
 use dioxus_core::ScopeState;
 use dioxus_core::ScopeState;
 use wry::application::event_loop::ControlFlow;
 use wry::application::event_loop::ControlFlow;
 use wry::application::event_loop::EventLoopProxy;
 use wry::application::event_loop::EventLoopProxy;
+#[cfg(target_os = "ios")]
+use wry::application::platform::ios::WindowExtIOS;
 use wry::application::window::Fullscreen as WryFullscreen;
 use wry::application::window::Fullscreen as WryFullscreen;
 
 
 use UserWindowEvent::*;
 use UserWindowEvent::*;
@@ -143,6 +145,18 @@ impl DesktopContext {
     pub fn eval(&self, script: impl std::string::ToString) {
     pub fn eval(&self, script: impl std::string::ToString) {
         let _ = self.proxy.send_event(Eval(script.to_string()));
         let _ = self.proxy.send_event(Eval(script.to_string()));
     }
     }
+
+    /// Push view
+    #[cfg(target_os = "ios")]
+    pub fn push_view(&self, view: objc_id::ShareId<objc::runtime::Object>) {
+        let _ = self.proxy.send_event(PushView(view));
+    }
+
+    /// Push view
+    #[cfg(target_os = "ios")]
+    pub fn pop_view(&self) {
+        let _ = self.proxy.send_event(PopView);
+    }
 }
 }
 
 
 #[derive(Debug)]
 #[derive(Debug)]
@@ -173,6 +187,11 @@ pub enum UserWindowEvent {
     DevTool,
     DevTool,
 
 
     Eval(String),
     Eval(String),
+
+    #[cfg(target_os = "ios")]
+    PushView(objc_id::ShareId<objc::runtime::Object>),
+    #[cfg(target_os = "ios")]
+    PopView,
 }
 }
 
 
 pub(super) fn handler(
 pub(super) fn handler(
@@ -242,5 +261,41 @@ pub(super) fn handler(
                 log::warn!("Eval script error: {e}");
                 log::warn!("Eval script error: {e}");
             }
             }
         }
         }
+
+        #[cfg(target_os = "ios")]
+        PushView(view) => unsafe {
+            use objc::runtime::Object;
+            use objc::*;
+            assert!(is_main_thread());
+            let ui_view = window.ui_view() as *mut Object;
+            let ui_view_frame: *mut Object = msg_send![ui_view, frame];
+            let _: () = msg_send![view, setFrame: ui_view_frame];
+            let _: () = msg_send![view, setAutoresizingMask: 31];
+
+            let ui_view_controller = window.ui_view_controller() as *mut Object;
+            let _: () = msg_send![ui_view_controller, setView: view];
+            desktop.views.push(ui_view);
+        },
+
+        #[cfg(target_os = "ios")]
+        PopView => unsafe {
+            use objc::runtime::Object;
+            use objc::*;
+            assert!(is_main_thread());
+            if let Some(view) = desktop.views.pop() {
+                let ui_view_controller = window.ui_view_controller() as *mut Object;
+                let _: () = msg_send![ui_view_controller, setView: view];
+            }
+        },
     }
     }
 }
 }
+
+#[cfg(target_os = "ios")]
+fn is_main_thread() -> bool {
+    use objc::runtime::{Class, BOOL, NO};
+    use objc::*;
+
+    let cls = Class::get("NSThread").unwrap();
+    let result: BOOL = unsafe { msg_send![cls, isMainThread] };
+    result != NO
+}

+ 18 - 15
packages/dioxus/tests/create_dom.rs

@@ -75,20 +75,21 @@ fn create() {
             CreateElement { root: None, tag: "div", children: 2 },
             CreateElement { root: None, tag: "div", children: 2 },
             CreateTextNode { root: None, text: "Hello, world!" },
             CreateTextNode { root: None, text: "Hello, world!" },
             CreateElement { root: None, tag: "div", children: 1 },
             CreateElement { root: None, tag: "div", children: 1 },
-            CreateElement { root: None, tag: "div", children: 1 },
-            CreatePlaceholder { root: None },
+            CreateElement { root: None, tag: "div", children: 0 },
             // clone template
             // clone template
             CloneNodeChildren { id: Some(1), new_ids: vec![2] },
             CloneNodeChildren { id: Some(1), new_ids: vec![2] },
-            CreateTextNode { root: Some(3), text: "hello" },
-            CreateTextNode { root: Some(4), text: "world" },
-            // update template
             SetLastNode { id: 2 },
             SetLastNode { id: 2 },
             FirstChild {},
             FirstChild {},
+            StoreWithId { id: 3 },
             FirstChild {},
             FirstChild {},
             NextSibling {},
             NextSibling {},
+            StoreWithId { id: 4 },
             FirstChild {},
             FirstChild {},
-            FirstChild {},
-            ReplaceWith { root: None, nodes: vec![3, 4] },
+            StoreWithId { id: 5 },
+            CreateTextNode { root: Some(6), text: "hello" },
+            CreateTextNode { root: Some(7), text: "world" },
+            SetLastNode { id: 5 },
+            AppendChildren { root: None, children: vec![6, 7] },
             AppendChildren { root: Some(0), children: vec![2] }
             AppendChildren { root: Some(0), children: vec![2] }
         ]
         ]
     );
     );
@@ -186,30 +187,32 @@ fn create_components() {
             // create template
             // create template
             CreateElement { root: Some(1), tag: "template", children: 3 },
             CreateElement { root: Some(1), tag: "template", children: 3 },
             CreateElement { root: None, tag: "h1", children: 0 },
             CreateElement { root: None, tag: "h1", children: 0 },
-            CreateElement { root: None, tag: "div", children: 1 },
-            CreatePlaceholder { root: None },
+            CreateElement { root: None, tag: "div", children: 0 },
             CreateElement { root: None, tag: "p", children: 0 },
             CreateElement { root: None, tag: "p", children: 0 },
             // clone template
             // clone template
             CloneNodeChildren { id: Some(1), new_ids: vec![2, 3, 4] },
             CloneNodeChildren { id: Some(1), new_ids: vec![2, 3, 4] },
             // update template
             // update template
+            SetLastNode { id: 2 },
+            NextSibling {},
             CreateTextNode { root: Some(5), text: "abc1" },
             CreateTextNode { root: Some(5), text: "abc1" },
             SetLastNode { id: 3 },
             SetLastNode { id: 3 },
-            FirstChild {},
-            ReplaceWith { root: None, nodes: vec![5] },
+            AppendChildren { root: None, children: vec![5] },
             // clone template
             // clone template
             CloneNodeChildren { id: Some(1), new_ids: vec![6, 7, 8] },
             CloneNodeChildren { id: Some(1), new_ids: vec![6, 7, 8] },
+            SetLastNode { id: 6 },
+            NextSibling {},
             // update template
             // update template
             CreateTextNode { root: Some(9), text: "abc2" },
             CreateTextNode { root: Some(9), text: "abc2" },
             SetLastNode { id: 7 },
             SetLastNode { id: 7 },
-            FirstChild {},
-            ReplaceWith { root: None, nodes: vec![9] },
+            AppendChildren { root: None, children: vec![9] },
             // clone template
             // clone template
             CloneNodeChildren { id: Some(1), new_ids: vec![10, 11, 12] },
             CloneNodeChildren { id: Some(1), new_ids: vec![10, 11, 12] },
             // update template
             // update template
+            SetLastNode { id: 10 },
+            NextSibling {},
             CreateTextNode { root: Some(13), text: "abc3" },
             CreateTextNode { root: Some(13), text: "abc3" },
             SetLastNode { id: 11 },
             SetLastNode { id: 11 },
-            FirstChild {},
-            ReplaceWith { root: None, nodes: vec![13] },
+            AppendChildren { root: None, children: vec![13] },
             // add to root
             // add to root
             AppendChildren { root: Some(0), children: vec![2, 3, 4, 6, 7, 8, 10, 11, 12] }
             AppendChildren { root: Some(0), children: vec![2, 3, 4, 6, 7, 8, 10, 11, 12] }
         ]
         ]

+ 1 - 0
packages/dioxus/tests/miri_stress.rs

@@ -20,6 +20,7 @@ fn new_dom<P: 'static + Send>(app: Component<P>, props: P) -> VirtualDom {
 /// This test ensures that if a component aborts early, it is replaced with a placeholder.
 /// This test ensures that if a component aborts early, it is replaced with a placeholder.
 /// In debug, this should also toss a warning.
 /// In debug, this should also toss a warning.
 #[test]
 #[test]
+#[ignore]
 fn test_memory_leak() {
 fn test_memory_leak() {
     fn app(cx: Scope) -> Element {
     fn app(cx: Scope) -> Element {
         let val = cx.use_hook(|| 0);
         let val = cx.use_hook(|| 0);

+ 1 - 0
packages/dioxus/tests/vdom_rebuild.rs

@@ -49,6 +49,7 @@ fn lists_work() {
 }
 }
 
 
 #[test]
 #[test]
+#[ignore]
 fn conditional_rendering() {
 fn conditional_rendering() {
     static App: Component = |cx| {
     static App: Component = |cx| {
         cx.render(rsx!(
         cx.render(rsx!(

+ 1 - 1
packages/fermi/README.md

@@ -77,7 +77,7 @@ fermi = { git = "https://github.com/dioxuslabs/dioxus" }
 ## Running examples
 ## Running examples
 
 
 The examples here use Dioxus Desktop to showcase their functionality. To run an example, use
 The examples here use Dioxus Desktop to showcase their functionality. To run an example, use
-```
+```sh
 $ cargo run --example fermi
 $ cargo run --example fermi
 ```
 ```
 
 

+ 11 - 9
packages/native-core/src/state.rs

@@ -46,6 +46,8 @@ pub(crate) fn union_ordered_iter<T: Ord + Debug>(
 /// Called when the current node's node properties are modified, a child's [ChildDepState] is modified or a child is removed.
 /// Called when the current node's node properties are modified, a child's [ChildDepState] is modified or a child is removed.
 /// Called at most once per update.
 /// Called at most once per update.
 /// ```rust
 /// ```rust
+/// # use dioxus_native_core::node_ref::NodeView;
+/// # use dioxus_native_core::state::ChildDepState;
 /// #[derive(Clone, Copy, PartialEq, Default)]
 /// #[derive(Clone, Copy, PartialEq, Default)]
 /// struct Layout {
 /// struct Layout {
 ///     width: u32,
 ///     width: u32,
@@ -69,8 +71,8 @@ pub(crate) fn union_ordered_iter<T: Ord + Debug>(
 ///             width: c1.width + c2.width,
 ///             width: c1.width + c2.width,
 ///             height: c1.height.max(c2.height)
 ///             height: c1.height.max(c2.height)
 ///         }).unwrap_or_default();
 ///         }).unwrap_or_default();
-///         let changed = new != self.combined;
-///         self = new;
+///         let changed = new != *self;
+///         *self = new;
 ///         changed
 ///         changed
 ///     }
 ///     }
 /// }
 /// }
@@ -120,12 +122,12 @@ pub trait ChildDepState {
 ///     ) -> bool{
 ///     ) -> bool{
 ///         let old = *self;
 ///         let old = *self;
 ///         // If the font size was set on the parent, it is passed down to the current element
 ///         // If the font size was set on the parent, it is passed down to the current element
-///         if let Some(parent) = parent{
-///             *self = parent;
+///         if let Some(parent) = parent {
+///             *self = *parent;
 ///         }
 ///         }
 ///         // If the current node overrides the font size, use that size insead.
 ///         // If the current node overrides the font size, use that size insead.
-///         for attr in node.attributes() {
-///             match attr.name {
+///         for attr in node.attributes().unwrap() {
+///             match attr.attribute.name.as_str() {
 ///                 "font-size" => {
 ///                 "font-size" => {
 ///                     self.0 = attr.value.as_text().unwrap().parse().unwrap();
 ///                     self.0 = attr.value.as_text().unwrap().parse().unwrap();
 ///                 }
 ///                 }
@@ -177,9 +179,9 @@ pub trait ParentDepState {
 ///         siblings: (),
 ///         siblings: (),
 ///         ctx: &(),
 ///         ctx: &(),
 ///     ) -> bool {
 ///     ) -> bool {
-///         let old = self;
-///         for attr in node.attributes() {
-///             match attr.name {
+///         let old = self.clone();
+///         for attr in node.attributes().unwrap() {
+///             match attr.attribute.name.as_str() {
 ///                 "tabindex" => {
 ///                 "tabindex" => {
 ///                     self.0 = attr.value.as_text().unwrap().parse().unwrap();
 ///                     self.0 = attr.value.as_text().unwrap().parse().unwrap();
 ///                 }
 ///                 }