1 use html5ever::serialize::TraversalScope::*;
2 use html5ever::serialize::{serialize, Serialize, SerializeOpts, Serializer, TraversalScope};
3 use html5ever::QualName;
4 use std::fs::File;
5 use std::io::{Result, Write};
6 use std::path::Path;
7 use std::string::ToString;
8 
9 use crate::tree::{NodeData, NodeRef};
10 
11 impl Serialize for NodeRef {
serialize<S: Serializer>( &self, serializer: &mut S, traversal_scope: TraversalScope, ) -> Result<()>12     fn serialize<S: Serializer>(
13         &self,
14         serializer: &mut S,
15         traversal_scope: TraversalScope,
16     ) -> Result<()> {
17         match (traversal_scope, self.data()) {
18             (ref scope, &NodeData::Element(ref element)) => {
19                 if *scope == IncludeNode {
20                     let attrs = element.attributes.borrow();
21 
22                     // Unfortunately we need to allocate something to hold these &'a QualName
23                     let attrs = attrs
24                         .map
25                         .iter()
26                         .map(|(name, attr)| {
27                             (
28                                 QualName::new(
29                                     attr.prefix.clone(),
30                                     name.ns.clone(),
31                                     name.local.clone(),
32                                 ),
33                                 &attr.value,
34                             )
35                         })
36                         .collect::<Vec<_>>();
37 
38                     serializer.start_elem(
39                         element.name.clone(),
40                         attrs.iter().map(|&(ref name, value)| (name, &**value)),
41                     )?
42                 }
43 
44                 for child in self.children() {
45                     Serialize::serialize(&child, serializer, IncludeNode)?
46                 }
47 
48                 if *scope == IncludeNode {
49                     serializer.end_elem(element.name.clone())?
50                 }
51                 Ok(())
52             }
53 
54             (_, &NodeData::DocumentFragment) | (_, &NodeData::Document(_)) => {
55                 for child in self.children() {
56                     Serialize::serialize(&child, serializer, IncludeNode)?
57                 }
58                 Ok(())
59             }
60 
61             (ChildrenOnly(_), _) => Ok(()),
62 
63             (IncludeNode, &NodeData::Doctype(ref doctype)) => {
64                 serializer.write_doctype(&doctype.name)
65             }
66             (IncludeNode, &NodeData::Text(ref text)) => serializer.write_text(&text.borrow()),
67             (IncludeNode, &NodeData::Comment(ref text)) => serializer.write_comment(&text.borrow()),
68             (IncludeNode, &NodeData::ProcessingInstruction(ref contents)) => {
69                 let contents = contents.borrow();
70                 serializer.write_processing_instruction(&contents.0, &contents.1)
71             }
72         }
73     }
74 }
75 
76 impl ToString for NodeRef {
77     #[inline]
to_string(&self) -> String78     fn to_string(&self) -> String {
79         let mut u8_vec = Vec::new();
80         self.serialize(&mut u8_vec).unwrap();
81         String::from_utf8(u8_vec).unwrap()
82     }
83 }
84 
85 impl NodeRef {
86     /// Serialize this node and its descendants in HTML syntax to the given stream.
87     #[inline]
serialize<W: Write>(&self, writer: &mut W) -> Result<()>88     pub fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
89         serialize(
90             writer,
91             self,
92             SerializeOpts {
93                 traversal_scope: IncludeNode,
94                 ..Default::default()
95             },
96         )
97     }
98 
99     /// Serialize this node and its descendants in HTML syntax to a new file at the given path.
100     #[inline]
serialize_to_file<P: AsRef<Path>>(&self, path: P) -> Result<()>101     pub fn serialize_to_file<P: AsRef<Path>>(&self, path: P) -> Result<()> {
102         let mut file = File::create(&path)?;
103         self.serialize(&mut file)
104     }
105 }
106