swc_css_compat/compiler/
legacy_rgb_and_hsl.rs
1use std::f64::consts::PI;
2
3use swc_css_ast::{
4 matches_eq_ignore_ascii_case, AbsoluteColorBase, AlphaValue, Angle, ComponentValue, Number,
5 Percentage,
6};
7use swc_css_utils::{clamp_unit_f64, round_alpha};
8
9use crate::compiler::Compiler;
10
11impl Compiler {
12 pub(crate) fn process_rgb_and_hsl(&mut self, n: &mut AbsoluteColorBase) {
13 if let AbsoluteColorBase::Function(function) = n {
14 let is_rgb = matches_eq_ignore_ascii_case!(function.name.as_str(), "rgb", "rgba");
15 let is_hsl = matches_eq_ignore_ascii_case!(function.name.as_str(), "hsl", "hsla");
16
17 if is_rgb {
18 function.value = function
19 .value
20 .drain(..)
21 .map(|n| match n {
22 ComponentValue::Percentage(percentage) => {
23 let Percentage {
24 span,
25 value: Number { value, .. },
26 ..
27 } = &*percentage;
28
29 ComponentValue::Number(Box::new(Number {
30 span: *span,
31 value: clamp_unit_f64(value / 100.0) as f64,
32 raw: None,
33 }))
34 }
35 _ => n,
36 })
37 .collect();
38 } else if is_hsl {
39 function.value = function
40 .value
41 .drain(..)
42 .map(|n| {
43 if let Some(Angle {
44 span,
45 value: Number { value, .. },
46 unit,
47 ..
48 }) = n.as_hue().and_then(|hue| hue.as_angle())
49 {
50 let value = match &*unit.value.to_ascii_lowercase() {
51 "deg" => *value,
52 "grad" => value * 180.0 / 200.0,
53 "rad" => value * 180.0 / PI,
54 "turn" => value * 360.0,
55 _ => {
56 unreachable!();
57 }
58 };
59
60 ComponentValue::Number(Box::new(Number {
61 span: *span,
62 value: value.round(),
63 raw: None,
64 }))
65 } else {
66 n
67 }
68 })
69 .collect();
70 }
71
72 if is_rgb || is_hsl {
73 if let Some(alpha_value) = function
74 .value
75 .last_mut()
76 .and_then(|component_value| component_value.as_mut_alpha_value())
77 .map(|alpha_value| alpha_value.as_mut())
78 {
79 if let AlphaValue::Percentage(Percentage {
80 span,
81 value: Number { value: a, .. },
82 ..
83 }) = alpha_value
84 {
85 *alpha_value = AlphaValue::Number(Number {
86 span: *span,
87 value: round_alpha(*a / 100.0),
88 raw: None,
89 });
90 }
91 }
92 }
93 }
94 }
95}