fix CID 1596595: Resource leaks, and CID 1596594: (CHECKED_RETURN)
[claws.git] / src / plugins / litehtml_viewer / litehtml / css_selector.h
1 #ifndef LH_CSS_SELECTOR_H
2 #define LH_CSS_SELECTOR_H
3
4 #include "style.h"
5 #include "media_query.h"
6
7 namespace litehtml
8 {
9         //////////////////////////////////////////////////////////////////////////
10
11         struct selector_specificity
12         {
13                 int             a;
14                 int             b;
15                 int             c;
16                 int             d;
17
18                 selector_specificity(int va = 0, int vb = 0, int vc = 0, int vd = 0)
19                 {
20                         a       = va;
21                         b       = vb;
22                         c       = vc;
23                         d       = vd;
24                 }
25
26                 void operator += (const selector_specificity& val)
27                 {
28                         a       += val.a;
29                         b       += val.b;
30                         c       += val.c;
31                         d       += val.d;
32                 }
33
34                 bool operator==(const selector_specificity& val) const
35                 {
36                         if(a == val.a && b == val.b && c == val.c && d == val.d)
37                         {
38                                 return true;
39                         }
40                         return false;
41                 }
42
43                 bool operator!=(const selector_specificity& val) const
44                 {
45                         if(a != val.a || b != val.b || c != val.c || d != val.d)
46                         {
47                                 return true;
48                         }
49                         return false;
50                 }
51
52                 bool operator > (const selector_specificity& val) const
53                 {
54                         if(a > val.a)
55                         {
56                                 return true;
57                         } else if(a < val.a)
58                         {
59                                 return false;
60                         } else
61                         {
62                                 if(b > val.b)
63                                 {
64                                         return true;
65                                 } else if(b < val.b)
66                                 {
67                                         return false;
68                                 } else
69                                 {
70                                         if(c > val.c)
71                                         {
72                                                 return true;
73                                         } else if(c < val.c)
74                                         {
75                                                 return false;
76                                         } else
77                                         {
78                                                 if(d > val.d)
79                                                 {
80                                                         return true;
81                                                 } else if(d < val.d)
82                                                 {
83                                                         return false;
84                                                 }
85                                         }
86                                 }
87                         }
88                         return false;
89                 }
90
91                 bool operator >= (const selector_specificity& val) const
92                 {
93                         if((*this) == val) return true;
94                         if((*this) > val) return true;
95                         return false;
96                 }
97
98                 bool operator <= (const selector_specificity& val) const
99                 {
100                         if((*this) > val)
101                         {
102                                 return false;
103                         }
104                         return true;
105                 }
106
107                 bool operator < (const selector_specificity& val) const
108                 {
109                         if((*this) <= val && (*this) != val)
110                         {
111                                 return true;
112                         }
113                         return false;
114                 }
115
116         };
117
118         //////////////////////////////////////////////////////////////////////////
119
120         enum attr_select_condition
121         {
122                 select_exists,
123                 select_equal,
124                 select_contain_str,
125                 select_start_str,
126                 select_end_str,
127                 select_pseudo_class,
128                 select_pseudo_element,
129         };
130
131         //////////////////////////////////////////////////////////////////////////
132
133         struct css_attribute_selector
134         {
135                 typedef std::vector<css_attribute_selector>     vector;
136
137                 tstring                                 attribute;
138                 tstring                                 val;
139                 string_vector                   class_val;
140                 attr_select_condition   condition;
141
142                 css_attribute_selector()
143                 {
144                         condition = select_exists;
145                 }
146         };
147
148         //////////////////////////////////////////////////////////////////////////
149
150         class css_element_selector
151         {
152         public:
153                 tstring                                                 m_tag;
154                 css_attribute_selector::vector  m_attrs;
155         public:
156
157                 void parse(const tstring& txt);
158         };
159
160         //////////////////////////////////////////////////////////////////////////
161
162         enum css_combinator
163         {
164                 combinator_descendant,
165                 combinator_child,
166                 combinator_adjacent_sibling,
167                 combinator_general_sibling
168         };
169
170         //////////////////////////////////////////////////////////////////////////
171
172         class css_selector
173         {
174         public:
175                 typedef std::shared_ptr<css_selector>   ptr;
176                 typedef std::vector<css_selector::ptr>  vector;
177         public:
178                 selector_specificity    m_specificity;
179                 css_element_selector    m_right;
180                 css_selector::ptr               m_left;
181                 css_combinator                  m_combinator;
182                 style::ptr                              m_style;
183                 int                                             m_order;
184                 media_query_list::ptr   m_media_query;
185         public:
186                 css_selector(media_query_list::ptr media)
187                 {
188                         m_media_query   = media;
189                         m_combinator    = combinator_descendant;
190                         m_order                 = 0;
191                 }
192
193                 ~css_selector()
194                 {
195                 }
196
197                 css_selector(const css_selector& val)
198                 {
199                         m_right                 = val.m_right;
200                         if(val.m_left)
201                         {
202                                 m_left                  = std::make_shared<css_selector>(*val.m_left);
203                         } else
204                         {
205                                 m_left = 0;
206                         }
207                         m_combinator    = val.m_combinator;
208                         m_specificity   = val.m_specificity;
209                         m_order                 = val.m_order;
210                         m_media_query   = val.m_media_query;
211                 }
212
213                 bool parse(const tstring& text);
214                 void calc_specificity();
215                 bool is_media_valid() const;
216                 void add_media_to_doc(document* doc) const;
217         };
218
219         inline bool css_selector::is_media_valid() const
220         {
221                 if(!m_media_query)
222                 {
223                         return true;
224                 }
225                 return m_media_query->is_used();
226         }
227
228
229         //////////////////////////////////////////////////////////////////////////
230
231         inline bool operator > (const css_selector& v1, const css_selector& v2)
232         {
233                 if(v1.m_specificity == v2.m_specificity)
234                 {
235                         return (v1.m_order > v2.m_order);
236                 }
237                 return (v1.m_specificity > v2.m_specificity);
238         }
239
240         inline bool operator < (const css_selector& v1, const css_selector& v2)
241         {
242                 if(v1.m_specificity == v2.m_specificity)
243                 {
244                         return (v1.m_order < v2.m_order);
245                 }
246                 return (v1.m_specificity < v2.m_specificity);
247         }
248
249         inline bool operator >(const css_selector::ptr& v1, const css_selector::ptr& v2)
250         {
251                 return (*v1 > *v2);
252         }
253
254         inline bool operator < (const css_selector::ptr& v1, const css_selector::ptr& v2)
255         {
256                 return (*v1 < *v2);
257         }
258
259         //////////////////////////////////////////////////////////////////////////
260
261         class used_selector
262         {
263         public:
264                 typedef std::unique_ptr<used_selector>  ptr;
265                 typedef std::vector<used_selector::ptr> vector;
266
267                 css_selector::ptr       m_selector;
268                 bool                            m_used;
269
270                 used_selector(const css_selector::ptr& selector, bool used)
271                 {
272                         m_used          = used;
273                         m_selector      = selector;
274                 }
275         };
276 }
277
278 #endif  // LH_CSS_SELECTOR_H