1 #ifndef LH_CSS_SELECTOR_H
2 #define LH_CSS_SELECTOR_H
5 #include "media_query.h"
9 //////////////////////////////////////////////////////////////////////////
11 struct selector_specificity
18 explicit selector_specificity(int va
= 0, int vb
= 0, int vc
= 0, int vd
= 0)
26 void operator += (const selector_specificity
& val
)
34 bool operator==(const selector_specificity
& val
) const
36 if(a
== val
.a
&& b
== val
.b
&& c
== val
.c
&& d
== val
.d
)
43 bool operator!=(const selector_specificity
& val
) const
45 if(a
!= val
.a
|| b
!= val
.b
|| c
!= val
.c
|| d
!= val
.d
)
52 bool operator > (const selector_specificity
& val
) const
91 bool operator >= (const selector_specificity
& val
) const
93 if((*this) == val
) return true;
94 if((*this) > val
) return true;
98 bool operator <= (const selector_specificity
& val
) const
107 bool operator < (const selector_specificity
& val
) const
109 if((*this) <= val
&& (*this) != val
)
118 //////////////////////////////////////////////////////////////////////////
120 enum attr_select_type
132 select_pseudo_element
,
135 //////////////////////////////////////////////////////////////////////////
137 class css_element_selector
;
139 struct css_attribute_selector
141 typedef std::vector
<css_attribute_selector
> vector
;
143 attr_select_type type
;
144 string_id name
; // .name, #name, [name], :name
145 string val
; // [name=val], :lang(val)
147 std::shared_ptr
<css_element_selector
> sel
; // :not(sel)
148 int a
, b
; // :nth-child(an+b)
150 css_attribute_selector()
158 //////////////////////////////////////////////////////////////////////////
160 class css_element_selector
164 css_attribute_selector::vector m_attrs
;
167 void parse(const string
& txt
);
168 static void parse_nth_child_params(const string
& param
, int& num
, int& off
);
171 //////////////////////////////////////////////////////////////////////////
175 combinator_descendant
,
177 combinator_adjacent_sibling
,
178 combinator_general_sibling
181 //////////////////////////////////////////////////////////////////////////
186 typedef std::shared_ptr
<css_selector
> ptr
;
187 typedef std::vector
<css_selector::ptr
> vector
;
189 selector_specificity m_specificity
;
190 css_element_selector m_right
;
191 css_selector::ptr m_left
;
192 css_combinator m_combinator
;
195 media_query_list::ptr m_media_query
;
197 explicit css_selector(const media_query_list::ptr
& media
= nullptr)
199 m_media_query
= media
;
200 m_combinator
= combinator_descendant
;
204 ~css_selector() = default;
206 css_selector(const css_selector
& val
)
208 m_right
= val
.m_right
;
211 m_left
= std::make_shared
<css_selector
>(*val
.m_left
);
216 m_combinator
= val
.m_combinator
;
217 m_specificity
= val
.m_specificity
;
218 m_order
= val
.m_order
;
219 m_media_query
= val
.m_media_query
;
222 bool parse(const string
& text
);
223 void calc_specificity();
224 bool is_media_valid() const;
225 void add_media_to_doc(document
* doc
) const;
228 inline bool css_selector::is_media_valid() const
234 return m_media_query
->is_used();
238 //////////////////////////////////////////////////////////////////////////
240 inline bool operator > (const css_selector
& v1
, const css_selector
& v2
)
242 if(v1
.m_specificity
== v2
.m_specificity
)
244 return (v1
.m_order
> v2
.m_order
);
246 return (v1
.m_specificity
> v2
.m_specificity
);
249 inline bool operator < (const css_selector
& v1
, const css_selector
& v2
)
251 if(v1
.m_specificity
== v2
.m_specificity
)
253 return (v1
.m_order
< v2
.m_order
);
255 return (v1
.m_specificity
< v2
.m_specificity
);
258 inline bool operator > (const css_selector::ptr
& v1
, const css_selector::ptr
& v2
)
263 inline bool operator < (const css_selector::ptr
& v1
, const css_selector::ptr
& v2
)
268 //////////////////////////////////////////////////////////////////////////
273 typedef std::unique_ptr
<used_selector
> ptr
;
274 typedef std::vector
<used_selector::ptr
> vector
;
276 css_selector::ptr m_selector
;
279 used_selector(const css_selector::ptr
& selector
, bool used
)
282 m_selector
= selector
;
285 used_selector(const used_selector
& val
)
288 m_selector
= val
.m_selector
;
291 used_selector
& operator=(const used_selector
& val
)
294 m_selector
= val
.m_selector
;
300 #endif // LH_CSS_SELECTOR_H