Selaa lähdekoodia

Merge branch 'master' into jk/templates-v3

Jonathan Kelley 2 vuotta sitten
vanhempi
commit
112c954e00

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

@@ -69,6 +69,7 @@ impl Buffer {
             BodyNode::Component(component) => self.write_component(component),
             BodyNode::DynamicText(text) => self.write_text(text),
             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]
 tokio = { version = "*", features = ["full"] }
 
+[dev-dependencies]
+dioxus = { path = "../dioxus" }
+
 [features]
 default = []
 serialize = ["serde"]

+ 4 - 0
packages/desktop/Cargo.toml

@@ -36,6 +36,10 @@ dunce = "1.0.2"
 interprocess = { version = "1.1.1" }
 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]
 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 futures_channel::mpsc::UnboundedReceiver;
 use futures_util::StreamExt;
+#[cfg(target_os = "ios")]
+use objc::runtime::Object;
 use std::{
     collections::HashMap,
     sync::Arc,
@@ -20,6 +22,8 @@ pub(super) struct DesktopController {
     pub(super) pending_edits: Arc<Mutex<Vec<String>>>,
     pub(super) quit_app_on_close: bool,
     pub(super) is_ready: Arc<AtomicBool>,
+    #[cfg(target_os = "ios")]
+    pub(super) views: Vec<*mut Object>,
 }
 
 impl DesktopController {
@@ -88,6 +92,8 @@ impl DesktopController {
             webviews: HashMap::new(),
             is_ready: Arc::new(AtomicBool::new(false)),
             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 wry::application::event_loop::ControlFlow;
 use wry::application::event_loop::EventLoopProxy;
+#[cfg(target_os = "ios")]
+use wry::application::platform::ios::WindowExtIOS;
 use wry::application::window::Fullscreen as WryFullscreen;
 
 use UserWindowEvent::*;
@@ -143,6 +145,18 @@ impl DesktopContext {
     pub fn eval(&self, script: impl std::string::ToString) {
         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)]
@@ -173,6 +187,11 @@ pub enum UserWindowEvent {
     DevTool,
 
     Eval(String),
+
+    #[cfg(target_os = "ios")]
+    PushView(objc_id::ShareId<objc::runtime::Object>),
+    #[cfg(target_os = "ios")]
+    PopView,
 }
 
 pub(super) fn handler(
@@ -242,5 +261,41 @@ pub(super) fn handler(
                 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 },
             CreateTextNode { root: None, text: "Hello, world!" },
             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
             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 },
             FirstChild {},
+            StoreWithId { id: 3 },
             FirstChild {},
             NextSibling {},
+            StoreWithId { id: 4 },
             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] }
         ]
     );
@@ -186,30 +187,32 @@ fn create_components() {
             // create template
             CreateElement { root: Some(1), tag: "template", children: 3 },
             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 },
             // clone template
             CloneNodeChildren { id: Some(1), new_ids: vec![2, 3, 4] },
             // update template
+            SetLastNode { id: 2 },
+            NextSibling {},
             CreateTextNode { root: Some(5), text: "abc1" },
             SetLastNode { id: 3 },
-            FirstChild {},
-            ReplaceWith { root: None, nodes: vec![5] },
+            AppendChildren { root: None, children: vec![5] },
             // clone template
             CloneNodeChildren { id: Some(1), new_ids: vec![6, 7, 8] },
+            SetLastNode { id: 6 },
+            NextSibling {},
             // update template
             CreateTextNode { root: Some(9), text: "abc2" },
             SetLastNode { id: 7 },
-            FirstChild {},
-            ReplaceWith { root: None, nodes: vec![9] },
+            AppendChildren { root: None, children: vec![9] },
             // clone template
             CloneNodeChildren { id: Some(1), new_ids: vec![10, 11, 12] },
             // update template
+            SetLastNode { id: 10 },
+            NextSibling {},
             CreateTextNode { root: Some(13), text: "abc3" },
             SetLastNode { id: 11 },
-            FirstChild {},
-            ReplaceWith { root: None, nodes: vec![13] },
+            AppendChildren { root: None, children: vec![13] },
             // add to root
             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.
 /// In debug, this should also toss a warning.
 #[test]
+#[ignore]
 fn test_memory_leak() {
     fn app(cx: Scope) -> Element {
         let val = cx.use_hook(|| 0);

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

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

+ 1 - 1
packages/fermi/README.md

@@ -77,7 +77,7 @@ fermi = { git = "https://github.com/dioxuslabs/dioxus" }
 ## Running examples
 
 The examples here use Dioxus Desktop to showcase their functionality. To run an example, use
-```
+```sh
 $ 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 at most once per update.
 /// ```rust
+/// # use dioxus_native_core::node_ref::NodeView;
+/// # use dioxus_native_core::state::ChildDepState;
 /// #[derive(Clone, Copy, PartialEq, Default)]
 /// struct Layout {
 ///     width: u32,
@@ -69,8 +71,8 @@ pub(crate) fn union_ordered_iter<T: Ord + Debug>(
 ///             width: c1.width + c2.width,
 ///             height: c1.height.max(c2.height)
 ///         }).unwrap_or_default();
-///         let changed = new != self.combined;
-///         self = new;
+///         let changed = new != *self;
+///         *self = new;
 ///         changed
 ///     }
 /// }
@@ -120,12 +122,12 @@ pub trait ChildDepState {
 ///     ) -> bool{
 ///         let old = *self;
 ///         // 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.
-///         for attr in node.attributes() {
-///             match attr.name {
+///         for attr in node.attributes().unwrap() {
+///             match attr.attribute.name.as_str() {
 ///                 "font-size" => {
 ///                     self.0 = attr.value.as_text().unwrap().parse().unwrap();
 ///                 }
@@ -177,9 +179,9 @@ pub trait ParentDepState {
 ///         siblings: (),
 ///         ctx: &(),
 ///     ) -> 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" => {
 ///                     self.0 = attr.value.as_text().unwrap().parse().unwrap();
 ///                 }