2 #include "stylesheet.h"
7 void litehtml::css::parse_stylesheet(const tchar_t* str, const tchar_t* baseurl, const std::shared_ptr<document>& doc, const media_query_list::ptr& media)
12 tstring::size_type c_start = text.find(_t("/*"));
13 while(c_start != tstring::npos)
15 tstring::size_type c_end = text.find(_t("*/"), c_start + 2);
16 text.erase(c_start, c_end - c_start + 2);
17 c_start = text.find(_t("/*"));
20 tstring::size_type pos = text.find_first_not_of(_t(" \n\r\t"));
21 while(pos != tstring::npos)
23 while(pos != tstring::npos && text[pos] == _t('@'))
25 tstring::size_type sPos = pos;
26 pos = text.find_first_of(_t("{;"), pos);
27 if(pos != tstring::npos && text[pos] == _t('{'))
29 pos = find_close_bracket(text, pos, _t('{'), _t('}'));
31 if(pos != tstring::npos)
33 parse_atrule(text.substr(sPos, pos - sPos + 1), baseurl, doc, media);
36 parse_atrule(text.substr(sPos), baseurl, doc, media);
39 if(pos != tstring::npos)
41 pos = text.find_first_not_of(_t(" \n\r\t"), pos + 1);
45 if(pos == tstring::npos)
50 tstring::size_type style_start = text.find(_t("{"), pos);
51 tstring::size_type style_end = text.find(_t("}"), pos);
52 if(style_start != tstring::npos && style_end != tstring::npos)
54 style::ptr st = std::make_shared<style>();
55 st->add(text.substr(style_start + 1, style_end - style_start - 1).c_str(), baseurl);
57 parse_selectors(text.substr(pos, style_start - pos), st, media);
61 doc->add_media_list(media);
70 if(pos != tstring::npos)
72 pos = text.find_first_not_of(_t(" \n\r\t"), pos);
77 void litehtml::css::parse_css_url( const tstring& str, tstring& url )
80 size_t pos1 = str.find(_t('('));
81 size_t pos2 = str.find(_t(')'));
82 if(pos1 != tstring::npos && pos2 != tstring::npos)
84 url = str.substr(pos1 + 1, pos2 - pos1 - 1);
87 if(url[0] == _t('\'') || url[0] == _t('"'))
94 if(url[url.length() - 1] == _t('\'') || url[url.length() - 1] == _t('"'))
96 url.erase(url.length() - 1, 1);
102 bool litehtml::css::parse_selectors( const tstring& txt, const litehtml::style::ptr& styles, const media_query_list::ptr& media )
104 tstring selector = txt;
106 string_vector tokens;
107 split_string(selector, tokens, _t(","));
109 bool added_something = false;
111 for(string_vector::iterator tok = tokens.begin(); tok != tokens.end(); tok++)
113 css_selector::ptr selector = std::make_shared<css_selector>(media);
114 selector->m_style = styles;
116 if(selector->parse(*tok))
118 selector->calc_specificity();
119 add_selector(selector);
120 added_something = true;
124 return added_something;
127 void litehtml::css::sort_selectors()
129 std::sort(m_selectors.begin(), m_selectors.end(),
130 [](const css_selector::ptr& v1, const css_selector::ptr& v2)
132 return (*v1) < (*v2);
137 void litehtml::css::parse_atrule(const tstring& text, const tchar_t* baseurl, const std::shared_ptr<document>& doc, const media_query_list::ptr& media)
139 if(text.substr(0, 7) == _t("@import"))
143 iStr = text.substr(sPos);
144 if(iStr[iStr.length() - 1] == _t(';'))
146 iStr.erase(iStr.length() - 1);
149 string_vector tokens;
150 split_string(iStr, tokens, _t(" "), _t(""), _t("(\""));
154 parse_css_url(tokens.front(), url);
157 url = tokens.front();
159 tokens.erase(tokens.begin());
162 document_container* doc_cont = doc->container();
169 css_baseurl = baseurl;
171 doc_cont->import_css(css_text, url, css_baseurl);
172 if(!css_text.empty())
174 media_query_list::ptr new_media = media;
178 for(string_vector::iterator iter = tokens.begin(); iter != tokens.end(); iter++)
180 if(iter != tokens.begin())
182 media_str += _t(" ");
184 media_str += (*iter);
186 new_media = media_query_list::create_from_string(media_str, doc);
192 parse_stylesheet(css_text.c_str(), css_baseurl.c_str(), doc, new_media);
197 } else if(text.substr(0, 6) == _t("@media"))
199 tstring::size_type b1 = text.find_first_of(_t('{'));
200 tstring::size_type b2 = text.find_last_of(_t('}'));
201 if(b1 != tstring::npos)
203 tstring media_type = text.substr(6, b1 - 6);
205 media_query_list::ptr new_media = media_query_list::create_from_string(media_type, doc);
208 if(b2 != tstring::npos)
210 media_style = text.substr(b1 + 1, b2 - b1 - 1);
213 media_style = text.substr(b1 + 1);
216 parse_stylesheet(media_style.c_str(), baseurl, doc, new_media);