1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
use crate::{KeyedElement, Mailbox, NonKeyedElement, Text}; use std::rc::Rc; use web_sys as web; #[derive(Debug)] pub enum Node<Message: 'static> { Element(NonKeyedElement<Message>), KeyedElement(KeyedElement<Message>), Text(Text), } impl<Message: 'static> Node<Message> { pub fn create(&mut self, mailbox: Mailbox<Message>) -> web::Node { match self { Node::Element(element) => element.create(mailbox).into(), Node::KeyedElement(keyed_element) => keyed_element.create(mailbox).into(), Node::Text(text) => text.create().into(), } } pub fn patch(&mut self, old: &mut Self, mailbox: Mailbox<Message>) -> web::Node { match (self, old) { (Node::Element(ref mut e1), Node::Element(ref mut e2)) => e1.patch(e2, mailbox).into(), (Node::KeyedElement(ref mut e1), Node::KeyedElement(ref mut e2)) => { e1.patch(e2, mailbox).into() } (Node::Text(ref mut t1), Node::Text(ref mut t2)) => t1.patch(t2).into(), (self_, old) => { let old_node = old.node().expect("old.node"); let parent_node = old_node.parent_node().expect("old_node.parent_node"); let node = self_.create(mailbox); parent_node .replace_child(&node, &old_node) .expect("replace_child"); node } } } pub fn node(&self) -> Option<web::Node> { match self { Node::Element(element) => element.node().map(Into::into), Node::KeyedElement(keyed_element) => keyed_element.node().map(Into::into), Node::Text(text) => text.node().map(Into::into), } } pub fn remove(&self) { if let Some(node) = self.node() { if let Some(parent_node) = node.parent_node() { parent_node.remove_child(&node).unwrap(); } } } pub fn map<NewMessage: 'static>( self, f: impl Fn(Message) -> NewMessage + 'static, ) -> Node<NewMessage> { self.do_map(Rc::new(f)) } pub(crate) fn do_map<NewMessage: 'static>( self, f: Rc<impl Fn(Message) -> NewMessage + 'static>, ) -> Node<NewMessage> { match self { Node::Element(element) => Node::Element(element.do_map(f)), Node::KeyedElement(keyed_element) => Node::KeyedElement(keyed_element.do_map(f)), Node::Text(text) => Node::Text(text), } } } impl<Message> From<Text> for Node<Message> { fn from(text: Text) -> Self { Node::Text(text) } } impl<Message: 'static> From<NonKeyedElement<Message>> for Node<Message> { fn from(element: NonKeyedElement<Message>) -> Self { Node::Element(element) } } impl<Message: 'static> From<KeyedElement<Message>> for Node<Message> { fn from(keyed_element: KeyedElement<Message>) -> Self { Node::KeyedElement(keyed_element) } } impl<Message, T: std::fmt::Display> From<T> for Node<Message> { fn from(t: T) -> Self { Text::new(t.to_string()).into() } }