1use std::ops::Deref;
2
3use html5ever::{tendril::StrTendril, Attribute, LocalName, QualName};
4use indexmap::IndexSet;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub enum Node {
8 Document,
10
11 Fragment,
13
14 Doctype(Doctype),
16
17 Comment(Comment),
19
20 Text(Text),
22
23 Element(Element),
25
26 ProcessingInstruction(ProcessingInstruction),
28}
29
30impl Node {
31 pub fn as_element(&self) -> Option<&Element> {
33 match *self {
34 Node::Element(ref e) => Some(e),
35 _ => None,
36 }
37 }
38}
39
40#[derive(Debug, Clone, PartialEq, Eq)]
42pub struct Doctype {
43 pub name: StrTendril,
45
46 pub public_id: StrTendril,
48
49 pub system_id: StrTendril,
51}
52
53#[derive(Debug, Clone, PartialEq, Eq)]
55pub struct Comment {
56 pub comment: StrTendril,
58}
59
60#[derive(Debug, Clone, PartialEq, Eq)]
62pub struct Text {
63 pub text: StrTendril,
65}
66
67pub type Attributes = indexmap::IndexMap<QualName, StrTendril>;
68
69#[derive(Debug, Clone, PartialEq, Eq)]
71pub struct Element {
72 pub name: QualName,
74
75 pub id: Option<LocalName>,
77
78 pub classes: IndexSet<LocalName>,
80
81 pub attrs: Attributes,
83}
84
85impl Element {
86 #[doc(hidden)]
87 pub fn new(name: QualName, attrs: Vec<Attribute>) -> Self {
88 let id = attrs
89 .iter()
90 .find(|a| a.name.local.deref() == "id")
91 .map(|a| LocalName::from(a.value.deref()));
92
93 let classes: IndexSet<LocalName> = attrs
94 .iter()
95 .find(|a| a.name.local.deref() == "class")
96 .map_or(IndexSet::new(), |a| {
97 a.value
98 .deref()
99 .split_whitespace()
100 .map(LocalName::from)
101 .collect()
102 });
103
104 Element {
105 attrs: attrs.into_iter().map(|a| (a.name, a.value)).collect(),
106 name,
107 id,
108 classes,
109 }
110 }
111}
112
113#[derive(Debug, Clone, PartialEq, Eq)]
115pub struct ProcessingInstruction {
116 pub target: StrTendril,
118
119 pub data: StrTendril,
121}