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