Skip to content

Commit 76860bc

Browse files
committed
Merge branch 'master' of github.com:devongovett/rust-css-transformer into logical
# Conflicts: # src/declaration.rs # src/properties/border_radius.rs # src/stylesheet.rs
2 parents 5ce610c + 58c7d97 commit 76860bc

File tree

11 files changed

+190
-180
lines changed

11 files changed

+190
-180
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ cssnano: 542.956ms
9090
esbuild: 17.411ms
9191
160332 bytes
9292
93-
parcel-css: 4.74ms
94-
143985 bytes
93+
parcel-css: 4.602ms
94+
143154 bytes
9595
9696
9797
$ node bench.js animate.css
@@ -101,7 +101,7 @@ cssnano: 283.105ms
101101
esbuild: 11.858ms
102102
72183 bytes
103103
104-
parcel-css: 1.989ms
104+
parcel-css: 1.973ms
105105
23666 bytes
106106
107107
@@ -112,6 +112,6 @@ cssnano: 2.198s
112112
esbuild: 107.668ms
113113
1961642 bytes
114114
115-
parcel-css: 45.701ms
116-
1799209 bytes
115+
parcel-css: 43.368ms
116+
1824130 bytes
117117
```

src/declaration.rs

Lines changed: 76 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,27 @@ use crate::logical::LogicalProperties;
2828

2929
#[derive(Debug, PartialEq)]
3030
pub struct DeclarationBlock {
31-
pub declarations: Vec<Declaration>
31+
pub important_declarations: Vec<Property>,
32+
pub declarations: Vec<Property>
3233
}
3334

3435
impl 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

94117
struct 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`
99124
impl<'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.
113138
impl<'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

166166
pub(crate) struct DeclarationHandler {
167167
background: BackgroundHandler,
@@ -189,7 +189,7 @@ pub(crate) struct DeclarationHandler {
189189
}
190190

191191
impl 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
}

src/logical.rs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use cssparser::SourceLocation;
22
use crate::rules::{CssRule, CssRuleList, style::StyleRule};
33
use parcel_selectors::SelectorList;
44
use crate::selector::{SelectorIdent, SelectorString};
5-
use crate::declaration::{Declaration, DeclarationBlock};
5+
use crate::declaration::DeclarationBlock;
66
use crate::css_modules::hash;
77
use crate::vendor_prefix::VendorPrefix;
88
use crate::compat::Feature;
@@ -69,21 +69,16 @@ impl LogicalProperties {
6969
rules: CssRuleList(vec![]),
7070
vendor_prefix: VendorPrefix::empty(),
7171
declarations: DeclarationBlock {
72+
important_declarations: vec![],
7273
declarations: vec![
73-
Declaration {
74-
property: Property::Custom(CustomProperty {
75-
name: "--ltr".into(),
76-
value: $ltr.into()
77-
}),
78-
important: false
79-
},
80-
Declaration {
81-
property: Property::Custom(CustomProperty {
82-
name: "--rtl".into(),
83-
value: $rtl.into()
84-
}),
85-
important: false
86-
}
74+
Property::Custom(CustomProperty {
75+
name: "--ltr".into(),
76+
value: $ltr.into()
77+
}),
78+
Property::Custom(CustomProperty {
79+
name: "--rtl".into(),
80+
value: $rtl.into()
81+
})
8782
]
8883
},
8984
loc: SourceLocation {

0 commit comments

Comments
 (0)