|
1 | 1 | use crate::values::{length::*, percentage::{Percentage, NumberOrPercentage}, number::serialize_number}; |
2 | 2 | use cssparser::*; |
3 | 3 | use crate::traits::{Parse, ToCss, PropertyHandler}; |
4 | | -use crate::properties::Property; |
| 4 | +use crate::properties::{Property, VendorPrefix}; |
| 5 | +use super::prefixes::{Feature, Browsers}; |
5 | 6 | use crate::values::rect::Rect; |
6 | 7 | use crate::values::image::Image; |
7 | 8 | use crate::macros::*; |
@@ -240,85 +241,123 @@ impl ToCss for BorderImage { |
240 | 241 |
|
241 | 242 | #[derive(Default, Debug)] |
242 | 243 | pub struct BorderImageHandler { |
| 244 | + targets: Option<Browsers>, |
243 | 245 | source: Option<Image>, |
244 | 246 | slice: Option<BorderImageSlice>, |
245 | 247 | width: Option<Rect<BorderImageSideWidth>>, |
246 | 248 | outset: Option<Rect<LengthOrNumber>>, |
247 | | - repeat: Option<BorderImageRepeat> |
| 249 | + repeat: Option<BorderImageRepeat>, |
| 250 | + vendor_prefix: VendorPrefix, |
| 251 | + decls: Vec<Property> |
| 252 | +} |
| 253 | + |
| 254 | +impl BorderImageHandler { |
| 255 | + pub fn new(targets: Option<Browsers>) -> BorderImageHandler { |
| 256 | + BorderImageHandler { |
| 257 | + targets, |
| 258 | + vendor_prefix: VendorPrefix::empty(), |
| 259 | + ..BorderImageHandler::default() |
| 260 | + } |
| 261 | + } |
248 | 262 | } |
249 | 263 |
|
250 | 264 | impl PropertyHandler for BorderImageHandler { |
251 | 265 | fn handle_property(&mut self, property: &Property) -> bool { |
252 | 266 | use Property::*; |
| 267 | + macro_rules! property { |
| 268 | + ($name: ident, $val: ident) => {{ |
| 269 | + if self.vendor_prefix != VendorPrefix::None { |
| 270 | + self.flush(); |
| 271 | + } |
| 272 | + self.vendor_prefix = VendorPrefix::None; |
| 273 | + self.$name = Some($val.clone()); |
| 274 | + }}; |
| 275 | + } |
| 276 | + |
253 | 277 | match property { |
254 | | - BorderImageSource(val) => self.source = Some(val.clone()), |
255 | | - BorderImageSlice(val) => self.slice = Some(val.clone()), |
256 | | - BorderImageWidth(val) => self.width = Some(val.clone()), |
257 | | - BorderImageOutset(val) => self.outset = Some(val.clone()), |
258 | | - BorderImageRepeat(val) => self.repeat = Some(val.clone()), |
259 | | - BorderImage(val) => self.set_border_image(val), |
| 278 | + BorderImageSource(val) => property!(source, val), |
| 279 | + BorderImageSlice(val) => property!(slice, val), |
| 280 | + BorderImageWidth(val) => property!(width, val), |
| 281 | + BorderImageOutset(val) => property!(outset, val), |
| 282 | + BorderImageRepeat(val) => property!(repeat, val), |
| 283 | + BorderImage(val, vp) => { |
| 284 | + self.set_border_image(val); |
| 285 | + self.vendor_prefix |= *vp; |
| 286 | + }, |
260 | 287 | _ => return false |
261 | 288 | } |
262 | 289 |
|
263 | 290 | true |
264 | 291 | } |
265 | 292 |
|
266 | 293 | fn finalize(&mut self) -> Vec<Property> { |
267 | | - let mut decls = vec![]; |
| 294 | + self.flush(); |
| 295 | + std::mem::take(&mut self.decls) |
| 296 | + } |
| 297 | +} |
| 298 | + |
| 299 | +impl BorderImageHandler { |
| 300 | + pub fn reset(&mut self) { |
| 301 | + self.source = None; |
| 302 | + self.slice = None; |
| 303 | + self.width = None; |
| 304 | + self.outset = None; |
| 305 | + self.repeat = None; |
| 306 | + } |
| 307 | + |
| 308 | + pub fn set_border_image(&mut self, border_image: &BorderImage) { |
| 309 | + self.source = Some(border_image.source.clone()); |
| 310 | + self.slice = Some(border_image.slice.clone()); |
| 311 | + self.width = Some(border_image.width.clone()); |
| 312 | + self.outset = Some(border_image.outset.clone()); |
| 313 | + self.repeat = Some(border_image.repeat.clone()); |
| 314 | + } |
| 315 | + |
| 316 | + fn flush(&mut self) { |
268 | 317 | let source = std::mem::take(&mut self.source); |
269 | 318 | let slice = std::mem::take(&mut self.slice); |
270 | 319 | let width = std::mem::take(&mut self.width); |
271 | 320 | let outset = std::mem::take(&mut self.outset); |
272 | 321 | let repeat = std::mem::take(&mut self.repeat); |
273 | 322 |
|
274 | 323 | if source.is_some() && slice.is_some() && width.is_some() && outset.is_some() && repeat.is_some() { |
275 | | - decls.push(Property::BorderImage(BorderImage { |
| 324 | + let slice = slice.unwrap(); |
| 325 | + let mut prefix = self.vendor_prefix; |
| 326 | + if prefix.contains(VendorPrefix::None) && !slice.fill { |
| 327 | + if let Some(targets) = self.targets { |
| 328 | + prefix = Feature::BorderImage.prefixes_for(targets) |
| 329 | + } |
| 330 | + } |
| 331 | + |
| 332 | + self.decls.push(Property::BorderImage(BorderImage { |
276 | 333 | source: source.unwrap(), |
277 | | - slice: slice.unwrap(), |
| 334 | + slice, |
278 | 335 | width: width.unwrap(), |
279 | 336 | outset: outset.unwrap(), |
280 | 337 | repeat: repeat.unwrap() |
281 | | - })) |
| 338 | + }, prefix)) |
282 | 339 | } else { |
283 | 340 | if let Some(source) = source { |
284 | | - decls.push(Property::BorderImageSource(source)) |
| 341 | + self.decls.push(Property::BorderImageSource(source)) |
285 | 342 | } |
286 | 343 |
|
287 | 344 | if let Some(slice) = slice { |
288 | | - decls.push(Property::BorderImageSlice(slice)) |
| 345 | + self.decls.push(Property::BorderImageSlice(slice)) |
289 | 346 | } |
290 | 347 |
|
291 | 348 | if let Some(width) = width { |
292 | | - decls.push(Property::BorderImageWidth(width)) |
| 349 | + self.decls.push(Property::BorderImageWidth(width)) |
293 | 350 | } |
294 | 351 |
|
295 | 352 | if let Some(outset) = outset { |
296 | | - decls.push(Property::BorderImageOutset(outset)) |
| 353 | + self.decls.push(Property::BorderImageOutset(outset)) |
297 | 354 | } |
298 | 355 |
|
299 | 356 | if let Some(repeat) = repeat { |
300 | | - decls.push(Property::BorderImageRepeat(repeat)) |
| 357 | + self.decls.push(Property::BorderImageRepeat(repeat)) |
301 | 358 | } |
302 | 359 | } |
303 | 360 |
|
304 | | - decls |
305 | | - } |
306 | | -} |
307 | | - |
308 | | -impl BorderImageHandler { |
309 | | - pub fn reset(&mut self) { |
310 | | - self.source = None; |
311 | | - self.slice = None; |
312 | | - self.width = None; |
313 | | - self.outset = None; |
314 | | - self.repeat = None; |
315 | | - } |
316 | | - |
317 | | - pub fn set_border_image(&mut self, border_image: &BorderImage) { |
318 | | - self.source = Some(border_image.source.clone()); |
319 | | - self.slice = Some(border_image.slice.clone()); |
320 | | - self.width = Some(border_image.width.clone()); |
321 | | - self.outset = Some(border_image.outset.clone()); |
322 | | - self.repeat = Some(border_image.repeat.clone()); |
| 361 | + self.vendor_prefix = VendorPrefix::empty(); |
323 | 362 | } |
324 | 363 | } |
0 commit comments