diff --git a/src/lib.rs b/src/lib.rs index 2005a6da..f0547df0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29411,6 +29411,76 @@ mod tests { assert_eq!(property, Property::ColorInterpolation(svg::ColorInterpolation::SRGB)); } + #[test] + fn test_mask_image_prefix_duplicates() { + let targets = Browsers { + chrome: Some(90 << 16), + ..Browsers::default() + }; + + for (source, expected) in [ + ( + ".foo { -webkit-mask-image: var(--image); mask-image: var(--image) }", + indoc! { r#" + .foo { + -webkit-mask-image: var(--image); + mask-image: var(--image); + } + "#}, + ), + ( + ".foo { mask-image: var(--first); mask-image: var(--second) }", + indoc! { r#" + .foo { + -webkit-mask-image: var(--first); + mask-image: var(--first); + -webkit-mask-image: var(--second); + mask-image: var(--second); + } + "#}, + ), + ( + ".foo { mask-image: var(--image); mask-position: center; -webkit-mask-image: var(--image) }", + indoc! { r#" + .foo { + -webkit-mask-image: var(--image); + mask-image: var(--image); + -webkit-mask-position: center; + mask-position: center; + -webkit-mask-image: var(--image); + } + "#}, + ), + ( + ".foo { mask-image: var(--image) !important; -webkit-mask-image: var(--image) }", + indoc! { r#" + .foo { + -webkit-mask-image: var(--image); + -webkit-mask-image: var(--image) !important; + mask-image: var(--image) !important; + } + "#}, + ), + ] { + prefix_test(source, expected, targets); + prefix_test(expected, expected, targets); + } + + prefix_test( + ".foo { -webkit-mask-image: var(--image); mask-image: var(--image) }", + indoc! { r#" + .foo { + -webkit-mask-image: var(--image); + mask-image: var(--image); + } + "#}, + Browsers { + chrome: Some(130 << 16), + ..Browsers::default() + }, + ); + } + #[test] fn test_filter() { property_range_test( diff --git a/src/properties/masking.rs b/src/properties/masking.rs index 784e6b11..e0ae9132 100644 --- a/src/properties/masking.rs +++ b/src/properties/masking.rs @@ -704,7 +704,20 @@ impl<'i> PropertyHandler<'i> for MaskHandler<'i> { self .flushed_properties .insert(MaskProperty::try_from(&val.property_id).unwrap()); - dest.push(Property::Unparsed(unparsed)); + let mut merged = false; + if let (PropertyId::MaskImage(prefix), Some(Property::Unparsed(previous))) = + (&unparsed.property_id, dest.last_mut()) + { + if let PropertyId::MaskImage(previous_prefix) = &mut previous.property_id { + if previous.value == unparsed.value { + *previous_prefix |= *prefix; + merged = true; + } + } + } + if !merged { + dest.push(Property::Unparsed(unparsed)); + } } Property::MaskBorderSource(val) => property!(border_source, val, &VendorPrefix::None), Property::WebKitMaskBoxImageSource(val, _) => property!(border_source, val, &VendorPrefix::WebKit),