Merge pull request #708 from Demonthos/support-optional-attrtibutes
Support optional attributes
This commit is contained in:
4 files changed
+46
-29
No files matched your search
@@ -5,7 +5,7 @@ use bumpalo::boxed::Box as BumpBox;
|
|||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
use std::{
|
use std::{
|
||||||
any::{Any, TypeId},
|
any::{Any, TypeId},
|
||||||
cell::{self, Cell, RefCell, UnsafeCell},
|
cell::{Cell, RefCell, UnsafeCell},
|
||||||
fmt::{Arguments, Debug},
|
fmt::{Arguments, Debug},
|
||||||
future::Future,
|
future::Future,
|
||||||
};
|
};
|
||||||
@@ -611,7 +611,7 @@ impl PartialEq for BorrowedAttributeValue<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serialize")]
|
#[cfg(feature = "serialize")]
|
||||||
fn serialize_any_value<S>(_: &cell::Ref<'_, dyn AnyValue>, _: S) -> Result<S::Ok, S::Error>
|
fn serialize_any_value<S>(_: &std::cell::Ref<'_, dyn AnyValue>, _: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
S: serde::Serializer,
|
S: serde::Serializer,
|
||||||
{
|
{
|
||||||
@@ -619,7 +619,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serialize")]
|
#[cfg(feature = "serialize")]
|
||||||
fn deserialize_any_value<'de, 'a, D>(_: D) -> Result<cell::Ref<'a, dyn AnyValue>, D::Error>
|
fn deserialize_any_value<'de, 'a, D>(_: D) -> Result<std::cell::Ref<'a, dyn AnyValue>, D::Error>
|
||||||
where
|
where
|
||||||
D: serde::Deserializer<'de>,
|
D: serde::Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -888,3 +888,12 @@ impl<'a> IntoAttributeValue<'a> for BumpBox<'a, dyn AnyValue> {
|
|||||||
AttributeValue::Any(RefCell::new(Some(self)))
|
AttributeValue::Any(RefCell::new(Some(self)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, T: IntoAttributeValue<'a>> IntoAttributeValue<'a> for Option<T> {
|
||||||
|
fn into_value(self, bump: &'a Bump) -> AttributeValue<'a> {
|
||||||
|
match self {
|
||||||
|
Some(val) => val.into_value(bump),
|
||||||
|
None => AttributeValue::None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -144,8 +144,15 @@ class Interpreter {
|
|||||||
this.nodes[root].textContent = text;
|
this.nodes[root].textContent = text;
|
||||||
}
|
}
|
||||||
SetAttribute(id, field, value, ns) {
|
SetAttribute(id, field, value, ns) {
|
||||||
const node = this.nodes[id];
|
console.log("set attribute", id, field, value, ns);
|
||||||
this.SetAttributeInner(node, field, value, ns);
|
|
||||||
|
if (value === null) {
|
||||||
|
this.RemoveAttribute(id, field, ns);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const node = this.nodes[id];
|
||||||
|
this.SetAttributeInner(node, field, value, ns);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SetAttributeInner(node, field, value, ns) {
|
SetAttributeInner(node, field, value, ns) {
|
||||||
const name = field;
|
const name = field;
|
||||||
@@ -334,9 +341,6 @@ class Interpreter {
|
|||||||
case "SetAttribute":
|
case "SetAttribute":
|
||||||
this.SetAttribute(edit.id, edit.name, edit.value, edit.ns);
|
this.SetAttribute(edit.id, edit.name, edit.value, edit.ns);
|
||||||
break;
|
break;
|
||||||
case "SetBoolAttribute":
|
|
||||||
this.SetAttribute(edit.id, edit.name, edit.value, edit.ns);
|
|
||||||
break;
|
|
||||||
case "RemoveAttribute":
|
case "RemoveAttribute":
|
||||||
this.RemoveAttribute(edit.id, edit.name, edit.ns);
|
this.RemoveAttribute(edit.id, edit.name, edit.ns);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ pub enum OwnedAttributeValue<V: FromAnyValue = ()> {
|
|||||||
Int(i64),
|
Int(i64),
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
Custom(V),
|
Custom(V),
|
||||||
None,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait FromAnyValue {
|
pub trait FromAnyValue {
|
||||||
@@ -99,7 +98,6 @@ impl<V: FromAnyValue> Debug for OwnedAttributeValue<V> {
|
|||||||
Self::Int(arg0) => f.debug_tuple("Int").field(arg0).finish(),
|
Self::Int(arg0) => f.debug_tuple("Int").field(arg0).finish(),
|
||||||
Self::Bool(arg0) => f.debug_tuple("Bool").field(arg0).finish(),
|
Self::Bool(arg0) => f.debug_tuple("Bool").field(arg0).finish(),
|
||||||
Self::Custom(_) => f.debug_tuple("Any").finish(),
|
Self::Custom(_) => f.debug_tuple("Any").finish(),
|
||||||
Self::None => write!(f, "None"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,7 +110,7 @@ impl<V: FromAnyValue> From<BorrowedAttributeValue<'_>> for OwnedAttributeValue<V
|
|||||||
BorrowedAttributeValue::Int(int) => Self::Int(int),
|
BorrowedAttributeValue::Int(int) => Self::Int(int),
|
||||||
BorrowedAttributeValue::Bool(bool) => Self::Bool(bool),
|
BorrowedAttributeValue::Bool(bool) => Self::Bool(bool),
|
||||||
BorrowedAttributeValue::Any(any) => Self::Custom(V::from_any_value(&*any)),
|
BorrowedAttributeValue::Any(any) => Self::Custom(V::from_any_value(&*any)),
|
||||||
BorrowedAttributeValue::None => Self::None,
|
BorrowedAttributeValue::None => panic!("None attribute values result in removing the attribute, not converting it to a None value.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,13 +144,6 @@ impl<V: FromAnyValue> OwnedAttributeValue<V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_none(&self) -> Option<()> {
|
|
||||||
match self {
|
|
||||||
OwnedAttributeValue::None => Some(()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_custom(&self) -> Option<&V> {
|
pub fn as_custom(&self) -> Option<&V> {
|
||||||
match self {
|
match self {
|
||||||
OwnedAttributeValue::Custom(custom) => Some(custom),
|
OwnedAttributeValue::Custom(custom) => Some(custom),
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use dioxus_core::{ElementId, Mutations, TemplateNode};
|
use dioxus_core::{BorrowedAttributeValue, ElementId, Mutations, TemplateNode};
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::ops::{Deref, DerefMut, Index, IndexMut};
|
use std::ops::{Deref, DerefMut, Index, IndexMut};
|
||||||
@@ -264,19 +264,32 @@ impl<S: State> RealDom<S> {
|
|||||||
let node_id = self.element_to_node_id(id);
|
let node_id = self.element_to_node_id(id);
|
||||||
let node = self.tree.get_mut(node_id).unwrap();
|
let node = self.tree.get_mut(node_id).unwrap();
|
||||||
if let NodeType::Element { attributes, .. } = &mut node.node_data.node_type {
|
if let NodeType::Element { attributes, .. } = &mut node.node_data.node_type {
|
||||||
attributes.insert(
|
if let BorrowedAttributeValue::None = &value {
|
||||||
OwnedAttributeDiscription {
|
attributes.remove(&OwnedAttributeDiscription {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
namespace: ns.map(|s| s.to_string()),
|
namespace: ns.map(|s| s.to_string()),
|
||||||
volatile: false,
|
volatile: false,
|
||||||
},
|
});
|
||||||
OwnedAttributeValue::from(value),
|
mark_dirty(
|
||||||
);
|
node_id,
|
||||||
mark_dirty(
|
NodeMask::new_with_attrs(AttributeMask::single(name)),
|
||||||
node_id,
|
&mut nodes_updated,
|
||||||
NodeMask::new_with_attrs(AttributeMask::single(name)),
|
);
|
||||||
&mut nodes_updated,
|
} else {
|
||||||
);
|
attributes.insert(
|
||||||
|
OwnedAttributeDiscription {
|
||||||
|
name: name.to_string(),
|
||||||
|
namespace: ns.map(|s| s.to_string()),
|
||||||
|
volatile: false,
|
||||||
|
},
|
||||||
|
OwnedAttributeValue::from(value),
|
||||||
|
);
|
||||||
|
mark_dirty(
|
||||||
|
node_id,
|
||||||
|
NodeMask::new_with_attrs(AttributeMask::single(name)),
|
||||||
|
&mut nodes_updated,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetText { value, id } => {
|
SetText { value, id } => {
|
||||||
|
|||||||
Reference in new issue
Block a user