add support for Ayatana indicator to Notification plugin
[claws.git] / src / plugins / litehtml_viewer / litehtml / media_query.cpp
blob8c2afff271fb7b8cee1e9245d1a5e9f5d3315598
1 #include "html.h"
2 #include "media_query.h"
3 #include "document.h"
6 litehtml::media_query::media_query()
8 m_media_type = media_type_all;
9 m_not = false;
12 litehtml::media_query::media_query( const media_query& val )
14 m_not = val.m_not;
15 m_expressions = val.m_expressions;
16 m_media_type = val.m_media_type;
19 litehtml::media_query::ptr litehtml::media_query::create_from_string(const string& str, const std::shared_ptr<document>& doc)
21 media_query::ptr query = std::make_shared<media_query>();
23 string_vector tokens;
24 split_string(str, tokens, " \t\r\n", "", "(");
26 for(auto & token : tokens)
28 if(token == "not")
30 query->m_not = true;
31 } else if(token.at(0) == '(')
33 token.erase(0, 1);
34 if(!token.empty() && token.at(token.length() - 1) == ')')
36 token.erase(token.length() - 1, 1);
38 media_query_expression expr;
39 string_vector expr_tokens;
40 split_string(token, expr_tokens, ":");
41 if(!expr_tokens.empty())
43 trim(expr_tokens[0]);
44 expr.feature = (media_feature) value_index(expr_tokens[0], media_feature_strings, media_feature_none);
45 if(expr.feature != media_feature_none)
47 if(expr_tokens.size() == 1)
49 expr.check_as_bool = true;
50 } else
52 trim(expr_tokens[1]);
53 expr.check_as_bool = false;
54 if(expr.feature == media_feature_orientation)
56 expr.val = value_index(expr_tokens[1], media_orientation_strings, media_orientation_landscape);
57 } else
59 string::size_type slash_pos = expr_tokens[1].find('/');
60 if( slash_pos != string::npos )
62 string val1 = expr_tokens[1].substr(0, slash_pos);
63 string val2 = expr_tokens[1].substr(slash_pos + 1);
64 trim(val1);
65 trim(val2);
66 expr.val = atoi(val1.c_str());
67 expr.val2 = atoi(val2.c_str());
68 } else
70 css_length length;
71 length.fromString(expr_tokens[1]);
72 if(length.units() == css_units_dpcm || length.units() == css_units_dpi)
74 expr.val = (int) (length.val() * 2.54);
75 } else
77 if(doc)
79 doc->cvt_units(length, doc->container()->get_default_font_size());
81 expr.val = (int) length.val();
86 query->m_expressions.push_back(expr);
89 } else
91 query->m_media_type = (media_type) value_index(token, media_type_strings, media_type_none);
95 return query;
98 bool litehtml::media_query::check( const media_features& features ) const
100 bool res = false;
101 if(m_media_type == media_type_all || m_media_type == features.type)
103 res = true;
104 for(auto expression : m_expressions)
106 if(!expression.check(features))
108 res = false;
109 break;
114 if(m_not)
116 res = !res;
119 return res;
122 //////////////////////////////////////////////////////////////////////////
124 litehtml::media_query_list::ptr litehtml::media_query_list::create_from_string(const string& str, const std::shared_ptr<document>& doc)
126 media_query_list::ptr list = std::make_shared<media_query_list>();
128 string_vector tokens;
129 split_string(str, tokens, ",");
131 for(auto & token : tokens)
133 trim(token);
134 lcase(token);
136 litehtml::media_query::ptr query = media_query::create_from_string(token, doc);
137 if(query)
139 list->m_queries.push_back(query);
142 if(list->m_queries.empty())
144 list = nullptr;
147 return list;
150 bool litehtml::media_query_list::apply_media_features( const media_features& features )
152 bool apply = false;
154 for(auto & query : m_queries)
156 if(query->check(features))
158 apply = true;
159 break;
163 bool ret = (apply != m_is_used);
164 m_is_used = apply;
165 return ret;
168 bool litehtml::media_query_expression::check( const media_features& features ) const
170 switch(feature)
172 case media_feature_width:
173 if(check_as_bool)
175 return (features.width != 0);
176 } else if(features.width == val)
178 return true;
180 break;
181 case media_feature_min_width:
182 if(features.width >= val)
184 return true;
186 break;
187 case media_feature_max_width:
188 if(features.width <= val)
190 return true;
192 break;
193 case media_feature_height:
194 if(check_as_bool)
196 return (features.height != 0);
197 } else if(features.height == val)
199 return true;
201 break;
202 case media_feature_min_height:
203 if(features.height >= val)
205 return true;
207 break;
208 case media_feature_max_height:
209 if(features.height <= val)
211 return true;
213 break;
215 case media_feature_device_width:
216 if(check_as_bool)
218 return (features.device_width != 0);
219 } else if(features.device_width == val)
221 return true;
223 break;
224 case media_feature_min_device_width:
225 if(features.device_width >= val)
227 return true;
229 break;
230 case media_feature_max_device_width:
231 if(features.device_width <= val)
233 return true;
235 break;
236 case media_feature_device_height:
237 if(check_as_bool)
239 return (features.device_height != 0);
240 } else if(features.device_height == val)
242 return true;
244 break;
245 case media_feature_min_device_height:
246 if(features.device_height >= val)
248 return true;
250 break;
251 case media_feature_max_device_height:
252 if(features.device_height <= val)
254 return true;
256 break;
258 case media_feature_orientation:
259 if(features.height >= features.width)
261 if(val == media_orientation_portrait)
263 return true;
265 } else
267 if(val == media_orientation_landscape)
269 return true;
272 break;
273 case media_feature_aspect_ratio:
274 if(features.height && val2)
276 int ratio_this = round_d( (double) val / (double) val2 * 100 );
277 int ratio_feat = round_d( (double) features.width / (double) features.height * 100.0 );
278 if(ratio_this == ratio_feat)
280 return true;
283 break;
284 case media_feature_min_aspect_ratio:
285 if(features.height && val2)
287 int ratio_this = round_d( (double) val / (double) val2 * 100 );
288 int ratio_feat = round_d( (double) features.width / (double) features.height * 100.0 );
289 if(ratio_feat >= ratio_this)
291 return true;
294 break;
295 case media_feature_max_aspect_ratio:
296 if(features.height && val2)
298 int ratio_this = round_d( (double) val / (double) val2 * 100 );
299 int ratio_feat = round_d( (double) features.width / (double) features.height * 100.0 );
300 if(ratio_feat <= ratio_this)
302 return true;
305 break;
307 case media_feature_device_aspect_ratio:
308 if(features.device_height && val2)
310 int ratio_this = round_d( (double) val / (double) val2 * 100 );
311 int ratio_feat = round_d( (double) features.device_width / (double) features.device_height * 100.0 );
312 if(ratio_feat == ratio_this)
314 return true;
317 break;
318 case media_feature_min_device_aspect_ratio:
319 if(features.device_height && val2)
321 int ratio_this = round_d( (double) val / (double) val2 * 100 );
322 int ratio_feat = round_d( (double) features.device_width / (double) features.device_height * 100.0 );
323 if(ratio_feat >= ratio_this)
325 return true;
328 break;
329 case media_feature_max_device_aspect_ratio:
330 if(features.device_height && val2)
332 int ratio_this = round_d( (double) val / (double) val2 * 100 );
333 int ratio_feat = round_d( (double) features.device_width / (double) features.device_height * 100.0 );
334 if(ratio_feat <= ratio_this)
336 return true;
339 break;
341 case media_feature_color:
342 if(check_as_bool)
344 return (features.color != 0);
345 } else if(features.color == val)
347 return true;
349 break;
350 case media_feature_min_color:
351 if(features.color >= val)
353 return true;
355 break;
356 case media_feature_max_color:
357 if(features.color <= val)
359 return true;
361 break;
363 case media_feature_color_index:
364 if(check_as_bool)
366 return (features.color_index != 0);
367 } else if(features.color_index == val)
369 return true;
371 break;
372 case media_feature_min_color_index:
373 if(features.color_index >= val)
375 return true;
377 break;
378 case media_feature_max_color_index:
379 if(features.color_index <= val)
381 return true;
383 break;
385 case media_feature_monochrome:
386 if(check_as_bool)
388 return (features.monochrome != 0);
389 } else if(features.monochrome == val)
391 return true;
393 break;
394 case media_feature_min_monochrome:
395 if(features.monochrome >= val)
397 return true;
399 break;
400 case media_feature_max_monochrome:
401 if(features.monochrome <= val)
403 return true;
405 break;
407 case media_feature_resolution:
408 if(features.resolution == val)
410 return true;
412 break;
413 case media_feature_min_resolution:
414 if(features.resolution >= val)
416 return true;
418 break;
419 case media_feature_max_resolution:
420 if(features.resolution <= val)
422 return true;
424 break;
425 default:
426 return false;
429 return false;