diff --git a/crates/swc_css_prefixer/data/prefixes_and_browsers.json b/crates/swc_css_prefixer/data/prefixes_and_browsers.json index 54dc24d695f0..6c0ade61f5de 100644 --- a/crates/swc_css_prefixer/data/prefixes_and_browsers.json +++ b/crates/swc_css_prefixer/data/prefixes_and_browsers.json @@ -3873,5 +3873,23 @@ "firefox": "3" }, {} + ], + "opacity": [ + { + "chrome": "4", + "edge": "12", + "firefox": "2", + "samsung": "4", + "ios": "3.2", + "opera": "10", + "safari": "3.1", + "ie": "6" + }, + { + "chrome": "77", + "edge": "78", + "firefox": "69", + "samsung": "11.2" + } ] } diff --git a/crates/swc_css_prefixer/src/prefixer.rs b/crates/swc_css_prefixer/src/prefixer.rs index 9db492809f78..2bc7e75f7cff 100644 --- a/crates/swc_css_prefixer/src/prefixer.rs +++ b/crates/swc_css_prefixer/src/prefixer.rs @@ -535,6 +535,16 @@ macro_rules! to_integer { }}; } +macro_rules! to_number { + ($val:expr) => {{ + ComponentValue::Number(Box::new(Number { + span: DUMMY_SP, + value: $val, + raw: None, + })) + }}; +} + #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum Prefix { Webkit, @@ -1431,6 +1441,36 @@ impl VisitMut for Prefixer { } } }}; + + ($property:expr, $value:expr) => {{ + if should_prefix($property, self.env, true) { + // Check we don't have prefixed property + + let name = DeclarationName::Ident(Ident { + span: DUMMY_SP, + value: $property.into(), + raw: None, + }); + + let value: Option Vec>> = $value; + + if let Some(value) = value { + self.added_declarations.push(Box::new(Declaration { + span: n.span, + name, + value: value(), + important: n.important.clone(), + })); + } else { + self.added_declarations.push(Box::new(Declaration { + span: n.span, + name, + value: n.value.clone(), + important: n.important.clone(), + })); + } + } + }}; } let property_name = &*name.to_ascii_lowercase(); @@ -1970,6 +2010,22 @@ impl VisitMut for Prefixer { ); } + "opacity" if should_prefix("opacity", self.env, true) => { + let old_value = match n.value.get(0) { + Some(ComponentValue::Percentage(percentage)) => Some(percentage.value.value), + _ => None, + }; + + if let Some(old_value) = old_value { + let rounded_alpha = (old_value * 1000.0).round() / 100000.0; + + add_declaration!( + "opacity", + Some(Box::new(|| { vec![to_number!(rounded_alpha)] })) + ); + } + } + "order" => { let old_spec_num = match n.value.get(0) { Some(ComponentValue::Integer(integer)) => Some(integer.value + 1), diff --git a/crates/swc_css_prefixer/tests/fixture/opacity/input.css b/crates/swc_css_prefixer/tests/fixture/opacity/input.css new file mode 100644 index 000000000000..a65fc1848c2d --- /dev/null +++ b/crates/swc_css_prefixer/tests/fixture/opacity/input.css @@ -0,0 +1,18 @@ +.class { + opacity: 0%; + opacity: 45%; + opacity: 0.45%; + opacity: 0.045%; + opacity: 0.00000000000045%; + opacity: 0.33%; + opacity: 0.3333333333%; + opacity: 99%; + opacity: 100%; + opacity: 120%; + opacity: 0.9999999999%; +} + +.bar { + opacity: 0.3; + opacity: initial; +} \ No newline at end of file diff --git a/crates/swc_css_prefixer/tests/fixture/opacity/output.css b/crates/swc_css_prefixer/tests/fixture/opacity/output.css new file mode 100644 index 000000000000..4bbb71f26491 --- /dev/null +++ b/crates/swc_css_prefixer/tests/fixture/opacity/output.css @@ -0,0 +1,28 @@ +.class { + opacity: 0; + opacity: 0%; + opacity: 0.45; + opacity: 45%; + opacity: 0.0045; + opacity: 0.45%; + opacity: 0.00045; + opacity: 0.045%; + opacity: 0; + opacity: 0.00000000000045%; + opacity: 0.0033; + opacity: 0.33%; + opacity: 0.00333; + opacity: 0.3333333333%; + opacity: 0.99; + opacity: 99%; + opacity: 1; + opacity: 100%; + opacity: 1.2; + opacity: 120%; + opacity: 0.01; + opacity: 0.9999999999%; +} +.bar { + opacity: 0.3; + opacity: initial; +} diff --git a/crates/swc_css_prefixer/tests/fixture/opacity/output.defaults-not-ie-11.css b/crates/swc_css_prefixer/tests/fixture/opacity/output.defaults-not-ie-11.css new file mode 100644 index 000000000000..4bbb71f26491 --- /dev/null +++ b/crates/swc_css_prefixer/tests/fixture/opacity/output.defaults-not-ie-11.css @@ -0,0 +1,28 @@ +.class { + opacity: 0; + opacity: 0%; + opacity: 0.45; + opacity: 45%; + opacity: 0.0045; + opacity: 0.45%; + opacity: 0.00045; + opacity: 0.045%; + opacity: 0; + opacity: 0.00000000000045%; + opacity: 0.0033; + opacity: 0.33%; + opacity: 0.00333; + opacity: 0.3333333333%; + opacity: 0.99; + opacity: 99%; + opacity: 1; + opacity: 100%; + opacity: 1.2; + opacity: 120%; + opacity: 0.01; + opacity: 0.9999999999%; +} +.bar { + opacity: 0.3; + opacity: initial; +}