1use crate::document::Document;
4use markup5ever_rcdom::RcDom;
5use std::io;
6use xml5ever::{driver::parse_document, tendril::TendrilSink};
7
8pub fn parse(source: &str) -> Result<Document, io::Error> {
10 parse_bytes(source.as_bytes())
11}
12
13pub fn parse_bytes(mut source: &[u8]) -> Result<Document, io::Error> {
15 parse_document(RcDom::default(), Default::default())
16 .from_utf8()
17 .read_from(&mut source)
18 .map(|dom| Document::from_markup5ever(&dom.document))
19}
20
21#[cfg(test)]
22mod tests {
23 use super::*;
24 use crate::document::{Element, Node};
25 use alloc::sync::Arc;
26 use pretty_assertions::assert_eq;
27
28 #[test]
29 fn parse_empty_string() {
30 assert_eq!(parse("").unwrap(), Document::new(vec![]));
31 }
32
33 #[test]
34 fn parse_svg_document() {
35 assert_eq!(
36 parse(concat!(
37 r#"<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">"#,
38 r#"<a href="/foo"><rect/></a>"#,
39 r#"<image xlink:href="/bar.png"/>"#,
40 "</svg>"
41 ))
42 .unwrap(),
43 Document::new(vec![Arc::new(Node::Element(Element::new(
44 "svg".to_string(),
45 vec![],
47 vec![
48 Arc::new(Node::Element(Element::new(
49 "a".to_string(),
50 vec![("href".to_string(), "/foo".to_string())],
51 vec![Arc::new(Node::Element(Element::new(
52 "rect".to_string(),
53 vec![],
54 vec![]
55 )))],
56 ))),
57 Arc::new(Node::Element(Element::new(
58 "image".to_string(),
59 vec![("href".to_string(), "/bar.png".to_string())],
60 vec![],
61 ))),
62 ],
63 )))])
64 );
65 }
66
67 #[test]
68 fn preserve_element_name_case() {
69 assert_eq!(
70 parse("<svg><foreignObject/></svg>").unwrap(),
71 Document::new(vec![Arc::new(Node::Element(Element::new(
72 "svg".to_string(),
73 vec![],
74 vec![Arc::new(Node::Element(Element::new(
75 "foreignObject".to_string(),
76 vec![],
77 vec![]
78 )))],
79 )))])
80 );
81 }
82
83 #[test]
84 fn keep_html_element_in_svg_element() {
85 assert_eq!(
86 parse("<svg><p>foo</p></svg>").unwrap(),
87 Document::new(vec![Arc::new(Node::Element(Element::new(
88 "svg".to_string(),
89 vec![],
90 vec![Arc::new(Node::Element(Element::new(
91 "p".to_string(),
92 vec![],
93 vec![Arc::new(Node::Text("foo".to_string()))],
94 )))],
95 )))])
96 );
97 }
98
99 #[test]
100 fn ignore_processing_instructions() {
101 assert_eq!(
102 parse(r#"<?xml version="1.0"?><svg/>"#).unwrap(),
103 Document::new(vec![Arc::new(Node::Element(Element::new(
104 "svg".to_string(),
105 vec![],
106 vec![],
107 )))])
108 );
109 }
110}