Merge pull request #1255 from Demonthos/core-private

Make more of core private
This commit is contained in:
Jonathan Kelley 2023-07-26 18:31:29 -07:00 committed by GitHub
commit 694fc22acb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 92 additions and 55 deletions

View file

@ -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. /// 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 /// 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 /// 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 /// 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 /// 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>>>, 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> { impl<'a> std::fmt::Debug for VComponent<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("VComponent") f.debug_struct("VComponent")
@ -342,14 +349,36 @@ pub struct VText<'a> {
pub value: &'a str, pub value: &'a str,
/// The ID of this node in the real DOM /// 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 /// A placeholder node, used by suspense and fragments
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct VPlaceholder { pub struct VPlaceholder {
/// The ID of this node in the real DOM /// 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 /// An attribute of the TemplateNode, created at compile time
@ -399,11 +428,34 @@ pub struct Attribute<'a> {
/// Doesnt exist in the html spec. Used in Dioxus to denote “style” tags and other attribute groups. /// Doesnt exist in the html spec. Used in Dioxus to denote “style” tags and other attribute groups.
pub namespace: Option<&'static str>, 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 /// An indication of we should always try and set the attribute. Used in controlled components to ensure changes are propagated
pub volatile: bool, 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 /// Any of the built-in values that the Dioxus VirtualDom supports as dynamic attributes on elements

View file

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

View file

@ -10,15 +10,14 @@ macro_rules! impl_event {
$( #[$attr] )* $( #[$attr] )*
#[inline] #[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> { 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 { ::dioxus_core::Attribute::new(
name: stringify!($name), stringify!($name),
value: _cx.listener(move |e: ::dioxus_core::Event<$data>| { _cx.listener(move |e: ::dioxus_core::Event<$data>| {
_f(e).spawn(_cx); _f(e).spawn(_cx);
}), }),
namespace: None, None,
mounted_element: Default::default(), false,
volatile: false, )
}
} }
)* )*
}; };

View file

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

View file

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

View file

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