@@ -28,21 +28,27 @@ use crate::logical::LogicalProperties;
2828
2929#[ derive( Debug , PartialEq ) ]
3030pub struct DeclarationBlock {
31- pub declarations : Vec < Declaration >
31+ pub important_declarations : Vec < Property > ,
32+ pub declarations : Vec < Property >
3233}
3334
3435impl DeclarationBlock {
3536 pub fn parse < ' i , ' t > ( input : & mut Parser < ' i , ' t > , options : & ParserOptions ) -> Result < Self , ParseError < ' i , ParserError < ' i > > > {
36- let mut parser = DeclarationListParser :: new ( input, PropertyDeclarationParser { options } ) ;
37- let mut declarations = vec ! [ ] ;
38- while let Some ( decl) = parser. next ( ) {
39- match decl {
40- Ok ( decl) => declarations. push ( decl) ,
41- Err ( ( err, _) ) => return Err ( err)
37+ let mut important_declarations = DeclarationList :: new ( ) ;
38+ let mut declarations = DeclarationList :: new ( ) ;
39+ let mut parser = DeclarationListParser :: new ( input, PropertyDeclarationParser {
40+ important_declarations : & mut important_declarations,
41+ declarations : & mut declarations,
42+ options
43+ } ) ;
44+ while let Some ( res) = parser. next ( ) {
45+ if let Err ( ( err, _) ) = res {
46+ return Err ( err)
4247 }
4348 }
4449
4550 Ok ( DeclarationBlock {
51+ important_declarations,
4652 declarations
4753 } )
4854 }
@@ -53,14 +59,26 @@ impl ToCss for DeclarationBlock {
5359 dest. whitespace ( ) ?;
5460 dest. write_char ( '{' ) ?;
5561 dest. indent ( ) ;
56- let len = self . declarations . len ( ) ;
57- for ( i, decl) in self . declarations . iter ( ) . enumerate ( ) {
58- dest. newline ( ) ?;
59- decl. to_css ( dest) ?;
60- if i != len - 1 || !dest. minify {
61- dest. write_char ( ';' ) ?;
62- }
62+
63+ let mut i = 0 ;
64+ let len = self . declarations . len ( ) + self . important_declarations . len ( ) ;
65+
66+ macro_rules! write {
67+ ( $decls: expr, $important: literal) => {
68+ for decl in & $decls {
69+ dest. newline( ) ?;
70+ decl. to_css( dest, $important) ?;
71+ if i != len - 1 || !dest. minify {
72+ dest. write_char( ';' ) ?;
73+ }
74+ i += 1 ;
75+ }
76+ } ;
6377 }
78+
79+ write ! ( self . declarations, false ) ;
80+ write ! ( self . important_declarations, true ) ;
81+
6482 dest. dedent ( ) ;
6583 dest. newline ( ) ?;
6684 dest. write_char ( '}' )
@@ -74,94 +92,76 @@ impl DeclarationBlock {
7492 important_handler : & mut DeclarationHandler ,
7593 logical_properties : & mut LogicalProperties
7694 ) {
77- let mut decls: Vec < Declaration > = vec ! [ ] ;
78- for decl in self . declarations . iter ( ) {
79- let handled =
80- ( decl. important && important_handler. handle_property ( decl, logical_properties) ) ||
81- ( !decl. important && handler. handle_property ( decl, logical_properties) ) ;
82-
83- if !handled {
84- decls. push ( decl. clone ( ) ) ;
85- }
95+ macro_rules! handle {
96+ ( $decls: expr, $handler: expr) => {
97+ for decl in $decls. iter( ) {
98+ let handled = $handler. handle_property( decl, logical_properties) ;
99+
100+ if !handled {
101+ $handler. decls. push( decl. clone( ) ) ;
102+ }
103+ }
104+ } ;
86105 }
87106
88- decls. extend ( handler. finalize ( logical_properties) ) ;
89- decls. extend ( important_handler. finalize ( logical_properties) ) ;
90- self . declarations = decls;
107+ handle ! ( self . important_declarations, important_handler) ;
108+ handle ! ( self . declarations, handler) ;
109+
110+ handler. finalize ( logical_properties) ;
111+ important_handler. finalize ( logical_properties) ;
112+ self . important_declarations = std:: mem:: take ( & mut important_handler. decls ) ;
113+ self . declarations = std:: mem:: take ( & mut handler. decls ) ;
91114 }
92115}
93116
94117struct PropertyDeclarationParser < ' a > {
118+ important_declarations : & ' a mut Vec < Property > ,
119+ declarations : & ' a mut Vec < Property > ,
95120 options : & ' a ParserOptions
96121}
97122
98123/// Parse a declaration within {} block: `color: blue`
99124impl < ' a , ' i > cssparser:: DeclarationParser < ' i > for PropertyDeclarationParser < ' a > {
100- type Declaration = Declaration ;
125+ type Declaration = ( ) ;
101126 type Error = ParserError < ' i > ;
102127
103128 fn parse_value < ' t > (
104129 & mut self ,
105130 name : CowRcStr < ' i > ,
106131 input : & mut cssparser:: Parser < ' i , ' t > ,
107132 ) -> Result < Self :: Declaration , cssparser:: ParseError < ' i , Self :: Error > > {
108- Declaration :: parse ( name, input, self . options )
133+ parse_declaration ( name, input, & mut self . declarations , & mut self . important_declarations , & self . options )
109134 }
110135}
111136
112137/// Default methods reject all at rules.
113138impl < ' a , ' i > AtRuleParser < ' i > for PropertyDeclarationParser < ' a > {
114139 type Prelude = ( ) ;
115- type AtRule = Declaration ;
140+ type AtRule = ( ) ;
116141 type Error = ParserError < ' i > ;
117142}
118143
119- #[ derive( Debug , Clone , PartialEq ) ]
120- pub struct Declaration {
121- pub property : Property ,
122- pub important : bool
123- }
124-
125- impl Declaration {
126- pub fn parse < ' i , ' t > ( name : CowRcStr < ' i > , input : & mut Parser < ' i , ' t > , options : & ParserOptions ) -> Result < Self , ParseError < ' i , ParserError < ' i > > > {
127- let property = input. parse_until_before ( Delimiter :: Bang , |input| Property :: parse ( name, input, options) ) ?;
128- let important = input. try_parse ( |input| {
129- input. expect_delim ( '!' ) ?;
130- input. expect_ident_matching ( "important" )
131- } ) . is_ok ( ) ;
132- Ok ( Declaration { property, important } )
133- }
134- }
135-
136- impl ToCss for Declaration {
137- fn to_css < W > ( & self , dest : & mut Printer < W > ) -> Result < ( ) , PrinterError > where W : std:: fmt:: Write {
138- self . property . to_css ( dest, self . important )
144+ pub ( crate ) fn parse_declaration < ' i , ' t > (
145+ name : CowRcStr < ' i > ,
146+ input : & mut cssparser:: Parser < ' i , ' t > ,
147+ declarations : & mut DeclarationList ,
148+ important_declarations : & mut DeclarationList ,
149+ options : & ParserOptions
150+ ) -> Result < ( ) , cssparser:: ParseError < ' i , ParserError < ' i > > > {
151+ let property = input. parse_until_before ( Delimiter :: Bang , |input| Property :: parse ( name, input, options) ) ?;
152+ let important = input. try_parse ( |input| {
153+ input. expect_delim ( '!' ) ?;
154+ input. expect_ident_matching ( "important" )
155+ } ) . is_ok ( ) ;
156+ if important {
157+ important_declarations. push ( property) ;
158+ } else {
159+ declarations. push ( property) ;
139160 }
161+ Ok ( ( ) )
140162}
141163
142- #[ derive( Default ) ]
143- pub ( crate ) struct DeclarationList {
144- important : bool ,
145- pub declarations : Vec < Declaration >
146- }
147-
148- impl DeclarationList {
149- pub fn new ( important : bool ) -> DeclarationList {
150- DeclarationList {
151- important,
152- declarations : Vec :: new ( )
153- }
154- }
155-
156- pub fn push ( & mut self , property : Property ) {
157- self . declarations . push ( Declaration { property, important : self . important } )
158- }
159-
160- pub fn extend ( & mut self , properties : & mut Vec < Property > ) {
161- let important = self . important ;
162- self . declarations . extend ( properties. drain ( ..) . map ( |property| Declaration { property, important } ) )
163- }
164- }
164+ pub ( crate ) type DeclarationList = Vec < Property > ;
165165
166166pub ( crate ) struct DeclarationHandler {
167167 background : BackgroundHandler ,
@@ -189,7 +189,7 @@ pub(crate) struct DeclarationHandler {
189189}
190190
191191impl DeclarationHandler {
192- pub fn new ( important : bool , targets : Option < Browsers > ) -> Self {
192+ pub fn new ( targets : Option < Browsers > ) -> Self {
193193 DeclarationHandler {
194194 background : BackgroundHandler :: new ( targets) ,
195195 border : BorderHandler :: new ( targets) ,
@@ -212,12 +212,11 @@ impl DeclarationHandler {
212212 overflow : OverflowHandler :: new ( targets) ,
213213 transform : TransformHandler :: new ( targets) ,
214214 prefix : PrefixHandler :: new ( targets) ,
215- decls : DeclarationList :: new ( important )
215+ decls : DeclarationList :: new ( )
216216 }
217217 }
218218
219- pub fn handle_property ( & mut self , decl : & Declaration , logical_properties : & mut LogicalProperties ) -> bool {
220- let property = & decl. property ;
219+ pub fn handle_property ( & mut self , property : & Property , logical_properties : & mut LogicalProperties ) -> bool {
221220 self . background . handle_property ( property, & mut self . decls , logical_properties) ||
222221 self . border . handle_property ( property, & mut self . decls , logical_properties) ||
223222 self . outline . handle_property ( property, & mut self . decls , logical_properties) ||
@@ -241,7 +240,7 @@ impl DeclarationHandler {
241240 self . prefix . handle_property ( property, & mut self . decls , logical_properties)
242241 }
243242
244- pub fn finalize ( & mut self , logical_properties : & mut LogicalProperties ) -> Vec < Declaration > {
243+ pub fn finalize ( & mut self , logical_properties : & mut LogicalProperties ) {
245244 self . background . finalize ( & mut self . decls , logical_properties) ;
246245 self . border . finalize ( & mut self . decls , logical_properties) ;
247246 self . outline . finalize ( & mut self . decls , logical_properties) ;
@@ -263,6 +262,5 @@ impl DeclarationHandler {
263262 self . overflow . finalize ( & mut self . decls , logical_properties) ;
264263 self . transform . finalize ( & mut self . decls , logical_properties) ;
265264 self . prefix . finalize ( & mut self . decls , logical_properties) ;
266- std:: mem:: take ( & mut self . decls . declarations )
267265 }
268266}
0 commit comments