vertigo/dom/
dom_comment.rs

1use crate::{
2    computed::{
3        struct_mut::{ValueMut, VecMut},
4        DropResource,
5    },
6    driver_module::get_driver_dom,
7    DomNode,
8};
9
10use super::dom_id::DomId;
11
12/// A Real DOM representative - comment kind
13pub struct DomComment {
14    pub id_dom: DomId,
15    subscriptions: VecMut<DropResource>,
16}
17
18impl DomComment {
19    pub fn new(text: impl Into<String>) -> DomComment {
20        let text = text.into();
21        let id_dom = DomId::default();
22
23        get_driver_dom().create_comment(id_dom, text);
24
25        DomComment {
26            id_dom,
27            subscriptions: VecMut::new(),
28        }
29    }
30
31    pub fn new_marker<F: Fn(DomId, DomId) -> Option<DropResource> + 'static>(
32        comment_value: &'static str,
33        mount: F,
34    ) -> DomComment {
35        let id_comment = DomId::default();
36
37        let when_mount = {
38            let current_client: ValueMut<Option<DropResource>> = ValueMut::new(None);
39
40            move |parent_id| {
41                let client = mount(parent_id, id_comment);
42
43                current_client.change(|current| {
44                    *current = client;
45                });
46            }
47        };
48
49        let drop_callback = get_driver_dom().node_parent(id_comment, when_mount);
50
51        let subscriptions = VecMut::new();
52
53        subscriptions.push(drop_callback);
54
55        get_driver_dom().create_comment(id_comment, comment_value);
56
57        DomComment {
58            id_dom: id_comment,
59            subscriptions,
60        }
61    }
62
63    pub fn id_dom(&self) -> DomId {
64        self.id_dom
65    }
66
67    pub fn add_subscription(&self, client: DropResource) {
68        self.subscriptions.push(client);
69    }
70
71    pub fn dom_fragment(mut list: Vec<DomNode>) -> DomComment {
72        list.reverse();
73
74        Self::new_marker("list dom node", move |parent_id, comment_id| {
75            let mut prev_node = comment_id;
76
77            for node in list.iter() {
78                let node_id = node.id_dom();
79                get_driver_dom().insert_before(parent_id, node_id, Some(prev_node));
80                prev_node = node_id;
81            }
82
83            None
84        })
85    }
86}
87
88impl Drop for DomComment {
89    fn drop(&mut self) {
90        get_driver_dom().remove_comment(self.id_dom);
91    }
92}