1use super::document::Document;
2use html5ever::{parse_document, tendril::TendrilSink};
3use markup5ever_rcdom::RcDom;
4use std::io;
5
6pub fn parse(source: &str) -> Result<Document, io::Error> {
8 parse_bytes(source.as_bytes())
9}
10
11pub fn parse_bytes(mut source: &[u8]) -> Result<Document, io::Error> {
13 parse_document(RcDom::default(), Default::default())
14 .from_utf8()
15 .read_from(&mut source)
16 .map(|dom| Document::from_markup5ever(&dom.document))
17}
18
19#[cfg(test)]
20mod tests {
21 use super::{
22 super::{element::Element, node::Node},
23 *,
24 };
25 use alloc::sync::Arc;
26 use pretty_assertions::assert_eq;
27
28 #[test]
29 fn parse_empty_string() {
30 assert_eq!(
31 parse("").unwrap(),
32 Document::new(vec![Arc::new(Node::Element(Element::new(
33 "html".to_string(),
34 vec![],
35 vec![
36 Arc::new(Node::Element(Element::new(
37 "head".to_string(),
38 vec![],
39 vec![]
40 ))),
41 Arc::new(Node::Element(Element::new(
42 "body".to_string(),
43 vec![],
44 vec![]
45 ))),
46 ],
47 )))])
48 );
49 }
50
51 #[test]
52 fn parse_simple_html() {
53 assert_eq!(
54 parse("<html><body><p>Hello</p></body></html>").unwrap(),
55 Document::new(vec![Arc::new(Node::Element(Element::new(
56 "html".to_string(),
57 vec![],
58 vec![
59 Arc::new(Node::Element(Element::new(
60 "head".to_string(),
61 vec![],
62 vec![]
63 ))),
64 Arc::new(Node::Element(Element::new(
65 "body".to_string(),
66 vec![],
67 vec![Arc::new(Node::Element(Element::new(
68 "p".to_string(),
69 vec![],
70 vec![Arc::new(Node::Text("Hello".to_string()))],
71 )))],
72 ))),
73 ],
74 )))])
75 );
76 }
77
78 #[test]
79 fn parse_with_attributes() {
80 assert_eq!(
81 parse("<html><body><p class=\"foo\">Hello</p></body></html>").unwrap(),
82 Document::new(vec![Arc::new(Node::Element(Element::new(
83 "html".to_string(),
84 vec![],
85 vec![
86 Arc::new(Node::Element(Element::new(
87 "head".to_string(),
88 vec![],
89 vec![]
90 ))),
91 Arc::new(Node::Element(Element::new(
92 "body".to_string(),
93 vec![],
94 vec![Arc::new(Node::Element(Element::new(
95 "p".to_string(),
96 vec![("class".to_string(), "foo".to_string())],
97 vec![Arc::new(Node::Text("Hello".to_string()))],
98 )))],
99 ))),
100 ],
101 )))])
102 );
103 }
104
105 #[test]
106 fn parse_svg_document() {
107 assert_eq!(
108 parse(concat!(
109 r#"<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">"#,
110 r#"<a href="/foo"><rect/></a>"#,
111 r#"<image xlink:href="/bar.png"/>"#,
112 "</svg>"
113 ))
114 .unwrap(),
115 Document::new(vec![Arc::new(Node::Element(Element::new(
116 "html".to_string(),
117 vec![],
118 vec![
119 Arc::new(Node::Element(Element::new(
120 "head".to_string(),
121 vec![],
122 vec![]
123 ))),
124 Arc::new(Node::Element(Element::new(
125 "body".to_string(),
126 vec![],
127 vec![Arc::new(Node::Element(Element::new(
128 "svg".to_string(),
129 vec![
130 (
131 "xmlns".to_string(),
132 "http://www.w3.org/2000/svg".to_string()
133 ),
134 (
135 "xlink".to_string(),
136 "http://www.w3.org/1999/xlink".to_string()
137 ),
138 ],
139 vec![
140 Arc::new(Node::Element(Element::new(
141 "a".to_string(),
142 vec![("href".to_string(), "/foo".to_string())],
143 vec![Arc::new(Node::Element(Element::new(
144 "rect".to_string(),
145 vec![],
146 vec![]
147 )))],
148 ))),
149 Arc::new(Node::Element(Element::new(
150 "image".to_string(),
151 vec![("href".to_string(), "/bar.png".to_string())],
152 vec![],
153 ))),
154 ],
155 )))],
156 ))),
157 ],
158 )))])
159 );
160 }
161
162 #[test]
163 fn ignore_comments() {
164 assert_eq!(
165 parse("<html><body><!-- comment --><p>Hello</p></body></html>").unwrap(),
166 Document::new(vec![Arc::new(Node::Element(Element::new(
167 "html".to_string(),
168 vec![],
169 vec![
170 Arc::new(Node::Element(Element::new(
171 "head".to_string(),
172 vec![],
173 vec![]
174 ))),
175 Arc::new(Node::Element(Element::new(
176 "body".to_string(),
177 vec![],
178 vec![Arc::new(Node::Element(Element::new(
179 "p".to_string(),
180 vec![],
181 vec![Arc::new(Node::Text("Hello".to_string()))],
182 )))],
183 ))),
184 ],
185 )))])
186 );
187 }
188}