swc_css_compat/compiler/
color_hex_alpha.rs1use swc_atoms::atom;
2use swc_common::DUMMY_SP;
3use swc_css_ast::{
4 AbsoluteColorBase, AlphaValue, Color, ComponentValue, Delimiter, DelimiterValue, Function,
5 FunctionName, Ident, Number,
6};
7use swc_css_utils::{hex_to_rgba, round_alpha};
8
9use crate::compiler::Compiler;
10
11fn shorten_hex_color(value: &str) -> Option<&str> {
12 let length = value.len();
13 let chars = value.as_bytes();
14
15 if length == 8 && chars[6] == b'f' && chars[7] == b'f' {
16 return Some(&value[0..6]);
17 } else if length == 4 && chars[3] == b'f' {
18 return Some(&value[0..3]);
19 }
20
21 None
22}
23
24impl Compiler {
25 pub(crate) fn process_color_hex_alpha(&mut self, n: &mut ComponentValue) {
26 if let Some(hex_color) = n
27 .as_mut_color()
28 .and_then(|color| color.as_mut_absolute_color_base())
29 .and_then(|color| color.as_mut_hex_color())
30 {
31 hex_color.value = hex_color.value.to_ascii_lowercase();
32 hex_color.raw = None;
33
34 if hex_color.value.len() != 4 && hex_color.value.len() != 8 {
35 return;
36 }
37
38 if let Some(shortened) = shorten_hex_color(&hex_color.value) {
39 hex_color.value = shortened.into();
40 hex_color.raw = None;
41
42 return;
43 }
44
45 let rgba = hex_to_rgba(&hex_color.value);
46
47 *n = ComponentValue::Color(Box::new(Color::AbsoluteColorBase(
48 AbsoluteColorBase::Function(Function {
49 span: hex_color.span,
50 name: FunctionName::Ident(Ident {
51 span: DUMMY_SP,
52 value: atom!("rgba"),
53 raw: None,
54 }),
55 value: vec![
56 ComponentValue::Number(Box::new(Number {
57 span: DUMMY_SP,
58 value: rgba.0 as f64,
59 raw: None,
60 })),
61 ComponentValue::Delimiter(Box::new(Delimiter {
62 span: DUMMY_SP,
63 value: DelimiterValue::Comma,
64 })),
65 ComponentValue::Number(Box::new(Number {
66 span: DUMMY_SP,
67 value: rgba.1 as f64,
68 raw: None,
69 })),
70 ComponentValue::Delimiter(Box::new(Delimiter {
71 span: DUMMY_SP,
72 value: DelimiterValue::Comma,
73 })),
74 ComponentValue::Number(Box::new(Number {
75 span: DUMMY_SP,
76 value: rgba.2 as f64,
77 raw: None,
78 })),
79 ComponentValue::Delimiter(Box::new(Delimiter {
80 span: DUMMY_SP,
81 value: DelimiterValue::Comma,
82 })),
83 ComponentValue::AlphaValue(Box::new(AlphaValue::Number(Number {
84 span: DUMMY_SP,
85 value: round_alpha(rgba.3),
86 raw: None,
87 }))),
88 ],
89 }),
90 )));
91 }
92 }
93}