1use swc_common::DUMMY_SP;
2use swc_css_ast::{
3 Dimension, Ident, MediaFeature, MediaFeatureName, MediaFeaturePlain, MediaFeatureRange,
4 MediaFeatureRangeComparison, MediaFeatureRangeInterval, MediaFeatureValue,
5};
6
7use crate::compiler::Compiler;
8
9impl Compiler {
10 pub(crate) fn get_legacy_media_feature(
11 &mut self,
12 n: &mut MediaFeature,
13 ) -> Option<(MediaFeature, Option<MediaFeature>)> {
14 match n {
15 MediaFeature::Range(MediaFeatureRange {
16 span,
17 left,
18 comparison,
19 right,
20 ..
21 }) => {
22 if let MediaFeatureValue::Ident(name) = &**left {
23 let name = match comparison {
24 MediaFeatureRangeComparison::Lt | MediaFeatureRangeComparison::Le => {
25 self.get_right_media_feature_name(name)
26 }
27 MediaFeatureRangeComparison::Eq => {
28 Some(MediaFeatureName::Ident(name.clone()))
29 }
30 _ => self.get_left_media_feature_name(name),
31 }?;
32
33 let original_value = (**right).clone();
34 let value = match comparison {
35 MediaFeatureRangeComparison::Lt => self.get_lt_value(original_value),
36 MediaFeatureRangeComparison::Gt => self.get_gt_value(original_value),
37 _ => Some(original_value),
38 }?;
39
40 return Some((
41 MediaFeature::Plain(MediaFeaturePlain {
42 span: *span,
43 name,
44 value: Box::new(value),
45 }),
46 None,
47 ));
48 } else if let MediaFeatureValue::Ident(name) = &**right {
49 let name = match comparison {
50 MediaFeatureRangeComparison::Lt | MediaFeatureRangeComparison::Le => {
51 self.get_left_media_feature_name(name)
52 }
53 MediaFeatureRangeComparison::Eq => {
54 Some(MediaFeatureName::Ident(name.clone()))
55 }
56 _ => self.get_right_media_feature_name(name),
57 }?;
58
59 let original_value = (**left).clone();
60 let value = match comparison {
61 MediaFeatureRangeComparison::Lt => self.get_gt_value(original_value),
62 MediaFeatureRangeComparison::Gt => self.get_lt_value(original_value),
63 _ => Some(original_value),
64 }?;
65
66 return Some((
67 MediaFeature::Plain(MediaFeaturePlain {
68 span: *span,
69 name,
70 value: Box::new(value),
71 }),
72 None,
73 ));
74 }
75 }
76 MediaFeature::RangeInterval(MediaFeatureRangeInterval {
77 span,
78 left,
79 left_comparison,
80 name: MediaFeatureName::Ident(name),
81 right,
82 right_comparison,
83 ..
84 }) => {
85 let left_name = match left_comparison {
86 MediaFeatureRangeComparison::Gt | MediaFeatureRangeComparison::Ge => {
87 self.get_right_media_feature_name(name)
88 }
89 _ => self.get_left_media_feature_name(name),
90 }?;
91
92 let left_value = match left_comparison {
93 MediaFeatureRangeComparison::Lt => self.get_gt_value((**left).clone()),
94 MediaFeatureRangeComparison::Gt => self.get_lt_value((**left).clone()),
95 _ => Some((**left).clone()),
96 }?;
97
98 let left = MediaFeature::Plain(MediaFeaturePlain {
99 span: *span,
100 name: left_name,
101 value: Box::new(left_value),
102 });
103
104 let right_name = match right_comparison {
105 MediaFeatureRangeComparison::Gt | MediaFeatureRangeComparison::Ge => {
106 self.get_left_media_feature_name(name)
107 }
108 _ => self.get_right_media_feature_name(name),
109 }?;
110
111 let right_value = match right_comparison {
112 MediaFeatureRangeComparison::Lt => self.get_lt_value((**right).clone()),
113 MediaFeatureRangeComparison::Gt => self.get_gt_value((**right).clone()),
114 _ => Some((**right).clone()),
115 }?;
116
117 let right = MediaFeature::Plain(MediaFeaturePlain {
118 span: *span,
119 name: right_name,
120 value: Box::new(right_value),
121 });
122
123 return Some((left, Some(right)));
124 }
125 _ => {}
126 }
127
128 None
129 }
130
131 fn get_left_media_feature_name(&self, name: &Ident) -> Option<MediaFeatureName> {
132 let value = match &*name.value {
133 "width" => "min-width",
134 "height" => "min-height",
135 "device-width" => "min-device-width",
136 "device-height" => "min-device-height",
137 "aspect-ratio" => "min-aspect-ratio",
138 "device-aspect-ratio" => "min-device-aspect-ratio",
139 "color" => "min-color",
140 "color-index" => "min-color-index",
141 "monochrome" => "min-monochrome",
142 "resolution" => "min-resolution",
143 _ => return None,
144 };
145
146 Some(MediaFeatureName::Ident(Ident {
147 span: DUMMY_SP,
148 value: value.into(),
149 raw: None,
150 }))
151 }
152
153 fn get_right_media_feature_name(&self, name: &Ident) -> Option<MediaFeatureName> {
154 let value = match &*name.value {
155 "width" => "max-width",
156 "height" => "max-height",
157 "device-width" => "max-device-width",
158 "device-height" => "max-device-height",
159 "aspect-ratio" => "max-aspect-ratio",
160 "device-aspect-ratio" => "max-device-aspect-ratio",
161 "color" => "max-color",
162 "color-index" => "max-color-index",
163 "monochrome" => "max-monochrome",
164 "resolution" => "max-resolution",
165 _ => return None,
166 };
167
168 Some(MediaFeatureName::Ident(Ident {
169 span: DUMMY_SP,
170 value: value.into(),
171 raw: None,
172 }))
173 }
174
175 fn get_lt_value(&self, mut value: MediaFeatureValue) -> Option<MediaFeatureValue> {
176 match &mut value {
177 MediaFeatureValue::Number(number) => {
178 number.value -= 1.0;
179 number.raw = None;
180
181 Some(value)
182 }
183 MediaFeatureValue::Dimension(dimension) => {
184 match dimension {
185 Dimension::Length(length) => {
186 length.value.value -= 0.001;
187 length.value.raw = None;
188 }
189 _ => {
190 return None;
191 }
192 }
193
194 Some(value)
195 }
196 MediaFeatureValue::Ratio(ration) => {
197 ration.left.value -= 0.001;
198 ration.left.raw = None;
199
200 Some(value)
201 }
202 _ => None,
203 }
204 }
205
206 fn get_gt_value(&self, mut value: MediaFeatureValue) -> Option<MediaFeatureValue> {
207 match &mut value {
208 MediaFeatureValue::Number(number) => {
209 number.value += 1.0;
210 number.raw = None;
211
212 Some(value)
213 }
214 MediaFeatureValue::Dimension(dimension) => {
215 match dimension {
216 Dimension::Length(length) => {
217 length.value.value += 0.001;
218 length.value.raw = None;
219 }
220 _ => {
221 return None;
222 }
223 }
224
225 Some(value)
226 }
227 MediaFeatureValue::Ratio(ration) => {
228 ration.left.value += 0.001;
229 ration.left.raw = None;
230
231 Some(value)
232 }
233 _ => None,
234 }
235 }
236}