virtual_node/
velement.rs

1use std::collections::HashMap;
2use std::fmt;
3
4use crate::event::Events;
5use crate::VirtualNode;
6
7pub use self::attribute_value::*;
8pub use self::special_attributes::*;
9
10mod attribute_value;
11mod special_attributes;
12
13#[derive(PartialEq)]
14pub struct VElement {
15    /// The HTML tag, such as "div"
16    pub tag: String,
17    /// HTML attributes such as id, class, style, etc
18    pub attrs: HashMap<String, AttributeValue>,
19    /// Events that will get added to your real DOM element via `.addEventListener`
20    ///
21    /// Events natively handled in HTML such as onclick, onchange, oninput and others
22    /// can be found in [`VElement.known_events`]
23    pub events: Events,
24    /// The children of this `VirtualNode`. So a <div> <em></em> </div> structure would
25    /// have a parent div and one child, em.
26    pub children: Vec<VirtualNode>,
27    /// See [`SpecialAttributes`]
28    pub special_attributes: SpecialAttributes,
29}
30
31impl VElement {
32    pub fn new<S>(tag: S) -> Self
33    where
34        S: Into<String>,
35    {
36        VElement {
37            tag: tag.into(),
38            attrs: HashMap::new(),
39            events: Events::new(),
40            children: vec![],
41            special_attributes: SpecialAttributes::default(),
42        }
43    }
44}
45
46impl fmt::Debug for VElement {
47    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
48        write!(
49            f,
50            "Element(<{}>, attrs: {:?}, children: {:?})",
51            self.tag, self.attrs, self.children,
52        )
53    }
54}
55
56impl fmt::Display for VElement {
57    // Turn a VElement and all of it's children (recursively) into an HTML string
58    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
59        write!(f, "<{}", self.tag).unwrap();
60
61        for (attr, value) in self.attrs.iter() {
62            match value {
63                AttributeValue::String(value_str) => {
64                    write!(f, r#" {}="{}""#, attr, value_str)?;
65                }
66                AttributeValue::Bool(value_bool) => {
67                    if *value_bool {
68                        write!(f, " {}", attr)?;
69                    }
70                }
71            }
72        }
73
74        write!(f, ">")?;
75
76        for child in self.children.iter() {
77            write!(f, "{}", child.to_string())?;
78        }
79
80        if !html_validation::is_self_closing(&self.tag) {
81            write!(f, "</{}>", self.tag)?;
82        }
83
84        Ok(())
85    }
86}