11
11
extern crate html5ever;
12
12
13
13
use std:: borrow:: Cow ;
14
+ use std:: cell:: { Cell , RefCell , Ref } ;
14
15
use std:: collections:: HashMap ;
15
16
use std:: io;
16
17
@@ -19,15 +20,15 @@ use html5ever::tendril::*;
19
20
use html5ever:: tree_builder:: { ElementFlags , NodeOrText , QuirksMode , TreeSink } ;
20
21
use html5ever:: { Attribute , ExpandedName , QualName } ;
21
22
22
- struct Sink {
23
- next_id : usize ,
24
- names : HashMap < usize , QualName > ,
23
+ struct Sink < ' a > {
24
+ next_id : Cell < usize > ,
25
+ names : & ' a mut HashMap < usize , QualName > ,
25
26
}
26
27
27
- impl Sink {
28
- fn get_id ( & mut self ) -> usize {
29
- let id = self . next_id ;
30
- self . next_id += 2 ;
28
+ impl < ' a > Sink < ' a > {
29
+ fn get_id ( & self ) -> usize {
30
+ let id = self . next_id . get ( ) ;
31
+ self . next_id . set ( id + 2 ) ;
31
32
id
32
33
}
33
34
}
@@ -36,18 +37,18 @@ impl Sink {
36
37
/// is processed. In this case the DOM elements are written into the "names" hashmap.
37
38
///
38
39
/// For deeper understating of each function go to the TreeSink declaration.
39
- impl TreeSink for Sink {
40
+ impl < ' a > TreeSink for Sink < ' a > {
40
41
type Handle = usize ;
41
42
type Output = Self ;
42
43
fn finish ( self ) -> Self {
43
44
self
44
45
}
45
46
46
- fn get_document ( & mut self ) -> usize {
47
+ fn get_document ( & self ) -> usize {
47
48
0
48
49
}
49
50
50
- fn get_template_contents ( & mut self , target : & usize ) -> usize {
51
+ fn get_template_contents ( & self , target : & usize ) -> usize {
51
52
if let Some ( expanded_name ! ( html "template" ) ) = self . names . get ( target) . map ( |n| n. expanded ( ) )
52
53
{
53
54
target + 1
@@ -61,53 +62,57 @@ impl TreeSink for Sink {
61
62
}
62
63
63
64
fn elem_name ( & self , target : & usize ) -> ExpandedName {
64
- self . names . get ( target) . expect ( "not an element" ) . expanded ( )
65
+ //let names = self.names.borrow();
66
+ //Ref::map(names, |names| names.get(target).expect("not an element").expanded())
67
+ //self.names.get(target).expect("not an element").expanded()
68
+ todo ! ( )
65
69
}
66
70
67
- fn create_element ( & mut self , name : QualName , _: Vec < Attribute > , _: ElementFlags ) -> usize {
71
+ fn create_element ( & self , name : QualName , _: Vec < Attribute > , _: ElementFlags ) -> usize {
68
72
let id = self . get_id ( ) ;
69
- self . names . insert ( id, name) ;
73
+ // self.names.insert(id, name);
70
74
id
71
75
}
72
76
73
- fn create_comment ( & mut self , _text : StrTendril ) -> usize {
77
+ fn create_comment ( & self , _text : StrTendril ) -> usize {
74
78
self . get_id ( )
75
79
}
76
80
77
81
#[ allow( unused_variables) ]
78
- fn create_pi ( & mut self , target : StrTendril , value : StrTendril ) -> usize {
82
+ fn create_pi ( & self , target : StrTendril , value : StrTendril ) -> usize {
79
83
unimplemented ! ( )
80
84
}
81
85
82
- fn append_before_sibling ( & mut self , _sibling : & usize , _new_node : NodeOrText < usize > ) { }
86
+ fn append_before_sibling ( & self , _sibling : & usize , _new_node : NodeOrText < usize > ) { }
83
87
84
88
fn append_based_on_parent_node (
85
- & mut self ,
89
+ & self ,
86
90
_element : & usize ,
87
91
_prev_element : & usize ,
88
92
_new_node : NodeOrText < usize > ,
89
93
) {
90
94
}
91
95
92
- fn parse_error ( & mut self , _msg : Cow < ' static , str > ) { }
93
- fn set_quirks_mode ( & mut self , _mode : QuirksMode ) { }
94
- fn append ( & mut self , _parent : & usize , _child : NodeOrText < usize > ) { }
96
+ fn parse_error ( & self , _msg : Cow < ' static , str > ) { }
97
+ fn set_quirks_mode ( & self , _mode : QuirksMode ) { }
98
+ fn append ( & self , _parent : & usize , _child : NodeOrText < usize > ) { }
95
99
96
- fn append_doctype_to_document ( & mut self , _: StrTendril , _: StrTendril , _: StrTendril ) { }
97
- fn add_attrs_if_missing ( & mut self , target : & usize , _attrs : Vec < Attribute > ) {
100
+ fn append_doctype_to_document ( & self , _: StrTendril , _: StrTendril , _: StrTendril ) { }
101
+ fn add_attrs_if_missing ( & self , target : & usize , _attrs : Vec < Attribute > ) {
98
102
assert ! ( self . names. contains_key( target) , "not an element" ) ;
99
103
}
100
- fn remove_from_parent ( & mut self , _target : & usize ) { }
101
- fn reparent_children ( & mut self , _node : & usize , _new_parent : & usize ) { }
102
- fn mark_script_already_started ( & mut self , _node : & usize ) { }
104
+ fn remove_from_parent ( & self , _target : & usize ) { }
105
+ fn reparent_children ( & self , _node : & usize , _new_parent : & usize ) { }
106
+ fn mark_script_already_started ( & self , _node : & usize ) { }
103
107
}
104
108
105
109
/// In this example we implement the TreeSink trait which takes each parsed elements and insert
106
110
/// it to a hashmap, while each element is given a numeric id.
107
111
fn main ( ) {
112
+ let mut names = HashMap :: new ( ) ;
108
113
let sink = Sink {
109
- next_id : 1 ,
110
- names : HashMap :: new ( ) ,
114
+ next_id : Cell :: new ( 1 ) ,
115
+ names : & mut names ,
111
116
} ;
112
117
113
118
// Read HTML from the standard input and parse it
0 commit comments