9999) ]
100100use crate :: parse:: Declaration ;
101101use kuchiki:: traits:: TendrilSink ;
102- use kuchiki:: { parse_html, ElementData , NodeDataRef , Selectors } ;
102+ use kuchiki:: { parse_html, Selectors } ;
103103
104104pub mod error;
105105mod parse;
@@ -122,57 +122,44 @@ impl Rule {
122122 }
123123}
124124
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-
140125/// Inline CSS styles from <style> tags to matching elements in the HTML tree.
141126pub fn inline ( html : & str ) -> Result < String , InlineError > {
142127 let document = parse_html ( ) . one ( html) ;
143- let rules = document
128+ for style_tag in document
144129 . select ( "style" )
145130 . 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+ }
165159 }
166160 }
167-
168161 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) ?;
176163 Ok ( String :: from_utf8_lossy ( & out) . to_string ( ) )
177164}
178165
@@ -186,7 +173,7 @@ fn merge_styles(existing_style: &str, new_styles: &[Declaration]) -> Result<Stri
186173 let mut styles: HashMap < String , String > = HashMap :: new ( ) ;
187174 for declaration in declarations. into_iter ( ) {
188175 let ( property, value) = declaration?;
189- styles. insert ( property. to_string ( ) , value. to_string ( ) ) ;
176+ styles. insert ( property, value) ;
190177 }
191178 for ( property, value) in new_styles. iter ( ) {
192179 styles. insert ( property. to_string ( ) , value. to_string ( ) ) ;
0 commit comments