@@ -27,21 +27,27 @@ use crate::error::{ParserError, PrinterError};
2727
2828#[ derive( Debug , PartialEq ) ]
2929pub struct DeclarationBlock {
30- pub declarations : Vec < Declaration >
30+ pub important_declarations : Vec < Property > ,
31+ pub declarations : Vec < Property >
3132}
3233
3334impl DeclarationBlock {
3435 pub fn parse < ' i , ' t > ( input : & mut Parser < ' i , ' t > , options : & ParserOptions ) -> Result < Self , ParseError < ' i , ParserError < ' i > > > {
35- let mut parser = DeclarationListParser :: new ( input, PropertyDeclarationParser { options } ) ;
36- let mut declarations = vec ! [ ] ;
37- while let Some ( decl) = parser. next ( ) {
38- match decl {
39- Ok ( decl) => declarations. push ( decl) ,
40- Err ( ( err, _) ) => return Err ( err)
36+ let mut important_declarations = DeclarationList :: new ( ) ;
37+ let mut declarations = DeclarationList :: new ( ) ;
38+ let mut parser = DeclarationListParser :: new ( input, PropertyDeclarationParser {
39+ important_declarations : & mut important_declarations,
40+ declarations : & mut declarations,
41+ options
42+ } ) ;
43+ while let Some ( res) = parser. next ( ) {
44+ if let Err ( ( err, _) ) = res {
45+ return Err ( err)
4146 }
4247 }
4348
4449 Ok ( DeclarationBlock {
50+ important_declarations,
4551 declarations
4652 } )
4753 }
@@ -52,14 +58,26 @@ impl ToCss for DeclarationBlock {
5258 dest. whitespace ( ) ?;
5359 dest. write_char ( '{' ) ?;
5460 dest. indent ( ) ;
55- let len = self . declarations . len ( ) ;
56- for ( i, decl) in self . declarations . iter ( ) . enumerate ( ) {
57- dest. newline ( ) ?;
58- decl. to_css ( dest) ?;
59- if i != len - 1 || !dest. minify {
60- dest. write_char ( ';' ) ?;
61- }
61+
62+ let mut i = 0 ;
63+ let len = self . declarations . len ( ) + self . important_declarations . len ( ) ;
64+
65+ macro_rules! write {
66+ ( $decls: expr, $important: literal) => {
67+ for decl in & $decls {
68+ dest. newline( ) ?;
69+ decl. to_css( dest, $important) ?;
70+ if i != len - 1 || !dest. minify {
71+ dest. write_char( ';' ) ?;
72+ }
73+ i += 1 ;
74+ }
75+ } ;
6276 }
77+
78+ write ! ( self . declarations, false ) ;
79+ write ! ( self . important_declarations, true ) ;
80+
6381 dest. dedent ( ) ;
6482 dest. newline ( ) ?;
6583 dest. write_char ( '}' )
@@ -68,94 +86,76 @@ impl ToCss for DeclarationBlock {
6886
6987impl DeclarationBlock {
7088 pub ( crate ) fn minify ( & mut self , handler : & mut DeclarationHandler , important_handler : & mut DeclarationHandler ) {
71- let mut decls: Vec < Declaration > = vec ! [ ] ;
72- for decl in self . declarations . iter ( ) {
73- let handled =
74- ( decl. important && important_handler. handle_property ( decl) ) ||
75- ( !decl. important && handler. handle_property ( decl) ) ;
76-
77- if !handled {
78- decls. push ( decl. clone ( ) ) ;
79- }
89+ macro_rules! handle {
90+ ( $decls: expr, $handler: expr) => {
91+ for decl in $decls. iter( ) {
92+ let handled = $handler. handle_property( decl) ;
93+
94+ if !handled {
95+ $handler. decls. push( decl. clone( ) ) ;
96+ }
97+ }
98+ } ;
8099 }
81100
82- decls. extend ( handler. finalize ( ) ) ;
83- decls. extend ( important_handler. finalize ( ) ) ;
84- self . declarations = decls;
101+ handle ! ( self . important_declarations, important_handler) ;
102+ handle ! ( self . declarations, handler) ;
103+
104+ handler. finalize ( ) ;
105+ important_handler. finalize ( ) ;
106+ self . important_declarations = std:: mem:: take ( & mut important_handler. decls ) ;
107+ self . declarations = std:: mem:: take ( & mut handler. decls ) ;
85108 }
86109}
87110
88111struct PropertyDeclarationParser < ' a > {
112+ important_declarations : & ' a mut Vec < Property > ,
113+ declarations : & ' a mut Vec < Property > ,
89114 options : & ' a ParserOptions
90115}
91116
92117/// Parse a declaration within {} block: `color: blue`
93118impl < ' a , ' i > cssparser:: DeclarationParser < ' i > for PropertyDeclarationParser < ' a > {
94- type Declaration = Declaration ;
119+ type Declaration = ( ) ;
95120 type Error = ParserError < ' i > ;
96121
97122 fn parse_value < ' t > (
98123 & mut self ,
99124 name : CowRcStr < ' i > ,
100125 input : & mut cssparser:: Parser < ' i , ' t > ,
101126 ) -> Result < Self :: Declaration , cssparser:: ParseError < ' i , Self :: Error > > {
102- Declaration :: parse ( name, input, self . options )
127+ parse_declaration ( name, input, & mut self . declarations , & mut self . important_declarations , & self . options )
103128 }
104129}
105130
106131/// Default methods reject all at rules.
107132impl < ' a , ' i > AtRuleParser < ' i > for PropertyDeclarationParser < ' a > {
108133 type Prelude = ( ) ;
109- type AtRule = Declaration ;
134+ type AtRule = ( ) ;
110135 type Error = ParserError < ' i > ;
111136}
112137
113- #[ derive( Debug , Clone , PartialEq ) ]
114- pub struct Declaration {
115- pub property : Property ,
116- pub important : bool
117- }
118-
119- impl Declaration {
120- pub fn parse < ' i , ' t > ( name : CowRcStr < ' i > , input : & mut Parser < ' i , ' t > , options : & ParserOptions ) -> Result < Self , ParseError < ' i , ParserError < ' i > > > {
121- let property = input. parse_until_before ( Delimiter :: Bang , |input| Property :: parse ( name, input, options) ) ?;
122- let important = input. try_parse ( |input| {
123- input. expect_delim ( '!' ) ?;
124- input. expect_ident_matching ( "important" )
125- } ) . is_ok ( ) ;
126- Ok ( Declaration { property, important } )
127- }
128- }
129-
130- impl ToCss for Declaration {
131- fn to_css < W > ( & self , dest : & mut Printer < W > ) -> Result < ( ) , PrinterError > where W : std:: fmt:: Write {
132- self . property . to_css ( dest, self . important )
138+ pub ( crate ) fn parse_declaration < ' i , ' t > (
139+ name : CowRcStr < ' i > ,
140+ input : & mut cssparser:: Parser < ' i , ' t > ,
141+ declarations : & mut DeclarationList ,
142+ important_declarations : & mut DeclarationList ,
143+ options : & ParserOptions
144+ ) -> Result < ( ) , cssparser:: ParseError < ' i , ParserError < ' i > > > {
145+ let property = input. parse_until_before ( Delimiter :: Bang , |input| Property :: parse ( name, input, options) ) ?;
146+ let important = input. try_parse ( |input| {
147+ input. expect_delim ( '!' ) ?;
148+ input. expect_ident_matching ( "important" )
149+ } ) . is_ok ( ) ;
150+ if important {
151+ important_declarations. push ( property) ;
152+ } else {
153+ declarations. push ( property) ;
133154 }
155+ Ok ( ( ) )
134156}
135157
136- #[ derive( Default ) ]
137- pub ( crate ) struct DeclarationList {
138- important : bool ,
139- pub declarations : Vec < Declaration >
140- }
141-
142- impl DeclarationList {
143- pub fn new ( important : bool ) -> DeclarationList {
144- DeclarationList {
145- important,
146- declarations : Vec :: new ( )
147- }
148- }
149-
150- pub fn push ( & mut self , property : Property ) {
151- self . declarations . push ( Declaration { property, important : self . important } )
152- }
153-
154- pub fn extend ( & mut self , properties : & mut Vec < Property > ) {
155- let important = self . important ;
156- self . declarations . extend ( properties. drain ( ..) . map ( |property| Declaration { property, important } ) )
157- }
158- }
158+ pub ( crate ) type DeclarationList = Vec < Property > ;
159159
160160#[ derive( Default ) ]
161161pub ( crate ) struct DeclarationHandler {
@@ -184,7 +184,7 @@ pub(crate) struct DeclarationHandler {
184184}
185185
186186impl DeclarationHandler {
187- pub fn new ( important : bool , targets : Option < Browsers > ) -> Self {
187+ pub fn new ( targets : Option < Browsers > ) -> Self {
188188 DeclarationHandler {
189189 background : BackgroundHandler :: new ( targets) ,
190190 border : BorderHandler :: new ( targets) ,
@@ -198,13 +198,12 @@ impl DeclarationHandler {
198198 transform : TransformHandler :: new ( targets) ,
199199 text : TextDecorationHandler :: new ( targets) ,
200200 prefix : PrefixHandler :: new ( targets) ,
201- decls : DeclarationList :: new ( important ) ,
201+ decls : DeclarationList :: new ( ) ,
202202 ..DeclarationHandler :: default ( )
203203 }
204204 }
205205
206- pub fn handle_property ( & mut self , decl : & Declaration ) -> bool {
207- let property = & decl. property ;
206+ pub fn handle_property ( & mut self , property : & Property ) -> bool {
208207 self . background . handle_property ( property, & mut self . decls ) ||
209208 self . border . handle_property ( property, & mut self . decls ) ||
210209 self . outline . handle_property ( property, & mut self . decls ) ||
@@ -228,7 +227,7 @@ impl DeclarationHandler {
228227 self . prefix . handle_property ( property, & mut self . decls )
229228 }
230229
231- pub fn finalize ( & mut self ) -> Vec < Declaration > {
230+ pub fn finalize ( & mut self ) {
232231 self . background . finalize ( & mut self . decls ) ;
233232 self . border . finalize ( & mut self . decls ) ;
234233 self . outline . finalize ( & mut self . decls ) ;
@@ -250,6 +249,5 @@ impl DeclarationHandler {
250249 self . overflow . finalize ( & mut self . decls ) ;
251250 self . transform . finalize ( & mut self . decls ) ;
252251 self . prefix . finalize ( & mut self . decls ) ;
253- std:: mem:: take ( & mut self . decls . declarations )
254252 }
255253}
0 commit comments