diff --git a/packages/core/Cargo.toml b/packages/core/Cargo.toml
index 47652e262..7158b3970 100644
--- a/packages/core/Cargo.toml
+++ b/packages/core/Cargo.toml
@@ -44,4 +44,4 @@ pretty_assertions = "1.3.0"
[features]
default = []
-serialize = ["serde"]
+serialize = ["serde"]
\ No newline at end of file
diff --git a/packages/core/src/arena.rs b/packages/core/src/arena.rs
index 36323730a..a11fc69ba 100644
--- a/packages/core/src/arena.rs
+++ b/packages/core/src/arena.rs
@@ -153,11 +153,17 @@ impl VirtualDom {
});
// Now that all the references are gone, we can safely drop our own references in our listeners.
- let mut listeners = scope.listeners.borrow_mut();
+ let mut listeners = scope.attributes_to_drop.borrow_mut();
listeners.drain(..).for_each(|listener| {
let listener = unsafe { &*listener };
- if let AttributeValue::Listener(l) = &listener.value {
- _ = l.take();
+ match &listener.value {
+ AttributeValue::Listener(l) => {
+ _ = l.take();
+ }
+ AttributeValue::Any(a) => {
+ _ = a.take();
+ }
+ _ => (),
}
});
}
diff --git a/packages/core/src/create.rs b/packages/core/src/create.rs
index f54684410..7e5633f12 100644
--- a/packages/core/src/create.rs
+++ b/packages/core/src/create.rs
@@ -1,5 +1,5 @@
use crate::any_props::AnyProps;
-use crate::innerlude::{VComponent, VPlaceholder, VText};
+use crate::innerlude::{BorrowedAttributeValue, VComponent, VPlaceholder, VText};
use crate::mutations::Mutation;
use crate::mutations::Mutation::*;
use crate::nodes::VNode;
@@ -285,7 +285,7 @@ impl<'b> VirtualDom {
}
}
- fn write_attribute(&mut self, attribute: &crate::Attribute, id: ElementId) {
+ fn write_attribute(&mut self, attribute: &'b crate::Attribute<'b>, id: ElementId) {
// Make sure we set the attribute's associated id
attribute.mounted_element.set(id);
@@ -293,9 +293,17 @@ impl<'b> VirtualDom {
let unbounded_name: &str = unsafe { std::mem::transmute(attribute.name) };
match &attribute.value {
- AttributeValue::Text(value) => {
+ AttributeValue::Listener(_) => {
+ self.mutations.push(NewEventListener {
+ // all listeners start with "on"
+ name: &unbounded_name[2..],
+ id,
+ })
+ }
+ _ => {
// Safety: we promise not to re-alias this text later on after committing it to the mutation
- let unbounded_value: &str = unsafe { std::mem::transmute(*value) };
+ let value: BorrowedAttributeValue<'b> = (&attribute.value).into();
+ let unbounded_value = unsafe { std::mem::transmute(value) };
self.mutations.push(SetAttribute {
name: unbounded_name,
@@ -304,22 +312,6 @@ impl<'b> VirtualDom {
id,
})
}
- AttributeValue::Bool(value) => self.mutations.push(SetBoolAttribute {
- name: unbounded_name,
- value: *value,
- id,
- }),
- AttributeValue::Listener(_) => {
- self.mutations.push(NewEventListener {
- // all listeners start with "on"
- name: &unbounded_name[2..],
- id,
- })
- }
- AttributeValue::Float(_) => todo!(),
- AttributeValue::Int(_) => todo!(),
- AttributeValue::Any(_) => todo!(),
- AttributeValue::None => todo!(),
}
}
diff --git a/packages/core/src/diff.rs b/packages/core/src/diff.rs
index efd534fe7..7227ee6e7 100644
--- a/packages/core/src/diff.rs
+++ b/packages/core/src/diff.rs
@@ -1,7 +1,7 @@
use crate::{
any_props::AnyProps,
arena::ElementId,
- innerlude::{DirtyScope, VComponent, VPlaceholder, VText},
+ innerlude::{BorrowedAttributeValue, DirtyScope, VComponent, VPlaceholder, VText},
mutations::Mutation,
nodes::RenderReturn,
nodes::{DynamicNode, VNode},
@@ -150,22 +150,16 @@ impl<'b> VirtualDom {
};
}
- fn update_attribute(&mut self, right_attr: &Attribute, left_attr: &Attribute) {
- // todo: add more types of attribute values
- match right_attr.value {
- AttributeValue::Text(text) => {
- let name = unsafe { std::mem::transmute(left_attr.name) };
- let value = unsafe { std::mem::transmute(text) };
- self.mutations.push(Mutation::SetAttribute {
- id: left_attr.mounted_element.get(),
- ns: right_attr.namespace,
- name,
- value,
- });
- }
- // todo: more types of attribute values
- _ => todo!("other attribute types"),
- }
+ fn update_attribute(&mut self, right_attr: &'b Attribute<'b>, left_attr: &'b Attribute) {
+ let name = unsafe { std::mem::transmute(left_attr.name) };
+ let value: BorrowedAttributeValue<'b> = (&right_attr.value).into();
+ let value = unsafe { std::mem::transmute(value) };
+ self.mutations.push(Mutation::SetAttribute {
+ id: left_attr.mounted_element.get(),
+ ns: right_attr.namespace,
+ name,
+ value,
+ });
}
fn diff_vcomponent(
diff --git a/packages/core/src/lib.rs b/packages/core/src/lib.rs
index f13c20b43..c4f162580 100644
--- a/packages/core/src/lib.rs
+++ b/packages/core/src/lib.rs
@@ -70,10 +70,10 @@ pub(crate) mod innerlude {
}
pub use crate::innerlude::{
- fc_to_builder, Attribute, AttributeValue, CapturedError, Component, DynamicNode, Element,
- ElementId, Event, Fragment, IntoDynNode, LazyNodes, Mutation, Mutations, Properties,
- RenderReturn, Scope, ScopeId, ScopeState, Scoped, SuspenseContext, TaskId, Template,
- TemplateAttribute, TemplateNode, VComponent, VNode, VText, VirtualDom,
+ fc_to_builder, AnyValue, Attribute, AttributeValue, BorrowedAttributeValue, CapturedError,
+ Component, DynamicNode, Element, ElementId, Event, Fragment, IntoDynNode, LazyNodes, Mutation,
+ Mutations, Properties, RenderReturn, Scope, ScopeId, ScopeState, Scoped, SuspenseContext,
+ TaskId, Template, TemplateAttribute, TemplateNode, VComponent, VNode, VText, VirtualDom,
};
/// The purpose of this module is to alleviate imports of many common types
@@ -81,9 +81,9 @@ pub use crate::innerlude::{
/// This includes types like [`Scope`], [`Element`], and [`Component`].
pub mod prelude {
pub use crate::innerlude::{
- fc_to_builder, Component, Element, Event, EventHandler, Fragment, LazyNodes, Properties,
- Scope, ScopeId, ScopeState, Scoped, TaskId, Template, TemplateAttribute, TemplateNode,
- Throw, VNode, VirtualDom,
+ fc_to_builder, AnyValue, Component, Element, Event, EventHandler, Fragment,
+ IntoAttributeValue, LazyNodes, Properties, Scope, ScopeId, ScopeState, Scoped, TaskId,
+ Template, TemplateAttribute, TemplateNode, Throw, VNode, VirtualDom,
};
}
diff --git a/packages/core/src/mutations.rs b/packages/core/src/mutations.rs
index f8553cd46..551069c45 100644
--- a/packages/core/src/mutations.rs
+++ b/packages/core/src/mutations.rs
@@ -1,6 +1,6 @@
use rustc_hash::FxHashSet;
-use crate::{arena::ElementId, ScopeId, Template};
+use crate::{arena::ElementId, innerlude::BorrowedAttributeValue, ScopeId, Template};
/// A container for all the relevant steps to modify the Real DOM
///
@@ -61,7 +61,7 @@ impl<'a> Mutations<'a> {
derive(serde::Serialize, serde::Deserialize),
serde(tag = "type")
)]
-#[derive(Debug, PartialEq, Eq)]
+#[derive(Debug, PartialEq)]
pub enum Mutation<'a> {
/// Add these m children to the target element
AppendChildren {
@@ -193,8 +193,9 @@ pub enum Mutation<'a> {
SetAttribute {
/// The name of the attribute to set.
name: &'a str,
+
/// The value of the attribute.
- value: &'a str,
+ value: BorrowedAttributeValue<'a>,
/// The ID of the node to set the attribute of.
id: ElementId,
@@ -204,18 +205,6 @@ pub enum Mutation<'a> {
ns: Option<&'a str>,
},
- /// Set the value of a node's attribute.
- SetBoolAttribute {
- /// The name of the attribute to set.
- name: &'a str,
-
- /// The value of the attribute.
- value: bool,
-
- /// The ID of the node to set the attribute of.
- id: ElementId,
- },
-
/// Set the textcontent of a node.
SetText {
/// The textcontent of the node
diff --git a/packages/core/src/nodes.rs b/packages/core/src/nodes.rs
index dee2f32b3..bb9f6734b 100644
--- a/packages/core/src/nodes.rs
+++ b/packages/core/src/nodes.rs
@@ -5,8 +5,8 @@ use bumpalo::boxed::Box as BumpBox;
use bumpalo::Bump;
use std::{
any::{Any, TypeId},
- cell::{Cell, RefCell, UnsafeCell},
- fmt::Arguments,
+ cell::{self, Cell, RefCell, UnsafeCell},
+ fmt::{Arguments, Debug},
future::Future,
};
@@ -523,13 +523,108 @@ pub enum AttributeValue<'a> {
Listener(RefCell