mirror of
https://github.com/yewstack/yew.git
synced 2025-12-08 21:26:25 +00:00
Change access to VList children to a wrapper (#2673)
this should avoid having to manually call recheck_fully_keyed * add mutable accessor to children * fix workflow * fix markdown example * remove recheck_fully_keyed
This commit is contained in:
parent
3760c5f8b5
commit
d7b43bbc26
@ -53,31 +53,34 @@ pub fn render_markdown(src: &str) -> Html {
|
|||||||
pre.add_child(top.into());
|
pre.add_child(top.into());
|
||||||
top = pre;
|
top = pre;
|
||||||
} else if let Tag::Table(aligns) = tag {
|
} else if let Tag::Table(aligns) = tag {
|
||||||
for r in top.children_mut().iter_mut().flat_map(|ch| ch.iter_mut()) {
|
if let Some(top_children) = top.children_mut() {
|
||||||
if let VNode::VTag(ref mut vtag) = r {
|
for r in top_children.children_mut().iter_mut() {
|
||||||
for (i, c) in vtag
|
if let VNode::VTag(ref mut vtag) = r {
|
||||||
.children_mut()
|
if let Some(vtag_children) = vtag.children_mut() {
|
||||||
.iter_mut()
|
for (i, c) in
|
||||||
.flat_map(|ch| ch.iter_mut())
|
vtag_children.children_mut().iter_mut().enumerate()
|
||||||
.enumerate()
|
{
|
||||||
{
|
if let VNode::VTag(ref mut vtag) = c {
|
||||||
if let VNode::VTag(ref mut vtag) = c {
|
match aligns[i] {
|
||||||
match aligns[i] {
|
Alignment::None => {}
|
||||||
Alignment::None => {}
|
Alignment::Left => add_class(vtag, "text-left"),
|
||||||
Alignment::Left => add_class(vtag, "text-left"),
|
Alignment::Center => add_class(vtag, "text-center"),
|
||||||
Alignment::Center => add_class(vtag, "text-center"),
|
Alignment::Right => add_class(vtag, "text-right"),
|
||||||
Alignment::Right => add_class(vtag, "text-right"),
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let Tag::TableHead = tag {
|
} else if let Tag::TableHead = tag {
|
||||||
for c in top.children_mut().iter_mut().flat_map(|ch| ch.iter_mut()) {
|
if let Some(top_children) = top.children_mut() {
|
||||||
if let VNode::VTag(ref mut vtag) = c {
|
for c in top_children.children_mut().iter_mut() {
|
||||||
// TODO
|
if let VNode::VTag(ref mut vtag) = c {
|
||||||
// vtag.tag = "th".into();
|
// TODO
|
||||||
vtag.add_attribute("scope", "col");
|
// vtag.tag = "th".into();
|
||||||
|
vtag.add_attribute("scope", "col");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,13 +29,42 @@ impl Deref for VList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DerefMut for VList {
|
/// Mutable children of a [VList].
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
///
|
||||||
// Caller might change the keys of the VList or add unkeyed children.
|
/// This struct has a `DerefMut` implementations into [`Vec<VNode>`](std::vec::Vec).
|
||||||
// Defensively assume they will.
|
/// Prefer to use immutable access, since this re-checks if all nodes have keys when dropped.
|
||||||
self.fully_keyed = false;
|
pub struct ChildrenMut<'a> {
|
||||||
|
children: &'a mut Vec<VNode>,
|
||||||
|
fully_keyed: &'a mut bool,
|
||||||
|
}
|
||||||
|
|
||||||
&mut self.children
|
impl<'a> Deref for ChildrenMut<'a> {
|
||||||
|
type Target = Vec<VNode>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
self.children
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DerefMut for ChildrenMut<'a> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
*self.fully_keyed = false;
|
||||||
|
self.children
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Drop for ChildrenMut<'a> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if !*self.fully_keyed {
|
||||||
|
// Caller might have changed the keys of the VList or add unkeyed children.
|
||||||
|
*self.fully_keyed = self.children.iter().all(|ch| ch.has_key());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> std::fmt::Debug for ChildrenMut<'a> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_tuple("ChildrenMut").field(&self.children).finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,12 +105,42 @@ impl VList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recheck, if the all the children have keys.
|
/// Get a mutable list of children in this vlist.
|
||||||
///
|
pub fn children_mut(&mut self) -> ChildrenMut<'_> {
|
||||||
/// Run this, after modifying the child list that contained only keyed children prior to the
|
ChildrenMut {
|
||||||
/// mutable dereference.
|
children: &mut self.children,
|
||||||
pub fn recheck_fully_keyed(&mut self) {
|
fully_keyed: &mut self.fully_keyed,
|
||||||
self.fully_keyed = self.children.iter().all(|ch| ch.has_key());
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
use crate::virtual_dom::{VTag, VText};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mutably_change_children() {
|
||||||
|
let mut vlist = VList::new();
|
||||||
|
assert!(vlist.fully_keyed, "should start fully keyed");
|
||||||
|
// add a child that is keyed
|
||||||
|
let mut children = vlist.children_mut();
|
||||||
|
children.push(VNode::VTag({
|
||||||
|
let mut tag = VTag::new("a");
|
||||||
|
tag.key = Some(42u32.into());
|
||||||
|
Box::new(tag)
|
||||||
|
}));
|
||||||
|
drop(children);
|
||||||
|
assert!(vlist.fully_keyed, "should still be fully keyed");
|
||||||
|
assert_eq!(vlist.len(), 1, "should contain 1 child");
|
||||||
|
// now add a child that is not keyed
|
||||||
|
let mut children = vlist.children_mut();
|
||||||
|
children.push(VNode::VText(VText::new("lorem ipsum")));
|
||||||
|
drop(children);
|
||||||
|
assert!(
|
||||||
|
!vlist.fully_keyed,
|
||||||
|
"should not be fully keyed, text tags have no key"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
git2 = "0.14"
|
git2 = "=0.14.2" # see https://github.com/rust-lang/git2-rs/issues/838 fixed with MSRV 1.60
|
||||||
regex = "1"
|
regex = "1"
|
||||||
reqwest = { version = "0.11", features = ["blocking", "json"] }
|
reqwest = { version = "0.11", features = ["blocking", "json"] }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user