Skip to content

Commit d0d9de7

Browse files
committed
Prefix border-image
1 parent a67d387 commit d0d9de7

File tree

5 files changed

+159
-37
lines changed

5 files changed

+159
-37
lines changed

src/declaration.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ impl DeclarationHandler {
6161
pub fn new(important: bool, targets: Option<Browsers>) -> Self {
6262
DeclarationHandler {
6363
important,
64+
border: BorderHandler::new(targets),
6465
flex: FlexHandler::new(targets),
6566
align: AlignHandler::new(targets),
6667
transition: TransitionHandler::new(targets),

src/lib.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,78 @@ mod tests {
428428
}
429429
"#
430430
});
431+
432+
test(r#"
433+
.foo {
434+
-webkit-border-image: url("test.png") 60;
435+
}
436+
"#, indoc! {r#"
437+
.foo {
438+
-webkit-border-image: url(test.png) 60;
439+
}
440+
"#
441+
});
442+
443+
test(r#"
444+
.foo {
445+
-webkit-border-image: url("test.png") 60;
446+
border-image: url("test.png") 60;
447+
}
448+
"#, indoc! {r#"
449+
.foo {
450+
-webkit-border-image: url(test.png) 60;
451+
border-image: url(test.png) 60;
452+
}
453+
"#
454+
});
455+
456+
test(r#"
457+
.foo {
458+
-webkit-border-image: url("test.png") 60;
459+
border-image-source: url(foo.png);
460+
}
461+
"#, indoc! {r#"
462+
.foo {
463+
-webkit-border-image: url(test.png) 60;
464+
border-image-source: url(foo.png);
465+
}
466+
"#
467+
});
468+
469+
prefix_test(r#"
470+
.foo {
471+
border-image: url("test.png") 60;
472+
}
473+
"#, indoc! {r#"
474+
.foo {
475+
-webkit-border-image: url(test.png) 60;
476+
-moz-border-image: url(test.png) 60;
477+
-o-border-image: url(test.png) 60;
478+
border-image: url(test.png) 60;
479+
}
480+
"#
481+
}, Browsers {
482+
safari: Some(4 << 16),
483+
firefox: Some(4 << 16),
484+
opera: Some(12 << 16),
485+
..Browsers::default()
486+
});
487+
488+
prefix_test(r#"
489+
.foo {
490+
border-image: url(foo.png) 10 40 fill / 10px round;
491+
}
492+
"#, indoc! {r#"
493+
.foo {
494+
border-image: url(foo.png) 10 40 fill / 10px round;
495+
}
496+
"#
497+
}, Browsers {
498+
safari: Some(4 << 16),
499+
firefox: Some(4 << 16),
500+
opera: Some(12 << 16),
501+
..Browsers::default()
502+
});
431503
}
432504

433505
#[test]

src/properties/border.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::values::rect::Rect;
77
use crate::macros::*;
88
use super::border_image::*;
99
use super::border_radius::*;
10+
use super::prefixes::Browsers;
1011
use crate::printer::Printer;
1112
use std::fmt::Write;
1213

@@ -223,6 +224,15 @@ pub struct BorderHandler {
223224
border_radius_handler: BorderRadiusHandler
224225
}
225226

227+
impl BorderHandler {
228+
pub fn new(targets: Option<Browsers>) -> BorderHandler {
229+
BorderHandler {
230+
border_image_handler: BorderImageHandler::new(targets),
231+
..BorderHandler::default()
232+
}
233+
}
234+
}
235+
226236
impl PropertyHandler for BorderHandler {
227237
fn handle_property(&mut self, property: &Property) -> bool {
228238
use Property::*;

src/properties/border_image.rs

Lines changed: 75 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use crate::values::{length::*, percentage::{Percentage, NumberOrPercentage}, number::serialize_number};
22
use cssparser::*;
33
use crate::traits::{Parse, ToCss, PropertyHandler};
4-
use crate::properties::Property;
4+
use crate::properties::{Property, VendorPrefix};
5+
use super::prefixes::{Feature, Browsers};
56
use crate::values::rect::Rect;
67
use crate::values::image::Image;
78
use crate::macros::*;
@@ -240,85 +241,123 @@ impl ToCss for BorderImage {
240241

241242
#[derive(Default, Debug)]
242243
pub struct BorderImageHandler {
244+
targets: Option<Browsers>,
243245
source: Option<Image>,
244246
slice: Option<BorderImageSlice>,
245247
width: Option<Rect<BorderImageSideWidth>>,
246248
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+
}
248262
}
249263

250264
impl PropertyHandler for BorderImageHandler {
251265
fn handle_property(&mut self, property: &Property) -> bool {
252266
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+
253277
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+
},
260287
_ => return false
261288
}
262289

263290
true
264291
}
265292

266293
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) {
268317
let source = std::mem::take(&mut self.source);
269318
let slice = std::mem::take(&mut self.slice);
270319
let width = std::mem::take(&mut self.width);
271320
let outset = std::mem::take(&mut self.outset);
272321
let repeat = std::mem::take(&mut self.repeat);
273322

274323
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 {
276333
source: source.unwrap(),
277-
slice: slice.unwrap(),
334+
slice,
278335
width: width.unwrap(),
279336
outset: outset.unwrap(),
280337
repeat: repeat.unwrap()
281-
}))
338+
}, prefix))
282339
} else {
283340
if let Some(source) = source {
284-
decls.push(Property::BorderImageSource(source))
341+
self.decls.push(Property::BorderImageSource(source))
285342
}
286343

287344
if let Some(slice) = slice {
288-
decls.push(Property::BorderImageSlice(slice))
345+
self.decls.push(Property::BorderImageSlice(slice))
289346
}
290347

291348
if let Some(width) = width {
292-
decls.push(Property::BorderImageWidth(width))
349+
self.decls.push(Property::BorderImageWidth(width))
293350
}
294351

295352
if let Some(outset) = outset {
296-
decls.push(Property::BorderImageOutset(outset))
353+
self.decls.push(Property::BorderImageOutset(outset))
297354
}
298355

299356
if let Some(repeat) = repeat {
300-
decls.push(Property::BorderImageRepeat(repeat))
357+
self.decls.push(Property::BorderImageRepeat(repeat))
301358
}
302359
}
303360

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();
323362
}
324363
}

src/properties/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ define_properties! {
268268
"border-image-repeat": BorderImageRepeat(BorderImageRepeat),
269269
"border-image-width": BorderImageWidth(Rect<BorderImageSideWidth>),
270270
"border-image-slice": BorderImageSlice(BorderImageSlice),
271-
"border-image": BorderImage(BorderImage),
271+
"border-image": BorderImage(BorderImage, VendorPrefix) / "webkit" / "moz" / "o",
272272

273273
"border-color": BorderColor(Rect<CssColor>),
274274
"border-style": BorderStyle(Rect<BorderStyle>),

0 commit comments

Comments
 (0)