Merge branch 'master' into jk/templates-v3
This commit is contained in:
commit
112c954e00
10 files changed
+101
-25
No files matched your search
@@ -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(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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![],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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] }
|
||||
]
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -49,6 +49,7 @@ fn lists_work() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn conditional_rendering() {
|
||||
static App: Component = |cx| {
|
||||
cx.render(rsx!(
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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();
|
||||
/// }
|
||||
|
||||
Reference in new issue
Block a user