99
99
) ]
100
100
use crate :: parse:: Declaration ;
101
101
use kuchiki:: traits:: TendrilSink ;
102
- use kuchiki:: { parse_html, ElementData , NodeDataRef , Selectors } ;
102
+ use kuchiki:: { parse_html, Selectors } ;
103
103
104
104
pub mod error;
105
105
mod parse;
@@ -122,57 +122,44 @@ impl Rule {
122
122
}
123
123
}
124
124
125
- fn process_style_node ( node : & NodeDataRef < ElementData > ) -> Vec < Rule > {
126
- let css = node. text_contents ( ) ;
127
- let mut parse_input = cssparser:: ParserInput :: new ( css. as_str ( ) ) ;
128
- let mut parser = parse:: CSSParser :: new ( & mut parse_input) ;
129
- parser
130
- . parse ( )
131
- . filter_map ( |r| {
132
- r. map ( |( selector, declarations) | Rule :: new ( & selector, declarations) )
133
- . ok ( )
134
- } )
135
- . collect :: < Result < Vec < _ > , _ > > ( )
136
- . map_err ( |_| error:: InlineError :: ParseError )
137
- . expect ( "Parsing error" ) // Should return Result instead
138
- }
139
-
140
125
/// Inline CSS styles from <style> tags to matching elements in the HTML tree.
141
126
pub fn inline ( html : & str ) -> Result < String , InlineError > {
142
127
let document = parse_html ( ) . one ( html) ;
143
- let rules = document
128
+ for style_tag in document
144
129
. select ( "style" )
145
130
. map_err ( |_| error:: InlineError :: ParseError ) ?
146
- . map ( |ref node| process_style_node ( node) )
147
- . flatten ( ) ;
148
-
149
- for rule in rules {
150
- let matching_elements = document
151
- . inclusive_descendants ( )
152
- . filter_map ( |node| node. into_element_ref ( ) )
153
- . filter ( |element| rule. selectors . matches ( element) ) ;
154
- for matching_element in matching_elements {
155
- let mut attributes = matching_element. attributes . borrow_mut ( ) ;
156
- let style = if let Some ( existing_style) = attributes. get ( "style" ) {
157
- merge_styles ( existing_style, & rule. declarations ) ?
158
- } else {
159
- rule. declarations
160
- . iter ( )
161
- . map ( |& ( ref key, ref value) | format ! ( "{}:{};" , key, value) )
162
- . collect ( )
163
- } ;
164
- attributes. insert ( "style" , style) ;
131
+ {
132
+ if let Some ( first_child) = style_tag. as_node ( ) . first_child ( ) {
133
+ if let Some ( css_cell) = first_child. as_text ( ) {
134
+ let css = css_cell. borrow ( ) ;
135
+ let mut parse_input = cssparser:: ParserInput :: new ( css. as_str ( ) ) ;
136
+ let mut parser = parse:: CSSParser :: new ( & mut parse_input) ;
137
+ for parsed in parser. parse ( ) {
138
+ let ( selector, declarations) = parsed?;
139
+ let rule = Rule :: new ( & selector, declarations)
140
+ . map_err ( |_| error:: InlineError :: ParseError ) ?;
141
+ let matching_elements = document
142
+ . inclusive_descendants ( )
143
+ . filter_map ( |node| node. into_element_ref ( ) )
144
+ . filter ( |element| rule. selectors . matches ( element) ) ;
145
+ for matching_element in matching_elements {
146
+ let mut attributes = matching_element. attributes . borrow_mut ( ) ;
147
+ let style = if let Some ( existing_style) = attributes. get ( "style" ) {
148
+ merge_styles ( existing_style, & rule. declarations ) ?
149
+ } else {
150
+ rule. declarations
151
+ . iter ( )
152
+ . map ( |& ( ref key, ref value) | format ! ( "{}:{};" , key, value) )
153
+ . collect ( )
154
+ } ;
155
+ attributes. insert ( "style" , style) ;
156
+ }
157
+ }
158
+ }
165
159
}
166
160
}
167
-
168
161
let mut out = vec ! [ ] ;
169
- document
170
- . select ( "html" )
171
- . map_err ( |_| error:: InlineError :: ParseError ) ?
172
- . next ( )
173
- . expect ( "HTML tag should be present" ) // Should it?
174
- . as_node ( )
175
- . serialize ( & mut out) ?;
162
+ document. serialize ( & mut out) ?;
176
163
Ok ( String :: from_utf8_lossy ( & out) . to_string ( ) )
177
164
}
178
165
@@ -186,7 +173,7 @@ fn merge_styles(existing_style: &str, new_styles: &[Declaration]) -> Result<Stri
186
173
let mut styles: HashMap < String , String > = HashMap :: new ( ) ;
187
174
for declaration in declarations. into_iter ( ) {
188
175
let ( property, value) = declaration?;
189
- styles. insert ( property. to_string ( ) , value. to_string ( ) ) ;
176
+ styles. insert ( property, value) ;
190
177
}
191
178
for ( property, value) in new_styles. iter ( ) {
192
179
styles. insert ( property. to_string ( ) , value. to_string ( ) ) ;
0 commit comments