@@ -4,12 +4,15 @@ use super::{
44 node:: { ElementData , Node , NodeData , NodeId } ,
55} ;
66use html5ever:: {
7- expanded_name, local_name, namespace_url , ns,
7+ expanded_name, local_name, ns,
88 tendril:: { StrTendril , TendrilSink } ,
99 tree_builder:: { ElementFlags , NodeOrText , QuirksMode , TreeSink } ,
10- Attribute , ExpandedName , QualName ,
10+ Attribute , QualName ,
11+ } ;
12+ use std:: {
13+ borrow:: Cow ,
14+ cell:: { Ref , RefCell } ,
1115} ;
12- use std:: borrow:: Cow ;
1316
1417#[ derive( Debug , Copy , Clone ) ]
1518pub ( crate ) enum InliningMode {
@@ -26,7 +29,7 @@ pub(crate) fn parse_with_options(
2629 mode : InliningMode ,
2730) -> Document {
2831 let sink = Sink {
29- document : Document :: with_capacity ( preallocate_node_capacity) ,
32+ document : RefCell :: new ( Document :: with_capacity ( preallocate_node_capacity) ) ,
3033 } ;
3134 let options = html5ever:: ParseOpts :: default ( ) ;
3235 match mode {
@@ -61,17 +64,17 @@ pub(crate) fn parse_with_options(
6164/// It takes care of creating and appending nodes to the document as the parsing progresses.
6265struct Sink {
6366 /// An HTML document that is being parsed.
64- document : Document ,
67+ document : RefCell < Document > ,
6568}
6669
6770impl Sink {
6871 /// Push a new node into the document.
69- fn push_node ( & mut self , data : NodeData ) -> NodeId {
70- self . document . push_node ( data)
72+ fn push_node ( & self , data : NodeData ) -> NodeId {
73+ self . document . borrow_mut ( ) . push_node ( data)
7174 }
7275
7376 fn push_element (
74- & mut self ,
77+ & self ,
7578 name : QualName ,
7679 attributes : Vec < Attribute > ,
7780 inlining_ignored : bool ,
@@ -80,28 +83,28 @@ impl Sink {
8083 element : ElementData :: new ( name, attributes) ,
8184 inlining_ignored,
8285 } ) ;
83- self . document . push_element_id ( node_id) ;
86+ self . document . borrow_mut ( ) . push_element_id ( node_id) ;
8487 node_id
8588 }
8689
87- fn push_text ( & mut self , text : StrTendril ) -> NodeId {
90+ fn push_text ( & self , text : StrTendril ) -> NodeId {
8891 self . push_node ( NodeData :: Text { text } )
8992 }
9093
91- fn push_comment ( & mut self , text : StrTendril ) -> NodeId {
94+ fn push_comment ( & self , text : StrTendril ) -> NodeId {
9295 self . push_node ( NodeData :: Comment { text } )
9396 }
9497
95- fn push_processing_instruction ( & mut self , target : StrTendril , data : StrTendril ) -> NodeId {
98+ fn push_processing_instruction ( & self , target : StrTendril , data : StrTendril ) -> NodeId {
9699 self . push_node ( NodeData :: ProcessingInstruction { target, data } )
97100 }
98101
99- fn push_doctype ( & mut self , name : StrTendril ) -> NodeId {
102+ fn push_doctype ( & self , name : StrTendril ) -> NodeId {
100103 self . push_node ( NodeData :: Doctype { name } )
101104 }
102105
103106 /// Append a new node or text to the document.
104- fn append_impl < P , A > ( & mut self , child : NodeOrText < NodeId > , previous : P , append : A )
107+ fn append_impl < P , A > ( & self , child : NodeOrText < NodeId > , previous : P , append : A )
105108 where
106109 P : FnOnce ( & mut Document ) -> Option < NodeId > ,
107110 A : FnOnce ( & mut Document , NodeId ) ,
@@ -110,50 +113,55 @@ impl Sink {
110113 NodeOrText :: AppendText ( text) => {
111114 // If the previous node is a text node, append to it.
112115 // Otherwise create a new text node.
113- if let Some ( id) = previous ( & mut self . document ) {
114- if let Node {
115- data : NodeData :: Text { text : existing } ,
116- ..
117- } = & mut self . document [ id]
118- {
119- existing. push_tendril ( & text) ;
120- return ;
121- }
116+ let Some ( id) = previous ( & mut self . document . borrow_mut ( ) ) else {
117+ let new_node = self . push_text ( text) ;
118+ append ( & mut self . document . borrow_mut ( ) , new_node) ;
119+ return ;
120+ } ;
121+ if let Node {
122+ data : NodeData :: Text { text : existing } ,
123+ ..
124+ } = & mut self . document . borrow_mut ( ) [ id]
125+ {
126+ existing. push_tendril ( & text) ;
127+ return ;
122128 }
123129 self . push_text ( text)
124130 }
125131 NodeOrText :: AppendNode ( node) => node,
126132 } ;
127133
128- append ( & mut self . document , new_node) ;
134+ append ( & mut self . document . borrow_mut ( ) , new_node) ;
129135 }
130136}
131137
132138impl TreeSink for Sink {
133139 type Handle = NodeId ;
134140 type Output = Document ;
141+ type ElemName < ' a >
142+ = Ref < ' a , QualName >
143+ where
144+ Self : ' a ;
135145
136146 fn finish ( self ) -> Document {
137- self . document
147+ self . document . into_inner ( )
138148 }
139149
140- fn parse_error ( & mut self , _msg : Cow < ' static , str > ) { }
150+ fn parse_error ( & self , _msg : Cow < ' static , str > ) { }
141151
142- fn get_document ( & mut self ) -> NodeId {
152+ fn get_document ( & self ) -> NodeId {
143153 NodeId :: document_id ( )
144154 }
145155
146- fn elem_name < ' a > ( & ' a self , & target: & ' a NodeId ) -> ExpandedName < ' a > {
147- self . document [ target]
148- . as_element ( )
149- // The `TreeSink` trait promises to never call this method on non-element node
150- . expect ( "Not an element" )
151- . name
152- . expanded ( )
156+ fn elem_name < ' a > ( & ' a self , target : & NodeId ) -> Self :: ElemName < ' a > {
157+ let document = self . document . borrow ( ) ;
158+ let node = Ref :: map ( document, |document| & document[ * target] ) ;
159+ let element = Ref :: map ( node, |node| node. as_element ( ) . expect ( "Not an element" ) ) ;
160+ Ref :: map ( element, |element| & element. name )
153161 }
154162
155163 fn create_element (
156- & mut self ,
164+ & self ,
157165 name : QualName ,
158166 attrs : Vec < Attribute > ,
159167 _flags : ElementFlags ,
@@ -191,24 +199,24 @@ impl TreeSink for Sink {
191199 let element = self . push_element ( name, attrs, inlining_ignored) ;
192200 // Collect `style` tags and linked stylesheets separately to use them for CSS inlining later.
193201 if is_style {
194- self . document . add_style ( element) ;
202+ self . document . borrow_mut ( ) . add_style ( element) ;
195203 }
196204 if is_stylesheet {
197- self . document . add_linked_stylesheet ( element) ;
205+ self . document . borrow_mut ( ) . add_linked_stylesheet ( element) ;
198206 }
199207 element
200208 }
201209
202- fn create_comment ( & mut self , text : StrTendril ) -> NodeId {
210+ fn create_comment ( & self , text : StrTendril ) -> NodeId {
203211 self . push_comment ( text)
204212 }
205213
206- fn create_pi ( & mut self , target : StrTendril , data : StrTendril ) -> NodeId {
214+ fn create_pi ( & self , target : StrTendril , data : StrTendril ) -> NodeId {
207215 self . push_processing_instruction ( target, data)
208216 }
209217
210218 /// Append a node as the last child of the given node.
211- fn append ( & mut self , & parent: & NodeId , child : NodeOrText < NodeId > ) {
219+ fn append ( & self , & parent: & NodeId , child : NodeOrText < NodeId > ) {
212220 self . append_impl (
213221 child,
214222 |document| document[ parent] . last_child ,
@@ -217,12 +225,12 @@ impl TreeSink for Sink {
217225 }
218226
219227 fn append_based_on_parent_node (
220- & mut self ,
228+ & self ,
221229 element : & NodeId ,
222230 prev_element : & NodeId ,
223231 child : NodeOrText < NodeId > ,
224232 ) {
225- if self . document [ * element] . parent . is_some ( ) {
233+ if self . document . borrow ( ) [ * element] . parent . is_some ( ) {
226234 self . append_before_sibling ( element, child) ;
227235 } else {
228236 self . append ( prev_element, child) ;
@@ -231,16 +239,18 @@ impl TreeSink for Sink {
231239
232240 /// Append a `DOCTYPE` element to the `Document` node.
233241 fn append_doctype_to_document (
234- & mut self ,
242+ & self ,
235243 name : StrTendril ,
236244 _public_id : StrTendril ,
237245 _system_id : StrTendril ,
238246 ) {
239247 let node = self . push_doctype ( name) ;
240- self . document . append ( NodeId :: document_id ( ) , node) ;
248+ self . document
249+ . borrow_mut ( )
250+ . append ( NodeId :: document_id ( ) , node) ;
241251 }
242252
243- fn get_template_contents ( & mut self , & target: & NodeId ) -> NodeId {
253+ fn get_template_contents ( & self , & target: & NodeId ) -> NodeId {
244254 target
245255 }
246256
@@ -249,10 +259,10 @@ impl TreeSink for Sink {
249259 x == y
250260 }
251261
252- fn set_quirks_mode ( & mut self , _mode : QuirksMode ) { }
262+ fn set_quirks_mode ( & self , _mode : QuirksMode ) { }
253263
254264 /// Append a node as the sibling immediately before the given node.
255- fn append_before_sibling ( & mut self , & sibling: & NodeId , child : NodeOrText < NodeId > ) {
265+ fn append_before_sibling ( & self , & sibling: & NodeId , child : NodeOrText < NodeId > ) {
256266 self . append_impl (
257267 child,
258268 |document| document[ sibling] . previous_sibling ,
@@ -261,10 +271,9 @@ impl TreeSink for Sink {
261271 }
262272
263273 /// Add each attribute to the given element, if no attribute with that name already exists.
264- fn add_attrs_if_missing ( & mut self , & target: & NodeId , attrs : Vec < Attribute > ) {
265- let element = self . document [ target]
266- . as_element_mut ( )
267- . expect ( "not an element" ) ;
274+ fn add_attrs_if_missing ( & self , & target: & NodeId , attrs : Vec < Attribute > ) {
275+ let mut document = self . document . borrow_mut ( ) ;
276+ let element = document[ target] . as_element_mut ( ) . expect ( "not an element" ) ;
268277 let attributes = & mut element. attributes ;
269278 for attr in attrs {
270279 if attributes
@@ -278,12 +287,14 @@ impl TreeSink for Sink {
278287 }
279288
280289 /// Detach the given node from its parent.
281- fn remove_from_parent ( & mut self , & target: & NodeId ) {
282- self . document . detach ( target) ;
290+ fn remove_from_parent ( & self , & target: & NodeId ) {
291+ self . document . borrow_mut ( ) . detach ( target) ;
283292 }
284293
285294 /// Remove all the children from node and append them to `new_parent`.
286- fn reparent_children ( & mut self , node : & NodeId , new_parent : & NodeId ) {
287- self . document . reparent_children ( * node, * new_parent) ;
295+ fn reparent_children ( & self , node : & NodeId , new_parent : & NodeId ) {
296+ self . document
297+ . borrow_mut ( )
298+ . reparent_children ( * node, * new_parent) ;
288299 }
289300}
0 commit comments