Skip to content

Commit bd08075

Browse files
committed
Handle margin and padding
1 parent 6f6985e commit bd08075

File tree

7 files changed

+385
-46
lines changed

7 files changed

+385
-46
lines changed

src/lib.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,4 +411,98 @@ mod tests {
411411
}"#
412412
});
413413
}
414+
415+
#[test]
416+
pub fn test_margin() {
417+
test(r#"
418+
.foo {
419+
margin-left: 10px;
420+
margin-right: 10px;
421+
margin-top: 20px;
422+
margin-bottom: 20px;
423+
}
424+
"#, indoc! {r#"
425+
.foo {
426+
margin: 20px 10px;
427+
}"#
428+
});
429+
430+
test(r#"
431+
.foo {
432+
margin-block-start: 15px;
433+
margin-block-end: 15px;
434+
}
435+
"#, indoc! {r#"
436+
.foo {
437+
margin-block: 15px;
438+
}"#
439+
});
440+
441+
test(r#"
442+
.foo {
443+
margin-left: 10px;
444+
margin-right: 10px;
445+
margin-inline-start: 15px;
446+
margin-inline-end: 15px;
447+
margin-top: 20px;
448+
margin-bottom: 20px;
449+
450+
}
451+
"#, indoc! {r#"
452+
.foo {
453+
margin-left: 10px;
454+
margin-right: 10px;
455+
margin-inline: 15px;
456+
margin-top: 20px;
457+
margin-bottom: 20px;
458+
}"#
459+
});
460+
}
461+
462+
#[test]
463+
pub fn test_padding() {
464+
test(r#"
465+
.foo {
466+
padding-left: 10px;
467+
padding-right: 10px;
468+
padding-top: 20px;
469+
padding-bottom: 20px;
470+
}
471+
"#, indoc! {r#"
472+
.foo {
473+
padding: 20px 10px;
474+
}"#
475+
});
476+
477+
test(r#"
478+
.foo {
479+
padding-block-start: 15px;
480+
padding-block-end: 15px;
481+
}
482+
"#, indoc! {r#"
483+
.foo {
484+
padding-block: 15px;
485+
}"#
486+
});
487+
488+
test(r#"
489+
.foo {
490+
padding-left: 10px;
491+
padding-right: 10px;
492+
padding-inline-start: 15px;
493+
padding-inline-end: 15px;
494+
padding-top: 20px;
495+
padding-bottom: 20px;
496+
497+
}
498+
"#, indoc! {r#"
499+
.foo {
500+
padding-left: 10px;
501+
padding-right: 10px;
502+
padding-inline: 15px;
503+
padding-top: 20px;
504+
padding-bottom: 20px;
505+
}"#
506+
});
507+
}
414508
}

