11
11
extern crate html5ever;
12
12
13
13
use std:: borrow:: Cow ;
14
- use std:: cell:: Cell ;
14
+ use std:: cell:: { Cell , RefCell } ;
15
15
use std:: collections:: HashMap ;
16
16
use std:: io;
17
17
@@ -20,12 +20,12 @@ use html5ever::tendril::*;
20
20
use html5ever:: tree_builder:: { ElementFlags , NodeOrText , QuirksMode , TreeSink } ;
21
21
use html5ever:: { Attribute , ExpandedName , QualName } ;
22
22
23
- struct Sink < ' a > {
23
+ struct Sink {
24
24
next_id : Cell < usize > ,
25
- names : & ' a mut HashMap < usize , QualName > ,
25
+ names : RefCell < HashMap < usize , & ' static QualName > > ,
26
26
}
27
27
28
- impl < ' a > Sink < ' a > {
28
+ impl Sink {
29
29
fn get_id ( & self ) -> usize {
30
30
let id = self . next_id . get ( ) ;
31
31
self . next_id . set ( id + 2 ) ;
@@ -37,7 +37,7 @@ impl <'a> Sink<'a> {
37
37
/// is processed. In this case the DOM elements are written into the "names" hashmap.
38
38
///
39
39
/// For deeper understating of each function go to the TreeSink declaration.
40
- impl < ' a > TreeSink for Sink < ' a > {
40
+ impl TreeSink for Sink {
41
41
type Handle = usize ;
42
42
type Output = Self ;
43
43
fn finish ( self ) -> Self {
@@ -49,7 +49,7 @@ impl <'a> TreeSink for Sink<'a> {
49
49
}
50
50
51
51
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 ( ) )
53
53
{
54
54
target + 1
55
55
} else {
@@ -61,17 +61,17 @@ impl <'a> TreeSink for Sink<'a> {
61
61
x == y
62
62
}
63
63
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 ( )
70
66
}
71
67
72
- fn create_element ( & self , _name : QualName , _: Vec < Attribute > , _: ElementFlags ) -> usize {
68
+ fn create_element ( & self , name : QualName , _: Vec < Attribute > , _: ElementFlags ) -> usize {
73
69
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) ) ) ;
75
75
id
76
76
}
77
77
@@ -100,7 +100,7 @@ impl <'a> TreeSink for Sink<'a> {
100
100
101
101
fn append_doctype_to_document ( & self , _: StrTendril , _: StrTendril , _: StrTendril ) { }
102
102
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" ) ;
104
104
}
105
105
fn remove_from_parent ( & self , _target : & usize ) { }
106
106
fn reparent_children ( & self , _node : & usize , _new_parent : & usize ) { }
@@ -110,10 +110,9 @@ impl <'a> TreeSink for Sink<'a> {
110
110
/// In this example we implement the TreeSink trait which takes each parsed elements and insert
111
111
/// it to a hashmap, while each element is given a numeric id.
112
112
fn main ( ) {
113
- let mut names = HashMap :: new ( ) ;
114
113
let sink = Sink {
115
114
next_id : Cell :: new ( 1 ) ,
116
- names : & mut names ,
115
+ names : RefCell :: new ( HashMap :: new ( ) ) ,
117
116
} ;
118
117
119
118
// Read HTML from the standard input and parse it
0 commit comments