1
1
use super :: {
2
- attributes:: Attributes ,
3
2
document:: Document ,
4
3
node:: { ElementData , NodeData , NodeId } ,
5
4
} ;
6
- use html5ever:: { local_name, namespace_url, ns, QualName } ;
5
+ use html5ever:: {
6
+ local_name,
7
+ serialize:: { serialize, Serialize , SerializeOpts , Serializer , TraversalScope } ,
8
+ } ;
7
9
use std:: { io, io:: Write } ;
8
10
9
11
pub ( crate ) fn serialize_to < W : Write > (
@@ -18,8 +20,7 @@ pub(crate) fn serialize_to<W: Write>(
18
20
keep_style_tags,
19
21
keep_link_tags,
20
22
) ;
21
- let mut serializer = HtmlSerializer :: new ( writer) ;
22
- sink. serialize ( & mut serializer)
23
+ serialize ( writer, & sink, SerializeOpts :: default ( ) )
23
24
}
24
25
25
26
/// Intermediary structure for serializing an HTML document.
@@ -69,23 +70,37 @@ impl<'a> Sink<'a> {
69
70
false
70
71
}
71
72
}
72
- fn serialize_children < W : Write > ( & self , serializer : & mut HtmlSerializer < W > ) -> io:: Result < ( ) > {
73
+ fn serialize_children < S : Serializer > ( & self , serializer : & mut S ) -> io:: Result < ( ) > {
73
74
for child in self . document . children ( self . node ) {
74
- self . for_node ( child) . serialize ( serializer) ?;
75
+ self . for_node ( child)
76
+ . serialize ( serializer, TraversalScope :: IncludeNode ) ?;
75
77
}
76
78
Ok ( ( ) )
77
79
}
78
- fn serialize < W : Write > ( & self , serializer : & mut HtmlSerializer < W > ) -> io:: Result < ( ) > {
80
+ }
81
+
82
+ impl < ' a > Serialize for Sink < ' a > {
83
+ fn serialize < S > ( & self , serializer : & mut S , _: TraversalScope ) -> io:: Result < ( ) >
84
+ where
85
+ S : Serializer ,
86
+ {
79
87
match self . data ( ) {
80
88
NodeData :: Element { element, .. } => {
81
89
if self . should_skip_element ( element) {
82
90
return Ok ( ( ) ) ;
83
91
}
84
- serializer. start_elem ( & element. name , & element. attributes ) ?;
92
+ serializer. start_elem (
93
+ element. name . clone ( ) ,
94
+ element
95
+ . attributes
96
+ . map
97
+ . iter ( )
98
+ . map ( |( key, value) | ( key, & * * value) ) ,
99
+ ) ?;
85
100
86
101
self . serialize_children ( serializer) ?;
87
102
88
- serializer. end_elem ( & element. name ) ?;
103
+ serializer. end_elem ( element. name . clone ( ) ) ?;
89
104
Ok ( ( ) )
90
105
}
91
106
NodeData :: Document => self . serialize_children ( serializer) ,
@@ -99,130 +114,6 @@ impl<'a> Sink<'a> {
99
114
}
100
115
}
101
116
102
- struct ElemInfo {
103
- ignore_children : bool ,
104
- }
105
-
106
- struct HtmlSerializer < Wr : Write > {
107
- writer : Wr ,
108
- stack : Vec < ElemInfo > ,
109
- }
110
-
111
- impl < Wr : Write > HtmlSerializer < Wr > {
112
- fn new ( writer : Wr ) -> Self {
113
- HtmlSerializer {
114
- writer,
115
- stack : vec ! [ ElemInfo {
116
- ignore_children: false ,
117
- } ] ,
118
- }
119
- }
120
-
121
- fn parent ( & mut self ) -> & mut ElemInfo {
122
- self . stack . last_mut ( ) . expect ( "Stack is empty" )
123
- }
124
-
125
- fn start_elem ( & mut self , name : & QualName , attrs : & Attributes ) -> io:: Result < ( ) > {
126
- if self . parent ( ) . ignore_children {
127
- self . stack . push ( ElemInfo {
128
- ignore_children : true ,
129
- } ) ;
130
- return Ok ( ( ) ) ;
131
- }
132
-
133
- self . writer . write_all ( b"<" ) ?;
134
- self . writer . write_all ( name. local . as_bytes ( ) ) ?;
135
- for ( name, value) in & attrs. map {
136
- self . writer . write_all ( b" " ) ?;
137
-
138
- match name. ns {
139
- ns ! ( ) => ( ) ,
140
- ns ! ( xml) => self . writer . write_all ( b"xml:" ) ?,
141
- ns ! ( xmlns) => {
142
- if name. local != local_name ! ( "xmlns" ) {
143
- self . writer . write_all ( b"xmlns:" ) ?;
144
- }
145
- }
146
- ns ! ( xlink) => self . writer . write_all ( b"xlink:" ) ?,
147
- _ => {
148
- self . writer . write_all ( b"unknown_namespace:" ) ?;
149
- }
150
- }
151
-
152
- self . writer . write_all ( name. local . as_bytes ( ) ) ?;
153
- self . writer . write_all ( b"=\" " ) ?;
154
- self . writer . write_all ( value. as_bytes ( ) ) ?;
155
- self . writer . write_all ( b"\" " ) ?;
156
- }
157
- self . writer . write_all ( b">" ) ?;
158
-
159
- let ignore_children = name. ns == ns ! ( html)
160
- && matches ! (
161
- name. local,
162
- local_name!( "area" )
163
- | local_name!( "base" )
164
- | local_name!( "basefont" )
165
- | local_name!( "bgsound" )
166
- | local_name!( "br" )
167
- | local_name!( "col" )
168
- | local_name!( "embed" )
169
- | local_name!( "frame" )
170
- | local_name!( "hr" )
171
- | local_name!( "img" )
172
- | local_name!( "input" )
173
- | local_name!( "keygen" )
174
- | local_name!( "link" )
175
- | local_name!( "meta" )
176
- | local_name!( "param" )
177
- | local_name!( "source" )
178
- | local_name!( "track" )
179
- | local_name!( "wbr" )
180
- ) ;
181
-
182
- self . stack . push ( ElemInfo { ignore_children } ) ;
183
-
184
- Ok ( ( ) )
185
- }
186
-
187
- fn end_elem ( & mut self , name : & QualName ) -> io:: Result < ( ) > {
188
- let info = match self . stack . pop ( ) {
189
- Some ( info) => info,
190
- _ => panic ! ( "no ElemInfo" ) ,
191
- } ;
192
- if info. ignore_children {
193
- return Ok ( ( ) ) ;
194
- }
195
-
196
- self . writer . write_all ( b"</" ) ?;
197
- self . writer . write_all ( name. local . as_bytes ( ) ) ?;
198
- self . writer . write_all ( b">" )
199
- }
200
-
201
- fn write_text ( & mut self , text : & str ) -> io:: Result < ( ) > {
202
- self . writer . write_all ( text. as_bytes ( ) )
203
- }
204
-
205
- fn write_comment ( & mut self , text : & str ) -> io:: Result < ( ) > {
206
- self . writer . write_all ( b"<!--" ) ?;
207
- self . writer . write_all ( text. as_bytes ( ) ) ?;
208
- self . writer . write_all ( b"-->" )
209
- }
210
-
211
- fn write_doctype ( & mut self , name : & str ) -> io:: Result < ( ) > {
212
- self . writer . write_all ( b"<!DOCTYPE " ) ?;
213
- self . writer . write_all ( name. as_bytes ( ) ) ?;
214
- self . writer . write_all ( b">" )
215
- }
216
-
217
- fn write_processing_instruction ( & mut self , target : & str , data : & str ) -> io:: Result < ( ) > {
218
- self . writer . write_all ( b"<?" ) ?;
219
- self . writer . write_all ( target. as_bytes ( ) ) ?;
220
- self . writer . write_all ( b" " ) ?;
221
- self . writer . write_all ( data. as_bytes ( ) ) ?;
222
- self . writer . write_all ( b">" )
223
- }
224
- }
225
-
226
117
#[ cfg( test) ]
227
118
mod tests {
228
119
use super :: Document ;
0 commit comments