Skip to content

Commit 6bd2761

Browse files
committed
Merge @supports declarations with the same property (minus prefix) and value
1 parent e37b9ed commit 6bd2761

File tree

3 files changed

+114
-3
lines changed

3 files changed

+114
-3
lines changed

src/lib.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13123,6 +13123,68 @@ mod tests {
1312313123
..Default::default()
1312413124
},
1312513125
);
13126+
prefix_test(
13127+
r#"
13128+
@supports ((-webkit-backdrop-filter: blur(10px)) or (backdrop-filter: blur(10px))) {
13129+
div {
13130+
backdrop-filter: blur(10px);
13131+
}
13132+
}
13133+
"#,
13134+
indoc! { r#"
13135+
@supports ((-webkit-backdrop-filter: blur(10px)) or (backdrop-filter: blur(10px))) {
13136+
div {
13137+
-webkit-backdrop-filter: blur(10px);
13138+
backdrop-filter: blur(10px);
13139+
}
13140+
}
13141+
"#},
13142+
Browsers {
13143+
safari: Some(14 << 16),
13144+
..Default::default()
13145+
},
13146+
);
13147+
prefix_test(
13148+
r#"
13149+
@supports ((-webkit-backdrop-filter: blur(20px)) or (backdrop-filter: blur(10px))) {
13150+
div {
13151+
backdrop-filter: blur(10px);
13152+
}
13153+
}
13154+
"#,
13155+
indoc! { r#"
13156+
@supports ((-webkit-backdrop-filter: blur(20px))) or ((-webkit-backdrop-filter: blur(10px)) or (backdrop-filter: blur(10px))) {
13157+
div {
13158+
-webkit-backdrop-filter: blur(10px);
13159+
backdrop-filter: blur(10px);
13160+
}
13161+
}
13162+
"#},
13163+
Browsers {
13164+
safari: Some(14 << 16),
13165+
..Default::default()
13166+
},
13167+
);
13168+
prefix_test(
13169+
r#"
13170+
@supports ((-webkit-backdrop-filter: blur(10px)) or (backdrop-filter: blur(10px))) {
13171+
div {
13172+
backdrop-filter: blur(10px);
13173+
}
13174+
}
13175+
"#,
13176+
indoc! { r#"
13177+
@supports (backdrop-filter: blur(10px)) {
13178+
div {
13179+
backdrop-filter: blur(10px);
13180+
}
13181+
}
13182+
"#},
13183+
Browsers {
13184+
chrome: Some(80 << 16),
13185+
..Default::default()
13186+
},
13187+
);
1312613188
minify_test(
1312713189
r#"
1312813190
@supports (width: calc(10px * 2)) {

src/properties/mod.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ macro_rules! define_properties {
322322
}
323323
}
324324

325-
fn with_prefix(&self, prefix: VendorPrefix) -> PropertyId<'i> {
325+
pub(crate) fn with_prefix(&self, prefix: VendorPrefix) -> PropertyId<'i> {
326326
use PropertyId::*;
327327
match self {
328328
$(
@@ -344,6 +344,26 @@ macro_rules! define_properties {
344344
}
345345
}
346346

347+
pub(crate) fn add_prefix(&mut self, prefix: VendorPrefix) {
348+
use PropertyId::*;
349+
match self {
350+
$(
351+
$(#[$meta])*
352+
$property$((vp_name!($vp, p)))? => {
353+
macro_rules! get_prefixed {
354+
($v: ty) => {{
355+
*p |= prefix;
356+
}};
357+
() => {{}};
358+
}
359+
360+
get_prefixed!($($vp)?)
361+
},
362+
)+
363+
_ => {}
364+
}
365+
}
366+
347367
pub(crate) fn set_prefixes_for_targets(&mut self, targets: Targets) {
348368
match self {
349369
$(

src/rules/supports.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! The `@supports` rule.
22
3+
use std::collections::HashMap;
4+
35
use super::Location;
46
use super::{CssRuleList, MinifyContext};
57
use crate::error::{MinifyError, ParserError, PrinterError};
@@ -159,6 +161,7 @@ impl<'i> Parse<'i> for SupportsCondition<'i> {
159161
let in_parens = Self::parse_in_parens(input)?;
160162
let mut expected_type = None;
161163
let mut conditions = Vec::new();
164+
let mut seen_declarations = HashMap::new();
162165

163166
loop {
164167
let condition = input.try_parse(|input| {
@@ -185,14 +188,40 @@ impl<'i> Parse<'i> for SupportsCondition<'i> {
185188

186189
if let Ok(condition) = condition {
187190
if conditions.is_empty() {
188-
conditions.push(in_parens.clone())
191+
conditions.push(in_parens.clone());
192+
if let SupportsCondition::Declaration { property_id, value } = &in_parens {
193+
seen_declarations.insert((property_id.with_prefix(VendorPrefix::None), value.clone()), 0);
194+
}
195+
}
196+
197+
if let SupportsCondition::Declaration { property_id, value } = condition {
198+
// Merge multiple declarations with the same property id (minus prefix) and value together.
199+
let property_id = property_id.with_prefix(VendorPrefix::None);
200+
let key = (property_id.clone(), value.clone());
201+
if let Some(index) = seen_declarations.get(&key) {
202+
if let SupportsCondition::Declaration {
203+
property_id: cur_property,
204+
..
205+
} = &mut conditions[*index]
206+
{
207+
cur_property.add_prefix(property_id.prefix());
208+
}
209+
} else {
210+
seen_declarations.insert(key, conditions.len());
211+
conditions.push(SupportsCondition::Declaration { property_id, value });
212+
}
213+
} else {
214+
conditions.push(condition);
189215
}
190-
conditions.push(condition)
191216
} else {
192217
break;
193218
}
194219
}
195220

221+
if conditions.len() == 1 {
222+
return Ok(conditions.pop().unwrap());
223+
}
224+
196225
match expected_type {
197226
Some(1) => Ok(SupportsCondition::And(conditions)),
198227
Some(2) => Ok(SupportsCondition::Or(conditions)),

0 commit comments

Comments
 (0)