1111extern  crate  html5ever; 
1212
1313use  std:: borrow:: Cow ; 
14- use  std:: cell:: Cell ; 
14+ use  std:: cell:: { Cell ,   RefCell } ; 
1515use  std:: collections:: HashMap ; 
1616use  std:: io; 
1717
@@ -20,12 +20,12 @@ use html5ever::tendril::*;
2020use  html5ever:: tree_builder:: { ElementFlags ,  NodeOrText ,  QuirksMode ,  TreeSink } ; 
2121use  html5ever:: { Attribute ,  ExpandedName ,  QualName } ; 
2222
23- struct  Sink < ' a >  { 
23+ struct  Sink  { 
2424    next_id :  Cell < usize > , 
25-     names :  & ' a   mut   HashMap < usize ,  QualName > , 
25+     names :  RefCell < HashMap < usize ,  & ' static   QualName > > , 
2626} 
2727
28- impl  < ' a >   Sink < ' a >  { 
28+ impl  Sink  { 
2929    fn  get_id ( & self )  -> usize  { 
3030        let  id = self . next_id . get ( ) ; 
3131        self . next_id . set ( id + 2 ) ; 
@@ -37,7 +37,7 @@ impl <'a> Sink<'a> {
3737/// is processed. In this case the DOM elements are written into the "names" hashmap. 
3838/// 
3939/// For deeper understating of each function go to the TreeSink declaration. 
40- impl  < ' a >   TreeSink  for  Sink < ' a >  { 
40+ impl  TreeSink  for  Sink  { 
4141    type  Handle  = usize ; 
4242    type  Output  = Self ; 
4343    fn  finish ( self )  -> Self  { 
@@ -49,7 +49,7 @@ impl <'a> TreeSink for Sink<'a> {
4949    } 
5050
5151    fn  get_template_contents ( & self ,  target :  & usize )  -> usize  { 
52-         if  let  Some ( expanded_name ! ( html "template" ) )  = self . names . get ( target) . map ( |n| n. expanded ( ) ) 
52+         if  let  Some ( expanded_name ! ( html "template" ) )  = self . names . borrow ( ) . get ( target) . map ( |n| n. expanded ( ) ) 
5353        { 
5454            target + 1 
5555        }  else  { 
@@ -61,17 +61,17 @@ impl <'a> TreeSink for Sink<'a> {
6161        x == y
6262    } 
6363
64-     fn  elem_name ( & self ,  _target :  & usize )  -> ExpandedName  { 
65-         //XXX(jdm) 
66-         //let names = self.names.borrow(); 
67-         //Ref::map(names, |names| names.get(target).expect("not an element").expanded()) 
68-         //self.names.get(target).expect("not an element").expanded() 
69-         todo ! ( ) 
64+     fn  elem_name ( & self ,  target :  & usize )  -> ExpandedName  { 
65+         self . names . borrow ( ) . get ( target) . expect ( "not an element" ) . expanded ( ) 
7066    } 
7167
72-     fn  create_element ( & self ,  _name :  QualName ,  _:  Vec < Attribute > ,  _:  ElementFlags )  -> usize  { 
68+     fn  create_element ( & self ,  name :  QualName ,  _:  Vec < Attribute > ,  _:  ElementFlags )  -> usize  { 
7369        let  id = self . get_id ( ) ; 
74-         //self.names.insert(id, name); 
70+         // N.B. We intentionally leak memory here to minimize the implementation complexity 
71+         //      of this example code. A real implementation would either want to use a real 
72+         //      real DOM tree implentation, or else use an arena as the backing store for 
73+         //      memory used by the parser. 
74+         self . names . borrow_mut ( ) . insert ( id,  Box :: leak ( Box :: new ( name) ) ) ; 
7575        id
7676    } 
7777
@@ -100,7 +100,7 @@ impl <'a> TreeSink for Sink<'a> {
100100
101101    fn  append_doctype_to_document ( & self ,  _:  StrTendril ,  _:  StrTendril ,  _:  StrTendril )  { } 
102102    fn  add_attrs_if_missing ( & self ,  target :  & usize ,  _attrs :  Vec < Attribute > )  { 
103-         assert ! ( self . names. contains_key( target) ,  "not an element" ) ; 
103+         assert ! ( self . names. borrow ( ) . contains_key( target) ,  "not an element" ) ; 
104104    } 
105105    fn  remove_from_parent ( & self ,  _target :  & usize )  { } 
106106    fn  reparent_children ( & self ,  _node :  & usize ,  _new_parent :  & usize )  { } 
@@ -110,10 +110,9 @@ impl <'a> TreeSink for Sink<'a> {
110110/// In this example we implement the TreeSink trait which takes each parsed elements and insert 
111111/// it to a hashmap, while each element is given a numeric id. 
112112fn  main ( )  { 
113-     let  mut  names = HashMap :: new ( ) ; 
114113    let  sink = Sink  { 
115114        next_id :  Cell :: new ( 1 ) , 
116-         names :  & mut  names , 
115+         names :  RefCell :: new ( HashMap :: new ( ) ) , 
117116    } ; 
118117
119118    // Read HTML from the standard input and parse it 
0 commit comments