浏览代码

Merge pull request #1255 from Demonthos/core-private

Make more of core private
Jonathan Kelley 1 年之前
父节点
当前提交
694fc22acb

+ 60 - 8
packages/core/src/nodes.rs

@@ -312,19 +312,26 @@ pub struct VComponent<'a> {
     /// Internally, this is used as a guarantee. Externally, this might be incorrect, so don't count on it.
     ///
     /// This flag is assumed by the [`crate::Properties`] trait which is unsafe to implement
-    pub static_props: bool,
+    pub(crate) static_props: bool,
 
     /// The assigned Scope for this component
-    pub scope: Cell<Option<ScopeId>>,
+    pub(crate) scope: Cell<Option<ScopeId>>,
 
     /// The function pointer of the component, known at compile time
     ///
     /// It is possible that components get folded at comppile time, so these shouldn't be really used as a key
-    pub render_fn: *const (),
+    pub(crate) render_fn: *const (),
 
     pub(crate) props: RefCell<Option<Box<dyn AnyProps<'a> + 'a>>>,
 }
 
+impl<'a> VComponent<'a> {
+    /// Get the scope that this component is mounted to
+    pub fn mounted_scope(&self) -> Option<ScopeId> {
+        self.scope.get()
+    }
+}
+
 impl<'a> std::fmt::Debug for VComponent<'a> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         f.debug_struct("VComponent")
@@ -342,14 +349,36 @@ pub struct VText<'a> {
     pub value: &'a str,
 
     /// The ID of this node in the real DOM
-    pub id: Cell<Option<ElementId>>,
+    pub(crate) id: Cell<Option<ElementId>>,
+}
+
+impl<'a> VText<'a> {
+    /// Create a new VText
+    pub fn new(value: &'a str) -> Self {
+        Self {
+            value,
+            id: Default::default(),
+        }
+    }
+
+    /// Get the mounted ID of this node
+    pub fn mounted_element(&self) -> Option<ElementId> {
+        self.id.get()
+    }
 }
 
 /// A placeholder node, used by suspense and fragments
 #[derive(Debug, Default)]
 pub struct VPlaceholder {
     /// The ID of this node in the real DOM
-    pub id: Cell<Option<ElementId>>,
+    pub(crate) id: Cell<Option<ElementId>>,
+}
+
+impl VPlaceholder {
+    /// Get the mounted ID of this node
+    pub fn mounted_element(&self) -> Option<ElementId> {
+        self.id.get()
+    }
 }
 
 /// An attribute of the TemplateNode, created at compile time
@@ -399,11 +428,34 @@ pub struct Attribute<'a> {
     /// Doesn’t exist in the html spec. Used in Dioxus to denote “style” tags and other attribute groups.
     pub namespace: Option<&'static str>,
 
-    /// The element in the DOM that this attribute belongs to
-    pub mounted_element: Cell<ElementId>,
-
     /// An indication of we should always try and set the attribute. Used in controlled components to ensure changes are propagated
     pub volatile: bool,
+
+    /// The element in the DOM that this attribute belongs to
+    pub(crate) mounted_element: Cell<ElementId>,
+}
+
+impl<'a> Attribute<'a> {
+    /// Create a new attribute
+    pub fn new(
+        name: &'a str,
+        value: AttributeValue<'a>,
+        namespace: Option<&'static str>,
+        volatile: bool,
+    ) -> Self {
+        Self {
+            name,
+            value,
+            namespace,
+            volatile,
+            mounted_element: Cell::new(ElementId::default()),
+        }
+    }
+
+    /// Get the element that this attribute is mounted to
+    pub fn mounted_element(&self) -> ElementId {
+        self.mounted_element.get()
+    }
 }
 
 /// Any of the built-in values that the Dioxus VirtualDom supports as dynamic attributes on elements

+ 9 - 19
packages/core/tests/fuzzing.rs

@@ -217,23 +217,16 @@ fn create_random_dynamic_attr(cx: &ScopeState) -> Attribute {
         5 => AttributeValue::None,
         6 => {
             let value = cx.listener(|e: Event<String>| println!("{:?}", e));
-            return Attribute {
-                name: "ondata",
-                value,
-                namespace: None,
-                mounted_element: Default::default(),
-                volatile: false,
-            };
+            return Attribute::new("ondata", value, None, false);
         }
         _ => unreachable!(),
     };
-    Attribute {
-        name: Box::leak(format!("attr{}", rand::random::<usize>()).into_boxed_str()),
+    Attribute::new(
+        Box::leak(format!("attr{}", rand::random::<usize>()).into_boxed_str()),
         value,
-        namespace: random_ns(),
-        mounted_element: Default::default(),
-        volatile: rand::random(),
-    }
+        random_ns(),
+        rand::random(),
+    )
 }
 
 static mut TEMPLATE_COUNT: usize = 0;
