Skip to content

Commit

Permalink
Deduplicate custom properties
Browse files Browse the repository at this point in the history
Fixes #466
  • Loading branch information
devongovett committed Feb 13, 2024
1 parent 5503ecd commit 7a34df2
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 28 deletions.
68 changes: 59 additions & 9 deletions src/declaration.rs
@@ -1,14 +1,15 @@
//! CSS declarations.

use std::borrow::Cow;
use std::collections::HashMap;
use std::ops::Range;

use crate::context::PropertyHandlerContext;
use crate::context::{DeclarationContext, PropertyHandlerContext};
use crate::error::{ParserError, PrinterError};
use crate::parser::ParserOptions;
use crate::printer::Printer;
use crate::properties::box_shadow::BoxShadowHandler;
use crate::properties::custom::CustomPropertyName;
use crate::properties::custom::{CustomProperty, CustomPropertyName};
use crate::properties::masking::MaskHandler;
use crate::properties::{
align::AlignHandler,
Expand All @@ -30,10 +31,11 @@ use crate::properties::{
text::TextDecorationHandler,
transform::TransformHandler,
transition::TransitionHandler,
ui::ColorSchemeHandler
ui::ColorSchemeHandler,
};
use crate::properties::{Property, PropertyId};
use crate::traits::{PropertyHandler, ToCss};
use crate::values::ident::DashedIdent;
use crate::values::string::CowArcStr;
#[cfg(feature = "visitor")]
use crate::visitor::Visit;
Expand Down Expand Up @@ -513,6 +515,7 @@ pub(crate) struct DeclarationHandler<'i> {
color_scheme: ColorSchemeHandler,
fallback: FallbackHandler,
prefix: PrefixHandler,
custom_properties: HashMap<DashedIdent<'i>, usize>,
decls: DeclarationList<'i>,
}

Expand All @@ -522,12 +525,6 @@ impl<'i> DeclarationHandler<'i> {
property: &Property<'i>,
context: &mut PropertyHandlerContext<'i, '_>,
) -> bool {
if !context.unused_symbols.is_empty()
&& matches!(property, Property::Custom(custom) if context.unused_symbols.contains(custom.name.as_ref()))
{
return true;
}

self.background.handle_property(property, &mut self.decls, context)
|| self.border.handle_property(property, &mut self.decls, context)
|| self.outline.handle_property(property, &mut self.decls, context)
Expand Down Expand Up @@ -555,6 +552,58 @@ impl<'i> DeclarationHandler<'i> {
|| self.color_scheme.handle_property(property, &mut self.decls, context)
|| self.fallback.handle_property(property, &mut self.decls, context)
|| self.prefix.handle_property(property, &mut self.decls, context)
|| self.handle_custom_property(property, context)
}

fn handle_custom_property(
&mut self,
property: &Property<'i>,
context: &mut PropertyHandlerContext<'i, '_>,
) -> bool {
if let Property::Custom(custom) = property {
if context.unused_symbols.contains(custom.name.as_ref()) {
return true;
}

if let CustomPropertyName::Custom(name) = &custom.name {
if let Some(index) = self.custom_properties.get(name) {
if self.decls[*index] == *property {
return true;
}
let mut custom = custom.clone();
self.add_conditional_fallbacks(&mut custom, context);
self.decls[*index] = Property::Custom(custom);
} else {
self.custom_properties.insert(name.clone(), self.decls.len());
let mut custom = custom.clone();
self.add_conditional_fallbacks(&mut custom, context);
self.decls.push(Property::Custom(custom));
}

return true;
}
}

false
}

fn add_conditional_fallbacks(
&self,
custom: &mut CustomProperty<'i>,
context: &mut PropertyHandlerContext<'i, '_>,
) {
if context.context != DeclarationContext::Keyframes {
let fallbacks = custom.value.get_fallbacks(context.targets);
for (condition, fallback) in fallbacks {
context.add_conditional_property(
condition,
Property::Custom(CustomProperty {
name: custom.name.clone(),
value: fallback,
}),
);
}
}
}

pub fn finalize(&mut self, context: &mut PropertyHandlerContext<'i, '_>) {
Expand Down Expand Up @@ -585,5 +634,6 @@ impl<'i> DeclarationHandler<'i> {
self.color_scheme.finalize(&mut self.decls, context);
self.fallback.finalize(&mut self.decls, context);
self.prefix.finalize(&mut self.decls, context);
self.custom_properties.clear();
}
}
16 changes: 16 additions & 0 deletions src/lib.rs
Expand Up @@ -8901,6 +8901,22 @@ mod tests {
}
"#},
);
test(
r#"
.foo {
--foo: red;
--foo: purple;
}
.foo {
--foo: green;
}
"#,
indoc! {r#"
.foo {
--foo: green;
}
"#},
);
test(
r#"
.foo {
Expand Down
20 changes: 1 addition & 19 deletions src/properties/prefix_handler.rs
@@ -1,9 +1,8 @@
#![allow(non_snake_case)]
use super::{Property, PropertyId};
use crate::context::{DeclarationContext, PropertyHandlerContext};
use crate::context::PropertyHandlerContext;
use crate::declaration::DeclarationList;
use crate::prefixes::Feature;
use crate::properties::custom::CustomProperty;
use crate::traits::{FallbackValues, IsCompatible, PropertyHandler};
use crate::vendor_prefix::VendorPrefix;

Expand Down Expand Up @@ -121,23 +120,6 @@ macro_rules! define_fallbacks {
}
}
)+
Property::Custom(custom) => {
let mut custom = custom.clone();
if context.context != DeclarationContext::Keyframes {
let fallbacks = custom.value.get_fallbacks(context.targets);
for (condition, fallback) in fallbacks {
context.add_conditional_property(
condition,
Property::Custom(CustomProperty {
name: custom.name.clone(),
value: fallback
})
);
}
}

dest.push(Property::Custom(custom))
}
Property::Unparsed(val) => {
let (mut unparsed, index) = match val.property_id {
$(
Expand Down

0 comments on commit 7a34df2

Please sign in to comment.