src/parser.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,17 +378,22 @@ impl ToCss for StyleRule {
378378
impl StyleRule {
379379
pub fn minify(&mut self) {
380380
use crate::values::border::*;
381+
use crate::properties::margin_padding::*;
381382

382383
let mut border_handler = BorderHandler::default();
384+
let mut margin_handler = MarginHandler::default();
385+
let mut padding_handler = PaddingHandler::default();
383386

384387
let mut decls = vec![];
385388
for decl in self.declarations.iter() {
386-
if !border_handler.handle_property(decl) {
389+
if !border_handler.handle_property(decl) && !margin_handler.handle_property(decl) && !padding_handler.handle_property(decl) {
387390
decls.push(decl.clone());
388391
}
389392
}
390393

391394
decls.extend(border_handler.finalize());
395+
decls.extend(margin_handler.finalize());
396+
decls.extend(padding_handler.finalize());
392397
self.declarations = decls;
393398
}
394399
}

src/properties/margin_padding.rs

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
use crate::values::{length::{Size2D, LengthPercentageOrAuto}, rect::Rect};
2+
use crate::properties::Property;
3+
4+
#[derive(Debug, PartialEq)]
5+
enum SideCategory {
6+
Logical,
7+
Physical
8+
}
9+
10+
impl Default for SideCategory {
11+
fn default() -> SideCategory {
12+
SideCategory::Physical
13+
}
14+
}
15+
16+
macro_rules! side_handler {
17+
($name: ident, $top: ident, $bottom: ident, $left: ident, $right: ident, $block_start: ident, $block_end: ident, $inline_start: ident, $inline_end: ident, $shorthand: ident, $block_shorthand: ident, $inline_shorthand: ident) => {
18+
#[derive(Debug, Default)]
19+
pub struct $name {
20+
top: Option<LengthPercentageOrAuto>,
21+
bottom: Option<LengthPercentageOrAuto>,
22+
left: Option<LengthPercentageOrAuto>,
23+
right: Option<LengthPercentageOrAuto>,
24+
block_start: Option<LengthPercentageOrAuto>,
25+
block_end: Option<LengthPercentageOrAuto>,
26+
inline_start: Option<LengthPercentageOrAuto>,
27+
inline_end: Option<LengthPercentageOrAuto>,
28+
category: SideCategory,
29+
decls: Vec<Property>
30+
}
31+
32+
impl $name {
33+
pub fn handle_property(&mut self, property: &Property) -> bool {
34+
use Property::*;
35+
use SideCategory::*;
36+
37+
macro_rules! property {
38+
($key: ident, $val: ident, $category: ident) => {{
39+
if $category != self.category {
40+
self.flush();
41+
}
42+
self.$key = Some($val.clone());
43+
self.category = $category;
44+
}};
45+
}
46+
47+
macro_rules! set_shorthand {
48+
($start: ident, $end: ident, $val: ident) => {{
49+
if self.category != Logical {
50+
self.flush();
51+
}
52+
self.$start = Some($val.0.clone());
53+
self.$end = Some($val.1.clone());
54+
self.category = Logical;
55+
}};
56+
}
57+
58+
match &property {
59+
$top(val) => property!(top, val, Physical),
60+
$bottom(val) => property!(bottom, val, Physical),
61+
$left(val) => property!(left, val, Physical),
62+
$right(val) => property!(right, val, Physical),
63+
$block_start(val) => property!(block_start, val, Logical),
64+
$block_end(val) => property!(block_end, val, Logical),
65+
$inline_start(val) => property!(inline_start, val, Logical),
66+
$inline_end(val) => property!(inline_end, val, Logical),
67+
$block_shorthand(val) => set_shorthand!(block_start, block_end, val),
68+
$inline_shorthand(val) => set_shorthand!(inline_start, inline_end, val),
69+
$shorthand(val) => {
70+
self.decls.clear();
71+
self.top = Some(val.0.clone());
72+
self.right = Some(val.1.clone());
73+
self.bottom = Some(val.2.clone());
74+
self.left = Some(val.3.clone());
75+
self.block_start = None;
76+
self.block_end = None;
77+
self.inline_start = None;
78+
self.inline_end = None;
79+
}
80+
_ => return false
81+
}
82+
83+
true
84+
}
85+
86+
fn flush(&mut self) {
87+
use Property::*;
88+
89+
let top = std::mem::take(&mut self.top);
90+
let bottom = std::mem::take(&mut self.bottom);
91+
let left = std::mem::take(&mut self.left);
92+
let right = std::mem::take(&mut self.right);
93+
94+
if top.is_some() && bottom.is_some() && left.is_some() && right.is_some() {
95+
let rect = Rect::new(top.unwrap(), right.unwrap(), bottom.unwrap(), left.unwrap());
96+
self.decls.push($shorthand(rect));
97+
} else {
98+
if let Some(val) = top {
99+
self.decls.push($top(val));
100+
}
101+
102+
if let Some(val) = bottom {
103+
self.decls.push($bottom(val));
104+
}
105+
106+
if let Some(val) = left {
107+
self.decls.push($left(val));
108+
}
109+
110+
if let Some(val) = right {
111+
self.decls.push($right(val));
112+
}
113+
}
114+
115+
let block_start = std::mem::take(&mut self.block_start);
116+
let block_end = std::mem::take(&mut self.block_end);
117+
let inline_start = std::mem::take(&mut self.inline_start);
118+
let inline_end = std::mem::take(&mut self.inline_end);
119+
120+
macro_rules! logical_side {
121+
($start: ident, $end: ident, $shorthand_prop: ident, $start_prop: ident, $end_prop: ident) => {
122+
if ($start.is_some() && $end.is_some()) {
123+
let size = Size2D($start.unwrap(), $end.unwrap());
124+
self.decls.push($shorthand_prop(size));
125+
} else {
126+
if let Some(val) = $start {
127+
self.decls.push($start_prop(val));
128+
}
129+
130+
if let Some(val) = $end {
131+
self.decls.push($end_prop(val));
132+
}
133+
}
134+
};
135+
}
136+
137+
logical_side!(block_start, block_end, $block_shorthand, $block_start, $block_end);
138+
logical_side!(inline_start, inline_end, $inline_shorthand, $inline_start, $inline_end);
139+
}
140+
141+
pub fn finalize(&mut self) -> Vec<Property> {
142+
self.flush();
143+
std::mem::take(&mut self.decls)
144+
}
145+
}
146+
};
147+
}
148+
149+
side_handler!(
150+
MarginHandler,
151+
MarginTop,
152+
MarginBottom,
153+
MarginLeft,
154+
MarginRight,
155+
MarginBlockStart,
156+
MarginBlockEnd,
157+
MarginInlineStart,
158+
MarginInlineEnd,
159+
Margin,
160+
MarginBlock,
161+
MarginInline
162+
);
163+
164+
side_handler!(
165+
PaddingHandler,
166+
PaddingTop,
167+
PaddingBottom,
168+
PaddingLeft,
169+
PaddingRight,
170+
PaddingBlockStart,
171+
PaddingBlockEnd,
172+
PaddingInlineStart,
173+
PaddingInlineEnd,
174+
Padding,
175+
PaddingBlock,
176+
PaddingInline
177+
);

0 commit comments

Comments
 (0)