Skip to content

Commit 10548d9

Browse files
committed
Allow position type to be shared
1 parent 1af2899 commit 10548d9

File tree

3 files changed

+172
-163
lines changed

3 files changed

+172
-163
lines changed

src/properties/background.rs

Lines changed: 7 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
use cssparser::*;
22
use crate::values::{
3-
length::{LengthPercentage, LengthPercentageOrAuto},
3+
length::LengthPercentageOrAuto,
44
position::*,
5-
percentage::Percentage,
65
color::CssColor,
76
image::Image
87
};
@@ -13,150 +12,6 @@ use itertools::izip;
1312
use crate::printer::Printer;
1413
use smallvec::SmallVec;
1514

16-
/// https://www.w3.org/TR/css-backgrounds-3/#background-position
17-
#[derive(Debug, Clone, PartialEq)]
18-
pub struct BackgroundPosition {
19-
x: HorizontalPosition,
20-
y: VerticalPosition
21-
}
22-
23-
impl Default for BackgroundPosition {
24-
fn default() -> BackgroundPosition {
25-
BackgroundPosition {
26-
x: HorizontalPosition::Length(LengthPercentage::Percentage(Percentage(0.0))),
27-
y: VerticalPosition::Length(LengthPercentage::Percentage(Percentage(0.0)))
28-
}
29-
}
30-
}
31-
32-
impl Parse for BackgroundPosition {
33-
fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i, ()>> {
34-
match input.try_parse(HorizontalPosition::parse) {
35-
Ok(HorizontalPosition::Center) => {
36-
// Try parsing a vertical position next.
37-
if let Ok(y) = input.try_parse(VerticalPosition::parse) {
38-
return Ok(BackgroundPosition {
39-
x: HorizontalPosition::Center,
40-
y
41-
})
42-
}
43-
44-
// If it didn't work, assume the first actually represents a y position,
45-
// and the next is an x position. e.g. `center left` rather than `left center`.
46-
let x = input
47-
.try_parse(HorizontalPosition::parse)
48-
.unwrap_or(HorizontalPosition::Center);
49-
let y = VerticalPosition::Center;
50-
return Ok(BackgroundPosition { x, y })
51-
},
52-
Ok(x @ HorizontalPosition::Length(_)) => {
53-
// If we got a length as the first component, then the second must
54-
// be a keyword or length (not a side offset).
55-
if let Ok(y_keyword) = input.try_parse(VerticalPositionKeyword::parse) {
56-
let y = VerticalPosition::Side(y_keyword, None);
57-
return Ok(BackgroundPosition { x, y });
58-
}
59-
if let Ok(y_lp) = input.try_parse(LengthPercentage::parse) {
60-
let y = VerticalPosition::Length(y_lp);
61-
return Ok(BackgroundPosition { x, y });
62-
}
63-
let y = VerticalPosition::Center;
64-
let _ = input.try_parse(|i| i.expect_ident_matching("center"));
65-
return Ok(BackgroundPosition { x, y });
66-
}
67-
Ok(HorizontalPosition::Side(x_keyword, lp)) => {
68-
// If we got a horizontal side keyword (and optional offset), expect another for the vertical side.
69-
// e.g. `left center` or `left 20px center`
70-
if input.try_parse(|i| i.expect_ident_matching("center")).is_ok() {
71-
let x = HorizontalPosition::Side(x_keyword, lp);
72-
let y = VerticalPosition::Center;
73-
return Ok(BackgroundPosition { x, y });
74-
}
75-
76-
// e.g. `left top`, `left top 20px`, `left 20px top`, or `left 20px top 20px`
77-
if let Ok(y_keyword) = input.try_parse(VerticalPositionKeyword::parse) {
78-
let y_lp = input.try_parse(LengthPercentage::parse).ok();
79-
let x = HorizontalPosition::Side(x_keyword, lp);
80-
let y = VerticalPosition::Side(y_keyword, y_lp);
81-
return Ok(BackgroundPosition { x, y });
82-
}
83-
84-
// If we didn't get a vertical side keyword (e.g. `left 20px`), then apply the offset to the vertical side.
85-
let x = HorizontalPosition::Side(x_keyword, None);
86-
let y = lp.map_or(VerticalPosition::Center, VerticalPosition::Length);
87-
return Ok(BackgroundPosition { x, y });
88-
}
89-
_ => {}
90-
}
91-
92-
// If the horizontal position didn't parse, then it must be out of order. Try vertical position keyword.
93-
let y_keyword = VerticalPositionKeyword::parse(input)?;
94-
let lp_and_x_pos: Result<_, ParseError<()>> = input.try_parse(|i| {
95-
let y_lp = i.try_parse(LengthPercentage::parse).ok();
96-
if let Ok(x_keyword) = i.try_parse(HorizontalPositionKeyword::parse) {
97-
let x_lp = i.try_parse(LengthPercentage::parse).ok();
98-
let x_pos = HorizontalPosition::Side(x_keyword, x_lp);
99-
return Ok((y_lp, x_pos));
100-
}
101-
i.expect_ident_matching("center")?;
102-
let x_pos = HorizontalPosition::Center;
103-
Ok((y_lp, x_pos))
104-
});
105-
106-
if let Ok((y_lp, x)) = lp_and_x_pos {
107-
let y = VerticalPosition::Side(y_keyword, y_lp);
108-
return Ok(BackgroundPosition { x, y });
109-
}
110-
111-
let x = HorizontalPosition::Center;
112-
let y = VerticalPosition::Side(y_keyword, None);
113-
Ok(BackgroundPosition { x, y })
114-
}
115-
}
116-
117-
impl ToCss for BackgroundPosition {
118-
fn to_css<W>(&self, dest: &mut Printer<W>) -> std::fmt::Result where W: std::fmt::Write {
119-
match (&self.x, &self.y) {
120-
(
121-
x_pos @ &HorizontalPosition::Side(_, Some(_)),
122-
&VerticalPosition::Length(ref y_lp),
123-
) => {
124-
x_pos.to_css(dest)?;
125-
dest.write_str(" top ")?;
126-
y_lp.to_css(dest)
127-
},
128-
(
129-
&HorizontalPosition::Length(ref x_lp),
130-
y_pos @ &VerticalPosition::Side(_, Some(_)),
131-
) => {
132-
dest.write_str("left ")?;
133-
x_lp.to_css(dest)?;
134-
dest.write_str(" ")?;
135-
y_pos.to_css(dest)
136-
},
137-
(
138-
&HorizontalPosition::Length(ref x_lp),
139-
&VerticalPosition::Center
140-
) => {
141-
// `center` is assumed if omitted.
142-
x_lp.to_css(dest)
143-
},
144-
(
145-
&HorizontalPosition::Length(ref x_lp),
146-
&VerticalPosition::Length(LengthPercentage::Percentage(Percentage(y_lp)))
147-
) if y_lp == 0.5 => {
148-
// 50% is equivalent to `center`, which may be omitted.
149-
x_lp.to_css(dest)
150-
},
151-
(x_pos, y_pos) => {
152-
x_pos.to_css(dest)?;
153-
dest.write_str(" ")?;
154-
y_pos.to_css(dest)
155-
},
156-
}
157-
}
158-
}
159-
16015
/// https://www.w3.org/TR/css-backgrounds-3/#background-size
16116
#[derive(Debug, Clone, PartialEq)]
16217
pub enum BackgroundSize {
@@ -302,7 +157,7 @@ enum_property!(BackgroundBox,
302157
pub struct Background {
303158
image: Image,
304159
color: CssColor,
305-
position: BackgroundPosition,
160+
position: Position,
306161
repeat: BackgroundRepeat,
307162
size: BackgroundSize,
308163
attachment: BackgroundAttachment,
@@ -313,7 +168,7 @@ pub struct Background {
313168
impl Parse for Background {
314169
fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i, ()>> {
315170
let mut color: Option<CssColor> = None;
316-
let mut position: Option<BackgroundPosition> = None;
171+
let mut position: Option<Position> = None;
317172
let mut size: Option<BackgroundSize> = None;
318173
let mut image: Option<Image> = None;
319174
let mut repeat: Option<BackgroundRepeat> = None;
@@ -331,7 +186,7 @@ impl Parse for Background {
331186
}
332187

333188
if position.is_none() {
334-
if let Ok(value) = input.try_parse(BackgroundPosition::parse) {
189+
if let Ok(value) = input.try_parse(Position::parse) {
335190
position = Some(value);
336191

337192
size = input.try_parse(|input| {
@@ -417,7 +272,7 @@ impl ToCss for Background {
417272
needs_space = true;
418273
}
419274

420-
if self.position != BackgroundPosition::default() || self.size != BackgroundSize::default() {
275+
if self.position != Position::default() || self.size != BackgroundSize::default() {
421276
if needs_space {
422277
dest.write_str(" ")?;
423278
}
@@ -537,7 +392,7 @@ impl PropertyHandler for BackgroundHandler {
537392
CssColor::default()
538393
},
539394
image,
540-
position: BackgroundPosition {
395+
position: Position {
541396
x: x_position,
542397
y: y_position
543398
},
@@ -563,7 +418,7 @@ impl PropertyHandler for BackgroundHandler {
563418

564419
match (&mut x_positions, &mut y_positions) {
565420
(Some(x_positions), Some(y_positions)) if x_positions.len() == y_positions.len() => {
566-
let positions = izip!(x_positions.drain(..), y_positions.drain(..)).map(|(x, y)| BackgroundPosition {x, y}).collect();
421+
let positions = izip!(x_positions.drain(..), y_positions.drain(..)).map(|(x, y)| Position {x, y}).collect();
567422
decls.push(Property::BackgroundPosition(positions))
568423
}
569424
_ => {

src/properties/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub enum Property {
3939
BackgroundImage(SmallVec<[Image; 1]>),
4040
BackgroundPositionX(SmallVec<[HorizontalPosition; 1]>),
4141
BackgroundPositionY(SmallVec<[VerticalPosition; 1]>),
42-
BackgroundPosition(SmallVec<[BackgroundPosition; 1]>),
42+
BackgroundPosition(SmallVec<[Position; 1]>),
4343
BackgroundSize(SmallVec<[BackgroundSize; 1]>),
4444
BackgroundRepeat(SmallVec<[BackgroundRepeat; 1]>),
4545
BackgroundAttachment(SmallVec<[BackgroundAttachment; 1]>),
@@ -297,7 +297,7 @@ impl Property {
297297
"background-image" => property!(BackgroundImage, Image, true),
298298
"background-position-x" => property!(BackgroundPositionX, HorizontalPosition, true),
299299
"background-position-y" => property!(BackgroundPositionY, VerticalPosition, true),
300-
"background-position" => property!(BackgroundPosition, BackgroundPosition, true),
300+
"background-position" => property!(BackgroundPosition, Position, true),
301301
"background-size" => property!(BackgroundSize, BackgroundSize, true),
302302
"background-repeat" => property!(BackgroundRepeat, BackgroundRepeat, true),
303303
"background-attachment" => property!(BackgroundAttachment, BackgroundAttachment, true),

0 commit comments

Comments
 (0)