@@ -288,12 +281,9 @@ fn create_random_element(cx: Scope<DepthProps>) -> Element {
                     let dynamic_nodes: Vec<_> = dynamic_node_types
                         .iter()
                         .map(|ty| match ty {
-                            DynamicNodeType::Text => DynamicNode::Text(VText {
-                                value: Box::leak(
-                                    format!("{}", rand::random::<usize>()).into_boxed_str(),
-                                ),
-                                id: Default::default(),
-                            }),
+                            DynamicNodeType::Text => DynamicNode::Text(VText::new(Box::leak(
+                                format!("{}", rand::random::<usize>()).into_boxed_str(),
+                            ))),
                             DynamicNodeType::Other => {
                                 create_random_dynamic_node(cx, cx.props.depth + 1)
                             }

+ 6 - 7
packages/html/src/events.rs

@@ -10,15 +10,14 @@ macro_rules! impl_event {
             $( #[$attr] )*
             #[inline]
             pub fn $name<'a, E: crate::EventReturn<T>, T>(_cx: &'a ::dioxus_core::ScopeState, mut _f: impl FnMut(::dioxus_core::Event<$data>) -> E + 'a) -> ::dioxus_core::Attribute<'a> {
-                ::dioxus_core::Attribute {
-                    name: stringify!($name),
-                    value: _cx.listener(move |e: ::dioxus_core::Event<$data>| {
+                ::dioxus_core::Attribute::new(
+                    stringify!($name),
+                    _cx.listener(move |e: ::dioxus_core::Event<$data>| {
                         _f(e).spawn(_cx);
                     }),
-                    namespace: None,
-                    mounted_element: Default::default(),
-                    volatile: false,
-                }
+                    None,
+                    false,
+                )
             }
         )*
     };

+ 8 - 12
packages/native-core/tests/fuzzing.rs

@@ -217,13 +217,12 @@ fn create_random_dynamic_attr(cx: &ScopeState) -> Attribute {
         // Listener(RefCell<Option<ListenerCb<'a>>>),
         _ => unreachable!(),
     };
-    Attribute {
-        name: Box::leak(format!("attr{}", rand::random::<usize>()).into_boxed_str()),
+    Attribute::new(
+        Box::leak(format!("attr{}", rand::random::<usize>()).into_boxed_str()),
         value,
-        namespace: random_ns(),
-        mounted_element: Default::default(),
-        volatile: rand::random(),
-    }
+        random_ns(),
+        rand::random(),
+    )
 }
 
 static mut TEMPLATE_COUNT: usize = 0;
@@ -263,12 +262,9 @@ fn create_random_element(cx: Scope<DepthProps>) -> Element {
                     let dynamic_nodes: Vec<_> = dynamic_node_types
                         .iter()
                         .map(|ty| match ty {
-                            DynamicNodeType::Text => DynamicNode::Text(VText {
-                                value: Box::leak(
-                                    format!("{}", rand::random::<usize>()).into_boxed_str(),
-                                ),
-                                id: Default::default(),
-                            }),
+                            DynamicNodeType::Text => DynamicNode::Text(VText::new(Box::leak(
+                                format!("{}", rand::random::<usize>()).into_boxed_str(),
+                            ))),
                             DynamicNodeType::Other => {
                                 create_random_dynamic_node(cx, cx.props.depth + 1)
                             }

+ 1 - 1
packages/ssr/src/renderer.rs

@@ -102,7 +102,7 @@ impl Renderer {
                         if self.skip_components {
                             write!(buf, "<{}><{}/>", node.name, node.name)?;
                         } else {
-                            let id = node.scope.get().unwrap();
+                            let id = node.mounted_scope().unwrap();
                             let scope = dom.get_scope(id).unwrap();
                             let node = scope.root_node();
                             match node {

+ 8 - 8
packages/web/src/rehydrate.rs

@@ -1,7 +1,6 @@
 use crate::dom::WebsysDom;
 use dioxus_core::{
-    AttributeValue, DynamicNode, ElementId, ScopeState, TemplateNode, VNode, VPlaceholder, VText,
-    VirtualDom,
+    AttributeValue, DynamicNode, ElementId, ScopeState, TemplateNode, VNode, VirtualDom,
 };
 use dioxus_html::event_bubbles;
 use wasm_bindgen::JsCast;
@@ -130,7 +129,7 @@ impl WebsysDom {
                     if let dioxus_core::TemplateAttribute::Dynamic { id } = attr {
                         let attribute = &vnode.dynamic_attrs[*id];
                         let value = &attribute.value;
-                        let id = attribute.mounted_element.get();
+                        let id = attribute.mounted_element();
                         mounted_id = Some(id);
                         let name = attribute.name;
                         if let AttributeValue::Listener(_) = value {
@@ -211,7 +210,8 @@ impl WebsysDom {
             }
         }
         match dynamic {
-            dioxus_core::DynamicNode::Text(VText { id, .. }) => {
+            dioxus_core::DynamicNode::Text(text) => {
+                let id = text.mounted_element();
                 // skip comment separator before node
                 if cfg!(debug_assertions) {
                     assert!(current_child
@@ -227,7 +227,7 @@ impl WebsysDom {
 
                 set_node(
                     hydrated,
-                    id.get().ok_or(VNodeNotInitialized)?,
+                    id.ok_or(VNodeNotInitialized)?,
                     current_child.clone()?,
                 );
                 *current_child = current_child
@@ -251,10 +251,10 @@ impl WebsysDom {
 
                 *last_node_was_static_text = false;
             }
-            dioxus_core::DynamicNode::Placeholder(VPlaceholder { id, .. }) => {
+            dioxus_core::DynamicNode::Placeholder(placeholder) => {
                 set_node(
                     hydrated,
-                    id.get().ok_or(VNodeNotInitialized)?,
+                    placeholder.mounted_element().ok_or(VNodeNotInitialized)?,
                     current_child.clone()?,
                 );
                 *current_child = current_child
@@ -265,7 +265,7 @@ impl WebsysDom {
                 *last_node_was_static_text = false;
             }
             dioxus_core::DynamicNode::Component(comp) => {
-                let scope = comp.scope.get().ok_or(VNodeNotInitialized)?;
+                let scope = comp.mounted_scope().ok_or(VNodeNotInitialized)?;
                 self.rehydrate_scope(
                     dom.get_scope(scope).unwrap(),
                     current_child,