@@ -5,34 +5,47 @@ use ego_tree::NodeId;
5
5
use html5ever:: tendril:: StrTendril ;
6
6
use html5ever:: tree_builder:: { ElementFlags , NodeOrText , QuirksMode , TreeSink } ;
7
7
use html5ever:: Attribute ;
8
- use html5ever:: { ExpandedName , QualName } ;
8
+ use html5ever:: QualName ;
9
9
use std:: borrow:: Cow ;
10
+ use std:: cell:: { Ref , RefCell } ;
11
+
12
+ /// Wraps `Html` instances as sinks to drive parsing
13
+ #[ derive( Debug ) ]
14
+ pub struct HtmlTreeSink ( RefCell < Html > ) ;
15
+
16
+ impl HtmlTreeSink {
17
+ /// Wrap a `Html`instance as a sink to drive parsing
18
+ pub fn new ( html : Html ) -> Self {
19
+ Self ( RefCell :: new ( html) )
20
+ }
21
+ }
10
22
11
23
/// Note: does not support the `<template>` element.
12
- impl TreeSink for Html {
13
- type Output = Self ;
24
+ impl TreeSink for HtmlTreeSink {
25
+ type Output = Html ;
14
26
type Handle = NodeId ;
27
+ type ElemName < ' a > = Ref < ' a , QualName > ;
15
28
16
- fn finish ( self ) -> Self {
17
- self
29
+ fn finish ( self ) -> Html {
30
+ self . 0 . into_inner ( )
18
31
}
19
32
20
33
// Signal a parse error.
21
- fn parse_error ( & mut self , msg : Cow < ' static , str > ) {
34
+ fn parse_error ( & self , msg : Cow < ' static , str > ) {
22
35
#[ cfg( feature = "errors" ) ]
23
- self . errors . push ( msg) ;
36
+ self . 0 . borrow_mut ( ) . errors . push ( msg) ;
24
37
#[ cfg( not( feature = "errors" ) ) ]
25
38
let _ = msg;
26
39
}
27
40
28
41
// Set the document's quirks mode.
29
- fn set_quirks_mode ( & mut self , mode : QuirksMode ) {
30
- self . quirks_mode = mode;
42
+ fn set_quirks_mode ( & self , mode : QuirksMode ) {
43
+ self . 0 . borrow_mut ( ) . quirks_mode = mode;
31
44
}
32
45
33
46
// Get a handle to the Document node.
34
- fn get_document ( & mut self ) -> Self :: Handle {
35
- self . tree . root ( ) . id ( )
47
+ fn get_document ( & self ) -> Self :: Handle {
48
+ self . 0 . borrow ( ) . tree . root ( ) . id ( )
36
49
}
37
50
38
51
// Do two handles refer to the same node?
@@ -43,15 +56,17 @@ impl TreeSink for Html {
43
56
// What is the name of this element?
44
57
//
45
58
// Should never be called on a non-element node; feel free to panic!.
46
- fn elem_name ( & self , target : & Self :: Handle ) -> ExpandedName {
47
- self . tree
48
- . get ( * target)
49
- . unwrap ( )
50
- . value ( )
51
- . as_element ( )
52
- . unwrap ( )
53
- . name
54
- . expanded ( )
59
+ fn elem_name < ' a > ( & ' a self , target : & Self :: Handle ) -> Ref < ' a , QualName > {
60
+ Ref :: map ( self . 0 . borrow ( ) , |this| {
61
+ & this
62
+ . tree
63
+ . get ( * target)
64
+ . unwrap ( )
65
+ . value ( )
66
+ . as_element ( )
67
+ . unwrap ( )
68
+ . name
69
+ } )
55
70
}
56
71
57
72
// Create an element.
@@ -60,14 +75,15 @@ impl TreeSink for Html {
60
75
// associated document fragment called the "template contents" should also be created. Later
61
76
// calls to self.get_template_contents() with that given element return it.
62
77
fn create_element (
63
- & mut self ,
78
+ & self ,
64
79
name : QualName ,
65
80
attrs : Vec < Attribute > ,
66
81
_flags : ElementFlags ,
67
82
) -> Self :: Handle {
68
83
let fragment = name. expanded ( ) == expanded_name ! ( html "template" ) ;
69
84
70
- let mut node = self . tree . orphan ( Node :: Element ( Element :: new ( name, attrs) ) ) ;
85
+ let mut this = self . 0 . borrow_mut ( ) ;
86
+ let mut node = this. tree . orphan ( Node :: Element ( Element :: new ( name, attrs) ) ) ;
71
87
72
88
if fragment {
73
89
node. append ( Node :: Fragment ) ;
@@ -77,8 +93,10 @@ impl TreeSink for Html {
77
93
}
78
94
79
95
// Create a comment node.
80
- fn create_comment ( & mut self , text : StrTendril ) -> Self :: Handle {
81
- self . tree
96
+ fn create_comment ( & self , text : StrTendril ) -> Self :: Handle {
97
+ self . 0
98
+ . borrow_mut ( )
99
+ . tree
82
100
. orphan ( Node :: Comment ( Comment {
83
101
comment : make_tendril ( text) ,
84
102
} ) )
@@ -87,7 +105,7 @@ impl TreeSink for Html {
87
105
88
106
// Append a DOCTYPE element to the Document node.
89
107
fn append_doctype_to_document (
90
- & mut self ,
108
+ & self ,
91
109
name : StrTendril ,
92
110
public_id : StrTendril ,
93
111
system_id : StrTendril ,
@@ -100,15 +118,20 @@ impl TreeSink for Html {
100
118
public_id,
101
119
system_id,
102
120
} ;
103
- self . tree . root_mut ( ) . append ( Node :: Doctype ( doctype) ) ;
121
+ self . 0
122
+ . borrow_mut ( )
123
+ . tree
124
+ . root_mut ( )
125
+ . append ( Node :: Doctype ( doctype) ) ;
104
126
}
105
127
106
128
// Append a node as the last child of the given node. If this would produce adjacent sibling
107
129
// text nodes, it should concatenate the text instead.
108
130
//
109
131
// The child node will not already have a parent.
110
- fn append ( & mut self , parent : & Self :: Handle , child : NodeOrText < Self :: Handle > ) {
111
- let mut parent = self . tree . get_mut ( * parent) . unwrap ( ) ;
132
+ fn append ( & self , parent : & Self :: Handle , child : NodeOrText < Self :: Handle > ) {
133
+ let mut this = self . 0 . borrow_mut ( ) ;
134
+ let mut parent = this. tree . get_mut ( * parent) . unwrap ( ) ;
112
135
113
136
match child {
114
137
NodeOrText :: AppendNode ( id) => {
@@ -141,16 +164,14 @@ impl TreeSink for Html {
141
164
// also a text node, the two should be merged, as in the behavior of append.
142
165
//
143
166
// NB: new_node may have an old parent, from which it should be removed.
144
- fn append_before_sibling (
145
- & mut self ,
146
- sibling : & Self :: Handle ,
147
- new_node : NodeOrText < Self :: Handle > ,
148
- ) {
167
+ fn append_before_sibling ( & self , sibling : & Self :: Handle , new_node : NodeOrText < Self :: Handle > ) {
168
+ let mut this = self . 0 . borrow_mut ( ) ;
169
+
149
170
if let NodeOrText :: AppendNode ( id) = new_node {
150
- self . tree . get_mut ( id) . unwrap ( ) . detach ( ) ;
171
+ this . tree . get_mut ( id) . unwrap ( ) . detach ( ) ;
151
172
}
152
173
153
- let mut sibling = self . tree . get_mut ( * sibling) . unwrap ( ) ;
174
+ let mut sibling = this . tree . get_mut ( * sibling) . unwrap ( ) ;
154
175
if sibling. parent ( ) . is_some ( ) {
155
176
match new_node {
156
177
NodeOrText :: AppendNode ( id) => {
@@ -180,22 +201,25 @@ impl TreeSink for Html {
180
201
}
181
202
182
203
// Detach the given node from its parent.
183
- fn remove_from_parent ( & mut self , target : & Self :: Handle ) {
184
- self . tree . get_mut ( * target) . unwrap ( ) . detach ( ) ;
204
+ fn remove_from_parent ( & self , target : & Self :: Handle ) {
205
+ self . 0 . borrow_mut ( ) . tree . get_mut ( * target) . unwrap ( ) . detach ( ) ;
185
206
}
186
207
187
208
// Remove all the children from node and append them to new_parent.
188
- fn reparent_children ( & mut self , node : & Self :: Handle , new_parent : & Self :: Handle ) {
189
- self . tree
209
+ fn reparent_children ( & self , node : & Self :: Handle , new_parent : & Self :: Handle ) {
210
+ self . 0
211
+ . borrow_mut ( )
212
+ . tree
190
213
. get_mut ( * new_parent)
191
214
. unwrap ( )
192
215
. reparent_from_id_append ( * node) ;
193
216
}
194
217
195
218
// Add each attribute to the given element, if no attribute with that name already exists. The
196
219
// tree builder promises this will never be called with something else than an element.
197
- fn add_attrs_if_missing ( & mut self , target : & Self :: Handle , attrs : Vec < Attribute > ) {
198
- let mut node = self . tree . get_mut ( * target) . unwrap ( ) ;
220
+ fn add_attrs_if_missing ( & self , target : & Self :: Handle , attrs : Vec < Attribute > ) {
221
+ let mut this = self . 0 . borrow_mut ( ) ;
222
+ let mut node = this. tree . get_mut ( * target) . unwrap ( ) ;
199
223
let element = match * node. value ( ) {
200
224
Node :: Element ( ref mut e) => e,
201
225
_ => unreachable ! ( ) ,
@@ -213,18 +237,27 @@ impl TreeSink for Html {
213
237
//
214
238
// The tree builder promises this will never be called with something else than a template
215
239
// element.
216
- fn get_template_contents ( & mut self , target : & Self :: Handle ) -> Self :: Handle {
217
- self . tree . get ( * target) . unwrap ( ) . first_child ( ) . unwrap ( ) . id ( )
240
+ fn get_template_contents ( & self , target : & Self :: Handle ) -> Self :: Handle {
241
+ self . 0
242
+ . borrow ( )
243
+ . tree
244
+ . get ( * target)
245
+ . unwrap ( )
246
+ . first_child ( )
247
+ . unwrap ( )
248
+ . id ( )
218
249
}
219
250
220
251
// Mark a HTML <script> element as "already started".
221
- fn mark_script_already_started ( & mut self , _node : & Self :: Handle ) { }
252
+ fn mark_script_already_started ( & self , _node : & Self :: Handle ) { }
222
253
223
254
// Create Processing Instruction.
224
- fn create_pi ( & mut self , target : StrTendril , data : StrTendril ) -> Self :: Handle {
255
+ fn create_pi ( & self , target : StrTendril , data : StrTendril ) -> Self :: Handle {
225
256
let target = make_tendril ( target) ;
226
257
let data = make_tendril ( data) ;
227
- self . tree
258
+ self . 0
259
+ . borrow_mut ( )
260
+ . tree
228
261
. orphan ( Node :: ProcessingInstruction ( ProcessingInstruction {
229
262
target,
230
263
data,
@@ -233,12 +266,21 @@ impl TreeSink for Html {
233
266
}
234
267
235
268
fn append_based_on_parent_node (
236
- & mut self ,
269
+ & self ,
237
270
element : & Self :: Handle ,
238
271
prev_element : & Self :: Handle ,
239
272
child : NodeOrText < Self :: Handle > ,
240
273
) {
241
- if self . tree . get ( * element) . unwrap ( ) . parent ( ) . is_some ( ) {
274
+ let has_parent = self
275
+ . 0
276
+ . borrow ( )
277
+ . tree
278
+ . get ( * element)
279
+ . unwrap ( )
280
+ . parent ( )
281
+ . is_some ( ) ;
282
+
283
+ if has_parent {
242
284
self . append_before_sibling ( element, child)
243
285
} else {
244
286
self . append ( prev_element, child)
0 commit comments