-#include "html.h"\r
-#include "style.h"\r
-#include <functional>\r
-#include <algorithm>\r
-#ifndef WINCE\r
-#include <locale>\r
-#endif\r
-\r
-litehtml::string_map litehtml::style::m_valid_values =\r
-{\r
- { _t("white-space"), white_space_strings }\r
-};\r
-\r
-litehtml::style::style()\r
-{\r
-}\r
-\r
-litehtml::style::style( const style& val )\r
-{\r
- m_properties = val.m_properties;\r
-}\r
-\r
-litehtml::style::~style()\r
-{\r
-\r
-}\r
-\r
-void litehtml::style::parse( const tchar_t* txt, const tchar_t* baseurl )\r
-{\r
- std::vector<tstring> properties;\r
- split_string(txt, properties, _t(";"));\r
-\r
- for(std::vector<tstring>::const_iterator i = properties.begin(); i != properties.end(); i++)\r
- {\r
- parse_property(*i, baseurl);\r
- }\r
-}\r
-\r
-void litehtml::style::parse_property( const tstring& txt, const tchar_t* baseurl )\r
-{\r
- tstring::size_type pos = txt.find_first_of(_t(":"));\r
- if(pos != tstring::npos)\r
- {\r
- tstring name = txt.substr(0, pos);\r
- tstring val = txt.substr(pos + 1);\r
-\r
- trim(name);\r
- trim(val);\r
-\r
- lcase(name);\r
-\r
- if(!name.empty() && !val.empty())\r
- {\r
- string_vector vals;\r
- split_string(val, vals, _t("!"));\r
- if(vals.size() == 1)\r
- {\r
- add_property(name.c_str(), val.c_str(), baseurl, false);\r
- } else if(vals.size() > 1)\r
- {\r
- trim(vals[0]);\r
- lcase(vals[1]);\r
- if(vals[1] == _t("important"))\r
- {\r
- add_property(name.c_str(), vals[0].c_str(), baseurl, true);\r
- } else\r
- {\r
- add_property(name.c_str(), vals[0].c_str(), baseurl, false);\r
- }\r
- }\r
- }\r
- }\r
-}\r
-\r
-void litehtml::style::combine( const litehtml::style& src )\r
-{\r
- for(props_map::const_iterator i = src.m_properties.begin(); i != src.m_properties.end(); i++)\r
- {\r
- add_parsed_property(i->first.c_str(), i->second.m_value.c_str(), i->second.m_important);\r
- }\r
-}\r
-\r
-void litehtml::style::add_property( const tchar_t* name, const tchar_t* val, const tchar_t* baseurl, bool important )\r
-{\r
- if(!name || !val)\r
- {\r
- return;\r
- }\r
-\r
- // Add baseurl for background image \r
- if( !t_strcmp(name, _t("background-image")))\r
- {\r
- add_parsed_property(name, val, important);\r
- if(baseurl)\r
- {\r
- add_parsed_property(_t("background-image-baseurl"), baseurl, important);\r
- }\r
- } else\r
-\r
- // Parse border spacing properties \r
- if( !t_strcmp(name, _t("border-spacing")))\r
- {\r
- string_vector tokens;\r
- split_string(val, tokens, _t(" "));\r
- if(tokens.size() == 1)\r
- {\r
- add_property(_t("-litehtml-border-spacing-x"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("-litehtml-border-spacing-y"), tokens[0].c_str(), baseurl, important);\r
- } else if(tokens.size() == 2)\r
- {\r
- add_property(_t("-litehtml-border-spacing-x"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("-litehtml-border-spacing-y"), tokens[1].c_str(), baseurl, important);\r
- }\r
- } else\r
-\r
- // Parse borders shorthand properties \r
-\r
- if( !t_strcmp(name, _t("border")))\r
- {\r
- string_vector tokens;\r
- split_string(val, tokens, _t(" "), _t(""), _t("("));\r
- int idx;\r
- tstring str;\r
- for(string_vector::const_iterator tok = tokens.begin(); tok != tokens.end(); tok++)\r
- {\r
- idx = value_index(tok->c_str(), border_style_strings, -1);\r
- if(idx >= 0)\r
- {\r
- add_property(_t("border-left-style"), tok->c_str(), baseurl, important);\r
- add_property(_t("border-right-style"), tok->c_str(), baseurl, important);\r
- add_property(_t("border-top-style"), tok->c_str(), baseurl, important);\r
- add_property(_t("border-bottom-style"), tok->c_str(), baseurl, important);\r
- } else\r
- {\r
- if(web_color::is_color(tok->c_str()))\r
- {\r
- add_property(_t("border-left-color"), tok->c_str(), baseurl, important);\r
- add_property(_t("border-right-color"), tok->c_str(), baseurl, important);\r
- add_property(_t("border-top-color"), tok->c_str(), baseurl, important);\r
- add_property(_t("border-bottom-color"), tok->c_str(), baseurl, important);\r
- } else\r
- {\r
- add_property(_t("border-left-width"), tok->c_str(), baseurl, important);\r
- add_property(_t("border-right-width"), tok->c_str(), baseurl, important);\r
- add_property(_t("border-top-width"), tok->c_str(), baseurl, important);\r
- add_property(_t("border-bottom-width"), tok->c_str(), baseurl, important);\r
- }\r
- }\r
- }\r
- } else if( !t_strcmp(name, _t("border-left")) ||\r
- !t_strcmp(name, _t("border-right")) ||\r
- !t_strcmp(name, _t("border-top")) ||\r
- !t_strcmp(name, _t("border-bottom")) )\r
- {\r
- string_vector tokens;\r
- split_string(val, tokens, _t(" "), _t(""), _t("("));\r
- int idx;\r
- tstring str;\r
- for(string_vector::const_iterator tok = tokens.begin(); tok != tokens.end(); tok++)\r
- {\r
- idx = value_index(tok->c_str(), border_style_strings, -1);\r
- if(idx >= 0)\r
- {\r
- str = name;\r
- str += _t("-style");\r
- add_property(str.c_str(), tok->c_str(), baseurl, important);\r
- } else\r
- {\r
- if(web_color::is_color(tok->c_str()))\r
- {\r
- str = name;\r
- str += _t("-color");\r
- add_property(str.c_str(), tok->c_str(), baseurl, important);\r
- } else\r
- {\r
- str = name;\r
- str += _t("-width");\r
- add_property(str.c_str(), tok->c_str(), baseurl, important);\r
- }\r
- }\r
- }\r
- } else \r
-\r
- // Parse border radius shorthand properties \r
- if(!t_strcmp(name, _t("border-bottom-left-radius")))\r
- {\r
- string_vector tokens;\r
- split_string(val, tokens, _t(" "));\r
- if(tokens.size() >= 2)\r
- {\r
- add_property(_t("border-bottom-left-radius-x"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-left-radius-y"), tokens[1].c_str(), baseurl, important);\r
- } else if(tokens.size() == 1)\r
- {\r
- add_property(_t("border-bottom-left-radius-x"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-left-radius-y"), tokens[0].c_str(), baseurl, important);\r
- }\r
-\r
- } else if(!t_strcmp(name, _t("border-bottom-right-radius")))\r
- {\r
- string_vector tokens;\r
- split_string(val, tokens, _t(" "));\r
- if(tokens.size() >= 2)\r
- {\r
- add_property(_t("border-bottom-right-radius-x"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-right-radius-y"), tokens[1].c_str(), baseurl, important);\r
- } else if(tokens.size() == 1)\r
- {\r
- add_property(_t("border-bottom-right-radius-x"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-right-radius-y"), tokens[0].c_str(), baseurl, important);\r
- }\r
-\r
- } else if(!t_strcmp(name, _t("border-top-right-radius")))\r
- {\r
- string_vector tokens;\r
- split_string(val, tokens, _t(" "));\r
- if(tokens.size() >= 2)\r
- {\r
- add_property(_t("border-top-right-radius-x"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-top-right-radius-y"), tokens[1].c_str(), baseurl, important);\r
- } else if(tokens.size() == 1)\r
- {\r
- add_property(_t("border-top-right-radius-x"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-top-right-radius-y"), tokens[0].c_str(), baseurl, important);\r
- }\r
-\r
- } else if(!t_strcmp(name, _t("border-top-left-radius")))\r
- {\r
- string_vector tokens;\r
- split_string(val, tokens, _t(" "));\r
- if(tokens.size() >= 2)\r
- {\r
- add_property(_t("border-top-left-radius-x"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-top-left-radius-y"), tokens[1].c_str(), baseurl, important);\r
- } else if(tokens.size() == 1)\r
- {\r
- add_property(_t("border-top-left-radius-x"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-top-left-radius-y"), tokens[0].c_str(), baseurl, important);\r
- }\r
-\r
- } else \r
-\r
- // Parse border-radius shorthand properties \r
- if(!t_strcmp(name, _t("border-radius")))\r
- {\r
- string_vector tokens;\r
- split_string(val, tokens, _t("/"));\r
- if(tokens.size() == 1)\r
- {\r
- add_property(_t("border-radius-x"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-radius-y"), tokens[0].c_str(), baseurl, important);\r
- } else if(tokens.size() >= 2)\r
- {\r
- add_property(_t("border-radius-x"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-radius-y"), tokens[1].c_str(), baseurl, important);\r
- }\r
- } else if(!t_strcmp(name, _t("border-radius-x")))\r
- {\r
- string_vector tokens;\r
- split_string(val, tokens, _t(" "));\r
- if(tokens.size() == 1)\r
- {\r
- add_property(_t("border-top-left-radius-x"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-top-right-radius-x"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-right-radius-x"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-left-radius-x"), tokens[0].c_str(), baseurl, important);\r
- } else if(tokens.size() == 2)\r
- {\r
- add_property(_t("border-top-left-radius-x"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-top-right-radius-x"), tokens[1].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-right-radius-x"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-left-radius-x"), tokens[1].c_str(), baseurl, important);\r
- } else if(tokens.size() == 3)\r
- {\r
- add_property(_t("border-top-left-radius-x"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-top-right-radius-x"), tokens[1].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-right-radius-x"), tokens[2].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-left-radius-x"), tokens[1].c_str(), baseurl, important);\r
- } else if(tokens.size() == 4)\r
- {\r
- add_property(_t("border-top-left-radius-x"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-top-right-radius-x"), tokens[1].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-right-radius-x"), tokens[2].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-left-radius-x"), tokens[3].c_str(), baseurl, important);\r
- }\r
- } else if(!t_strcmp(name, _t("border-radius-y")))\r
- {\r
- string_vector tokens;\r
- split_string(val, tokens, _t(" "));\r
- if(tokens.size() == 1)\r
- {\r
- add_property(_t("border-top-left-radius-y"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-top-right-radius-y"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-right-radius-y"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-left-radius-y"), tokens[0].c_str(), baseurl, important);\r
- } else if(tokens.size() == 2)\r
- {\r
- add_property(_t("border-top-left-radius-y"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-top-right-radius-y"), tokens[1].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-right-radius-y"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-left-radius-y"), tokens[1].c_str(), baseurl, important);\r
- } else if(tokens.size() == 3)\r
- {\r
- add_property(_t("border-top-left-radius-y"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-top-right-radius-y"), tokens[1].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-right-radius-y"), tokens[2].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-left-radius-y"), tokens[1].c_str(), baseurl, important);\r
- } else if(tokens.size() == 4)\r
- {\r
- add_property(_t("border-top-left-radius-y"), tokens[0].c_str(), baseurl, important);\r
- add_property(_t("border-top-right-radius-y"), tokens[1].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-right-radius-y"), tokens[2].c_str(), baseurl, important);\r
- add_property(_t("border-bottom-left-radius-y"), tokens[3].c_str(), baseurl, important);\r
- }\r
- }\r
- \r
-\r
- // Parse list-style shorthand properties \r
- if(!t_strcmp(name, _t("list-style")))\r
- {\r
- add_parsed_property(_t("list-style-type"), _t("disc"), important);\r
- add_parsed_property(_t("list-style-position"), _t("outside"), important);\r
- add_parsed_property(_t("list-style-image"), _t(""), important);\r
- add_parsed_property(_t("list-style-image-baseurl"), _t(""), important);\r
-\r
- string_vector tokens;\r
- split_string(val, tokens, _t(" "), _t(""), _t("("));\r
- for(string_vector::iterator tok = tokens.begin(); tok != tokens.end(); tok++)\r
- {\r
- int idx = value_index(tok->c_str(), list_style_type_strings, -1);\r
- if(idx >= 0)\r
- {\r
- add_parsed_property(_t("list-style-type"), *tok, important);\r
- } else\r
- {\r
- idx = value_index(tok->c_str(), list_style_position_strings, -1);\r
- if(idx >= 0)\r
- {\r
- add_parsed_property(_t("list-style-position"), *tok, important);\r
- } else if(!t_strncmp(val, _t("url"), 3))\r
- {\r
- add_parsed_property(_t("list-style-image"), *tok, important);\r
- if(baseurl)\r
- {\r
- add_parsed_property(_t("list-style-image-baseurl"), baseurl, important);\r
- }\r
- }\r
- }\r
- }\r
- } else \r
-\r
- // Add baseurl for background image \r
- if( !t_strcmp(name, _t("list-style-image")))\r
- {\r
- add_parsed_property(name, val, important);\r
- if(baseurl)\r
- {\r
- add_parsed_property(_t("list-style-image-baseurl"), baseurl, important);\r
- }\r
- } else\r
- \r
- // Parse background shorthand properties \r
- if(!t_strcmp(name, _t("background")))\r
- {\r
- parse_short_background(val, baseurl, important);\r
-\r
- } else \r
- \r
- // Parse margin and padding shorthand properties \r
- if(!t_strcmp(name, _t("margin")) || !t_strcmp(name, _t("padding")))\r
- {\r
- string_vector tokens;\r
- split_string(val, tokens, _t(" "));\r
- if(tokens.size() >= 4)\r
- {\r
- add_parsed_property(tstring(name) + _t("-top"), tokens[0], important);\r
- add_parsed_property(tstring(name) + _t("-right"), tokens[1], important);\r
- add_parsed_property(tstring(name) + _t("-bottom"), tokens[2], important);\r
- add_parsed_property(tstring(name) + _t("-left"), tokens[3], important);\r
- } else if(tokens.size() == 3)\r
- {\r
- add_parsed_property(tstring(name) + _t("-top"), tokens[0], important);\r
- add_parsed_property(tstring(name) + _t("-right"), tokens[1], important);\r
- add_parsed_property(tstring(name) + _t("-left"), tokens[1], important);\r
- add_parsed_property(tstring(name) + _t("-bottom"), tokens[2], important);\r
- } else if(tokens.size() == 2)\r
- {\r
- add_parsed_property(tstring(name) + _t("-top"), tokens[0], important);\r
- add_parsed_property(tstring(name) + _t("-bottom"), tokens[0], important);\r
- add_parsed_property(tstring(name) + _t("-right"), tokens[1], important);\r
- add_parsed_property(tstring(name) + _t("-left"), tokens[1], important);\r
- } else if(tokens.size() == 1)\r
- {\r
- add_parsed_property(tstring(name) + _t("-top"), tokens[0], important);\r
- add_parsed_property(tstring(name) + _t("-bottom"), tokens[0], important);\r
- add_parsed_property(tstring(name) + _t("-right"), tokens[0], important);\r
- add_parsed_property(tstring(name) + _t("-left"), tokens[0], important);\r
- }\r
- } else \r
- \r
- \r
- // Parse border-* shorthand properties \r
- if( !t_strcmp(name, _t("border-left")) || \r
- !t_strcmp(name, _t("border-right")) ||\r
- !t_strcmp(name, _t("border-top")) || \r
- !t_strcmp(name, _t("border-bottom")))\r
- {\r
- parse_short_border(name, val, important);\r
- } else \r
- \r
- // Parse border-width/style/color shorthand properties \r
- if( !t_strcmp(name, _t("border-width")) ||\r
- !t_strcmp(name, _t("border-style")) ||\r
- !t_strcmp(name, _t("border-color")) )\r
- {\r
- string_vector nametokens;\r
- split_string(name, nametokens, _t("-"));\r
-\r
- string_vector tokens;\r
- split_string(val, tokens, _t(" "));\r
- if(tokens.size() >= 4)\r
- {\r
- add_parsed_property(nametokens[0] + _t("-top-") + nametokens[1], tokens[0], important);\r
- add_parsed_property(nametokens[0] + _t("-right-") + nametokens[1], tokens[1], important);\r
- add_parsed_property(nametokens[0] + _t("-bottom-") + nametokens[1], tokens[2], important);\r
- add_parsed_property(nametokens[0] + _t("-left-") + nametokens[1], tokens[3], important);\r
- } else if(tokens.size() == 3)\r
- {\r
- add_parsed_property(nametokens[0] + _t("-top-") + nametokens[1], tokens[0], important);\r
- add_parsed_property(nametokens[0] + _t("-right-") + nametokens[1], tokens[1], important);\r
- add_parsed_property(nametokens[0] + _t("-left-") + nametokens[1], tokens[1], important);\r
- add_parsed_property(nametokens[0] + _t("-bottom-") + nametokens[1], tokens[2], important);\r
- } else if(tokens.size() == 2)\r
- {\r
- add_parsed_property(nametokens[0] + _t("-top-") + nametokens[1], tokens[0], important);\r
- add_parsed_property(nametokens[0] + _t("-bottom-") + nametokens[1], tokens[0], important);\r
- add_parsed_property(nametokens[0] + _t("-right-") + nametokens[1], tokens[1], important);\r
- add_parsed_property(nametokens[0] + _t("-left-") + nametokens[1], tokens[1], important);\r
- } else if(tokens.size() == 1)\r
- {\r
- add_parsed_property(nametokens[0] + _t("-top-") + nametokens[1], tokens[0], important);\r
- add_parsed_property(nametokens[0] + _t("-bottom-") + nametokens[1], tokens[0], important);\r
- add_parsed_property(nametokens[0] + _t("-right-") + nametokens[1], tokens[0], important);\r
- add_parsed_property(nametokens[0] + _t("-left-") + nametokens[1], tokens[0], important);\r
- }\r
- } else \r
- \r
- // Parse font shorthand properties \r
- if(!t_strcmp(name, _t("font")))\r
- {\r
- parse_short_font(val, important);\r
- } else \r
- {\r
- add_parsed_property(name, val, important);\r
- }\r
-}\r
-\r
-void litehtml::style::parse_short_border( const tstring& prefix, const tstring& val, bool important )\r
-{\r
- string_vector tokens;\r
- split_string(val, tokens, _t(" "), _t(""), _t("("));\r
- if(tokens.size() >= 3)\r
- {\r
- add_parsed_property(prefix + _t("-width"), tokens[0], important);\r
- add_parsed_property(prefix + _t("-style"), tokens[1], important);\r
- add_parsed_property(prefix + _t("-color"), tokens[2], important);\r
- } else if(tokens.size() == 2)\r
- {\r
- if(iswdigit(tokens[0][0]) || value_index(val.c_str(), border_width_strings) >= 0)\r
- {\r
- add_parsed_property(prefix + _t("-width"), tokens[0], important);\r
- add_parsed_property(prefix + _t("-style"), tokens[1], important);\r
- } else\r
- {\r
- add_parsed_property(prefix + _t("-style"), tokens[0], important);\r
- add_parsed_property(prefix + _t("-color"), tokens[1], important);\r
- }\r
- }\r
-}\r
-\r
-void litehtml::style::parse_short_background( const tstring& val, const tchar_t* baseurl, bool important )\r
-{\r
- add_parsed_property(_t("background-color"), _t("transparent"), important);\r
- add_parsed_property(_t("background-image"), _t(""), important);\r
- add_parsed_property(_t("background-image-baseurl"), _t(""), important);\r
- add_parsed_property(_t("background-repeat"), _t("repeat"), important);\r
- add_parsed_property(_t("background-origin"), _t("padding-box"), important);\r
- add_parsed_property(_t("background-clip"), _t("border-box"), important);\r
- add_parsed_property(_t("background-attachment"), _t("scroll"), important);\r
-\r
- if(val == _t("none"))\r
- {\r
- return;\r
- }\r
-\r
- string_vector tokens;\r
- split_string(val, tokens, _t(" "), _t(""), _t("("));\r
- bool origin_found = false;\r
- for(string_vector::iterator tok = tokens.begin(); tok != tokens.end(); tok++)\r
- {\r
- if(web_color::is_color(tok->c_str()))\r
- {\r
- add_parsed_property(_t("background-color"), *tok, important);\r
- } else if(tok->substr(0, 3) == _t("url"))\r
- {\r
- add_parsed_property(_t("background-image"), *tok, important);\r
- if(baseurl)\r
- {\r
- add_parsed_property(_t("background-image-baseurl"), baseurl, important);\r
- }\r
-\r
- } else if( value_in_list(tok->c_str(), background_repeat_strings) )\r
- {\r
- add_parsed_property(_t("background-repeat"), *tok, important);\r
- } else if( value_in_list(tok->c_str(), background_attachment_strings) )\r
- {\r
- add_parsed_property(_t("background-attachment"), *tok, important);\r
- } else if( value_in_list(tok->c_str(), background_box_strings) )\r
- {\r
- if(!origin_found)\r
- {\r
- add_parsed_property(_t("background-origin"), *tok, important);\r
- origin_found = true;\r
- } else\r
- {\r
- add_parsed_property(_t("background-clip"),*tok, important);\r
- }\r
- } else if( value_in_list(tok->c_str(), _t("left;right;top;bottom;center")) ||\r
- iswdigit((*tok)[0]) ||\r
- (*tok)[0] == _t('-') ||\r
- (*tok)[0] == _t('.') ||\r
- (*tok)[0] == _t('+'))\r
- {\r
- if(m_properties.find(_t("background-position")) != m_properties.end())\r
- {\r
- m_properties[_t("background-position")].m_value = m_properties[_t("background-position")].m_value + _t(" ") + *tok;\r
- } else\r
- {\r
- add_parsed_property(_t("background-position"), *tok, important);\r
- }\r
- }\r
- }\r
-}\r
-\r
-void litehtml::style::parse_short_font( const tstring& val, bool important )\r
-{\r
- add_parsed_property(_t("font-style"), _t("normal"), important);\r
- add_parsed_property(_t("font-variant"), _t("normal"), important);\r
- add_parsed_property(_t("font-weight"), _t("normal"), important);\r
- add_parsed_property(_t("font-size"), _t("medium"), important);\r
- add_parsed_property(_t("line-height"), _t("normal"), important);\r
-\r
- string_vector tokens;\r
- split_string(val, tokens, _t(" "), _t(""), _t("\""));\r
-\r
- int idx = 0;\r
- bool was_normal = false;\r
- bool is_family = false;\r
- tstring font_family;\r
- for(string_vector::iterator tok = tokens.begin(); tok != tokens.end(); tok++)\r
- {\r
- idx = value_index(tok->c_str(), font_style_strings);\r
- if(!is_family)\r
- {\r
- if(idx >= 0)\r
- {\r
- if(idx == 0 && !was_normal)\r
- {\r
- add_parsed_property(_t("font-weight"), *tok, important);\r
- add_parsed_property(_t("font-variant"), *tok, important);\r
- add_parsed_property(_t("font-style"), *tok, important);\r
- } else\r
- {\r
- add_parsed_property(_t("font-style"), *tok, important);\r
- }\r
- } else\r
- {\r
- if(value_in_list(tok->c_str(), font_weight_strings))\r
- {\r
- add_parsed_property(_t("font-weight"), *tok, important);\r
- } else\r
- {\r
- if(value_in_list(tok->c_str(), font_variant_strings))\r
- {\r
- add_parsed_property(_t("font-variant"), *tok, important);\r
- } else if( iswdigit((*tok)[0]) )\r
- {\r
- string_vector szlh;\r
- split_string(*tok, szlh, _t("/"));\r
-\r
- if(szlh.size() == 1)\r
- {\r
- add_parsed_property(_t("font-size"), szlh[0], important);\r
- } else if(szlh.size() >= 2)\r
- {\r
- add_parsed_property(_t("font-size"), szlh[0], important);\r
- add_parsed_property(_t("line-height"), szlh[1], important);\r
- }\r
- } else\r
- {\r
- is_family = true;\r
- font_family += *tok;\r
- }\r
- }\r
- }\r
- } else\r
- {\r
- font_family += *tok;\r
- }\r
- }\r
- add_parsed_property(_t("font-family"), font_family, important);\r
-}\r
-\r
-void litehtml::style::add_parsed_property( const tstring& name, const tstring& val, bool important )\r
-{\r
- bool is_valid = true;\r
- string_map::iterator vals = m_valid_values.find(name);\r
- if (vals != m_valid_values.end())\r
- {\r
- if (!value_in_list(val, vals->second))\r
- {\r
- is_valid = false;\r
- }\r
- }\r
-\r
- if (is_valid)\r
- {\r
- props_map::iterator prop = m_properties.find(name);\r
- if (prop != m_properties.end())\r
- {\r
- if (!prop->second.m_important || (important && prop->second.m_important))\r
- {\r
- prop->second.m_value = val;\r
- prop->second.m_important = important;\r
- }\r
- }\r
- else\r
- {\r
- m_properties[name] = property_value(val.c_str(), important);\r
- }\r
- }\r
-}\r
-\r
-void litehtml::style::remove_property( const tstring& name, bool important )\r
-{\r
- props_map::iterator prop = m_properties.find(name);\r
- if(prop != m_properties.end())\r
- {\r
- if( !prop->second.m_important || (important && prop->second.m_important) )\r
- {\r
- m_properties.erase(prop);\r
- }\r
- }\r
-}\r
+#include "html.h"
+#include "style.h"
+#include <functional>
+#include <algorithm>
+#ifndef WINCE
+#include <locale>
+#endif
+
+litehtml::string_map litehtml::style::m_valid_values =
+{
+ { _t("white-space"), white_space_strings }
+};
+
+litehtml::style::style()
+{
+}
+
+litehtml::style::style( const style& val )
+{
+ m_properties = val.m_properties;
+}
+
+litehtml::style::~style()
+{
+
+}
+
+void litehtml::style::parse( const tchar_t* txt, const tchar_t* baseurl )
+{
+ std::vector<tstring> properties;
+ split_string(txt, properties, _t(";"));
+
+ for(std::vector<tstring>::const_iterator i = properties.begin(); i != properties.end(); i++)
+ {
+ parse_property(*i, baseurl);
+ }
+}
+
+void litehtml::style::parse_property( const tstring& txt, const tchar_t* baseurl )
+{
+ tstring::size_type pos = txt.find_first_of(_t(":"));
+ if(pos != tstring::npos)
+ {
+ tstring name = txt.substr(0, pos);
+ tstring val = txt.substr(pos + 1);
+
+ trim(name);
+ trim(val);
+
+ lcase(name);
+
+ if(!name.empty() && !val.empty())
+ {
+ string_vector vals;
+ split_string(val, vals, _t("!"));
+ if(vals.size() == 1)
+ {
+ add_property(name.c_str(), val.c_str(), baseurl, false);
+ } else if(vals.size() > 1)
+ {
+ trim(vals[0]);
+ lcase(vals[1]);
+ if(vals[1] == _t("important"))
+ {
+ add_property(name.c_str(), vals[0].c_str(), baseurl, true);
+ } else
+ {
+ add_property(name.c_str(), vals[0].c_str(), baseurl, false);
+ }
+ }
+ }
+ }
+}
+
+void litehtml::style::combine( const litehtml::style& src )
+{
+ for(props_map::const_iterator i = src.m_properties.begin(); i != src.m_properties.end(); i++)
+ {
+ add_parsed_property(i->first.c_str(), i->second.m_value.c_str(), i->second.m_important);
+ }
+}
+
+void litehtml::style::add_property( const tchar_t* name, const tchar_t* val, const tchar_t* baseurl, bool important )
+{
+ if(!name || !val)
+ {
+ return;
+ }
+
+ // Add baseurl for background image
+ if( !t_strcmp(name, _t("background-image")))
+ {
+ add_parsed_property(name, val, important);
+ if(baseurl)
+ {
+ add_parsed_property(_t("background-image-baseurl"), baseurl, important);
+ }
+ } else
+
+ // Parse border spacing properties
+ if( !t_strcmp(name, _t("border-spacing")))
+ {
+ string_vector tokens;
+ split_string(val, tokens, _t(" "));
+ if(tokens.size() == 1)
+ {
+ add_property(_t("-litehtml-border-spacing-x"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("-litehtml-border-spacing-y"), tokens[0].c_str(), baseurl, important);
+ } else if(tokens.size() == 2)
+ {
+ add_property(_t("-litehtml-border-spacing-x"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("-litehtml-border-spacing-y"), tokens[1].c_str(), baseurl, important);
+ }
+ } else
+
+ // Parse borders shorthand properties
+
+ if( !t_strcmp(name, _t("border")))
+ {
+ string_vector tokens;
+ split_string(val, tokens, _t(" "), _t(""), _t("("));
+ int idx;
+ tstring str;
+ for(string_vector::const_iterator tok = tokens.begin(); tok != tokens.end(); tok++)
+ {
+ idx = value_index(tok->c_str(), border_style_strings, -1);
+ if(idx >= 0)
+ {
+ add_property(_t("border-left-style"), tok->c_str(), baseurl, important);
+ add_property(_t("border-right-style"), tok->c_str(), baseurl, important);
+ add_property(_t("border-top-style"), tok->c_str(), baseurl, important);
+ add_property(_t("border-bottom-style"), tok->c_str(), baseurl, important);
+ } else
+ {
+ if (t_isdigit((*tok)[0]) || (*tok)[0] == _t('.') ||
+ value_in_list((*tok), _t("thin;medium;thick")))
+ {
+ add_property(_t("border-left-width"), tok->c_str(), baseurl, important);
+ add_property(_t("border-right-width"), tok->c_str(), baseurl, important);
+ add_property(_t("border-top-width"), tok->c_str(), baseurl, important);
+ add_property(_t("border-bottom-width"), tok->c_str(), baseurl, important);
+ }
+ else
+ {
+ add_property(_t("border-left-color"), tok->c_str(), baseurl, important);
+ add_property(_t("border-right-color"), tok->c_str(), baseurl, important);
+ add_property(_t("border-top-color"), tok->c_str(), baseurl, important);
+ add_property(_t("border-bottom-color"), tok->c_str(), baseurl, important);
+ }
+ }
+ }
+ } else if( !t_strcmp(name, _t("border-left")) ||
+ !t_strcmp(name, _t("border-right")) ||
+ !t_strcmp(name, _t("border-top")) ||
+ !t_strcmp(name, _t("border-bottom")) )
+ {
+ string_vector tokens;
+ split_string(val, tokens, _t(" "), _t(""), _t("("));
+ int idx;
+ tstring str;
+ for(string_vector::const_iterator tok = tokens.begin(); tok != tokens.end(); tok++)
+ {
+ idx = value_index(tok->c_str(), border_style_strings, -1);
+ if(idx >= 0)
+ {
+ str = name;
+ str += _t("-style");
+ add_property(str.c_str(), tok->c_str(), baseurl, important);
+ } else
+ {
+ if(web_color::is_color(tok->c_str()))
+ {
+ str = name;
+ str += _t("-color");
+ add_property(str.c_str(), tok->c_str(), baseurl, important);
+ } else
+ {
+ str = name;
+ str += _t("-width");
+ add_property(str.c_str(), tok->c_str(), baseurl, important);
+ }
+ }
+ }
+ } else
+
+ // Parse border radius shorthand properties
+ if(!t_strcmp(name, _t("border-bottom-left-radius")))
+ {
+ string_vector tokens;
+ split_string(val, tokens, _t(" "));
+ if(tokens.size() >= 2)
+ {
+ add_property(_t("border-bottom-left-radius-x"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-bottom-left-radius-y"), tokens[1].c_str(), baseurl, important);
+ } else if(tokens.size() == 1)
+ {
+ add_property(_t("border-bottom-left-radius-x"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-bottom-left-radius-y"), tokens[0].c_str(), baseurl, important);
+ }
+
+ } else if(!t_strcmp(name, _t("border-bottom-right-radius")))
+ {
+ string_vector tokens;
+ split_string(val, tokens, _t(" "));
+ if(tokens.size() >= 2)
+ {
+ add_property(_t("border-bottom-right-radius-x"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-bottom-right-radius-y"), tokens[1].c_str(), baseurl, important);
+ } else if(tokens.size() == 1)
+ {
+ add_property(_t("border-bottom-right-radius-x"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-bottom-right-radius-y"), tokens[0].c_str(), baseurl, important);
+ }
+
+ } else if(!t_strcmp(name, _t("border-top-right-radius")))
+ {
+ string_vector tokens;
+ split_string(val, tokens, _t(" "));
+ if(tokens.size() >= 2)
+ {
+ add_property(_t("border-top-right-radius-x"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-top-right-radius-y"), tokens[1].c_str(), baseurl, important);
+ } else if(tokens.size() == 1)
+ {
+ add_property(_t("border-top-right-radius-x"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-top-right-radius-y"), tokens[0].c_str(), baseurl, important);
+ }
+
+ } else if(!t_strcmp(name, _t("border-top-left-radius")))
+ {
+ string_vector tokens;
+ split_string(val, tokens, _t(" "));
+ if(tokens.size() >= 2)
+ {
+ add_property(_t("border-top-left-radius-x"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-top-left-radius-y"), tokens[1].c_str(), baseurl, important);
+ } else if(tokens.size() == 1)
+ {
+ add_property(_t("border-top-left-radius-x"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-top-left-radius-y"), tokens[0].c_str(), baseurl, important);
+ }
+
+ } else
+
+ // Parse border-radius shorthand properties
+ if(!t_strcmp(name, _t("border-radius")))
+ {
+ string_vector tokens;
+ split_string(val, tokens, _t("/"));
+ if(tokens.size() == 1)
+ {
+ add_property(_t("border-radius-x"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-radius-y"), tokens[0].c_str(), baseurl, important);
+ } else if(tokens.size() >= 2)
+ {
+ add_property(_t("border-radius-x"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-radius-y"), tokens[1].c_str(), baseurl, important);
+ }
+ } else if(!t_strcmp(name, _t("border-radius-x")))
+ {
+ string_vector tokens;
+ split_string(val, tokens, _t(" "));
+ if(tokens.size() == 1)
+ {
+ add_property(_t("border-top-left-radius-x"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-top-right-radius-x"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-bottom-right-radius-x"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-bottom-left-radius-x"), tokens[0].c_str(), baseurl, important);
+ } else if(tokens.size() == 2)
+ {
+ add_property(_t("border-top-left-radius-x"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-top-right-radius-x"), tokens[1].c_str(), baseurl, important);
+ add_property(_t("border-bottom-right-radius-x"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-bottom-left-radius-x"), tokens[1].c_str(), baseurl, important);
+ } else if(tokens.size() == 3)
+ {
+ add_property(_t("border-top-left-radius-x"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-top-right-radius-x"), tokens[1].c_str(), baseurl, important);
+ add_property(_t("border-bottom-right-radius-x"), tokens[2].c_str(), baseurl, important);
+ add_property(_t("border-bottom-left-radius-x"), tokens[1].c_str(), baseurl, important);
+ } else if(tokens.size() == 4)
+ {
+ add_property(_t("border-top-left-radius-x"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-top-right-radius-x"), tokens[1].c_str(), baseurl, important);
+ add_property(_t("border-bottom-right-radius-x"), tokens[2].c_str(), baseurl, important);
+ add_property(_t("border-bottom-left-radius-x"), tokens[3].c_str(), baseurl, important);
+ }
+ } else if(!t_strcmp(name, _t("border-radius-y")))
+ {
+ string_vector tokens;
+ split_string(val, tokens, _t(" "));
+ if(tokens.size() == 1)
+ {
+ add_property(_t("border-top-left-radius-y"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-top-right-radius-y"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-bottom-right-radius-y"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-bottom-left-radius-y"), tokens[0].c_str(), baseurl, important);
+ } else if(tokens.size() == 2)
+ {
+ add_property(_t("border-top-left-radius-y"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-top-right-radius-y"), tokens[1].c_str(), baseurl, important);
+ add_property(_t("border-bottom-right-radius-y"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-bottom-left-radius-y"), tokens[1].c_str(), baseurl, important);
+ } else if(tokens.size() == 3)
+ {
+ add_property(_t("border-top-left-radius-y"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-top-right-radius-y"), tokens[1].c_str(), baseurl, important);
+ add_property(_t("border-bottom-right-radius-y"), tokens[2].c_str(), baseurl, important);
+ add_property(_t("border-bottom-left-radius-y"), tokens[1].c_str(), baseurl, important);
+ } else if(tokens.size() == 4)
+ {
+ add_property(_t("border-top-left-radius-y"), tokens[0].c_str(), baseurl, important);
+ add_property(_t("border-top-right-radius-y"), tokens[1].c_str(), baseurl, important);
+ add_property(_t("border-bottom-right-radius-y"), tokens[2].c_str(), baseurl, important);
+ add_property(_t("border-bottom-left-radius-y"), tokens[3].c_str(), baseurl, important);
+ }
+ }
+
+
+ // Parse list-style shorthand properties
+ if(!t_strcmp(name, _t("list-style")))
+ {
+ add_parsed_property(_t("list-style-type"), _t("disc"), important);
+ add_parsed_property(_t("list-style-position"), _t("outside"), important);
+ add_parsed_property(_t("list-style-image"), _t(""), important);
+ add_parsed_property(_t("list-style-image-baseurl"), _t(""), important);
+
+ string_vector tokens;
+ split_string(val, tokens, _t(" "), _t(""), _t("("));
+ for(string_vector::iterator tok = tokens.begin(); tok != tokens.end(); tok++)
+ {
+ int idx = value_index(tok->c_str(), list_style_type_strings, -1);
+ if(idx >= 0)
+ {
+ add_parsed_property(_t("list-style-type"), *tok, important);
+ } else
+ {
+ idx = value_index(tok->c_str(), list_style_position_strings, -1);
+ if(idx >= 0)
+ {
+ add_parsed_property(_t("list-style-position"), *tok, important);
+ } else if(!t_strncmp(val, _t("url"), 3))
+ {
+ add_parsed_property(_t("list-style-image"), *tok, important);
+ if(baseurl)
+ {
+ add_parsed_property(_t("list-style-image-baseurl"), baseurl, important);
+ }
+ }
+ }
+ }
+ } else
+
+ // Add baseurl for background image
+ if( !t_strcmp(name, _t("list-style-image")))
+ {
+ add_parsed_property(name, val, important);
+ if(baseurl)
+ {
+ add_parsed_property(_t("list-style-image-baseurl"), baseurl, important);
+ }
+ } else
+
+ // Parse background shorthand properties
+ if(!t_strcmp(name, _t("background")))
+ {
+ parse_short_background(val, baseurl, important);
+
+ } else
+
+ // Parse margin and padding shorthand properties
+ if(!t_strcmp(name, _t("margin")) || !t_strcmp(name, _t("padding")))
+ {
+ string_vector tokens;
+ split_string(val, tokens, _t(" "));
+ if(tokens.size() >= 4)
+ {
+ add_parsed_property(tstring(name) + _t("-top"), tokens[0], important);
+ add_parsed_property(tstring(name) + _t("-right"), tokens[1], important);
+ add_parsed_property(tstring(name) + _t("-bottom"), tokens[2], important);
+ add_parsed_property(tstring(name) + _t("-left"), tokens[3], important);
+ } else if(tokens.size() == 3)
+ {
+ add_parsed_property(tstring(name) + _t("-top"), tokens[0], important);
+ add_parsed_property(tstring(name) + _t("-right"), tokens[1], important);
+ add_parsed_property(tstring(name) + _t("-left"), tokens[1], important);
+ add_parsed_property(tstring(name) + _t("-bottom"), tokens[2], important);
+ } else if(tokens.size() == 2)
+ {
+ add_parsed_property(tstring(name) + _t("-top"), tokens[0], important);
+ add_parsed_property(tstring(name) + _t("-bottom"), tokens[0], important);
+ add_parsed_property(tstring(name) + _t("-right"), tokens[1], important);
+ add_parsed_property(tstring(name) + _t("-left"), tokens[1], important);
+ } else if(tokens.size() == 1)
+ {
+ add_parsed_property(tstring(name) + _t("-top"), tokens[0], important);
+ add_parsed_property(tstring(name) + _t("-bottom"), tokens[0], important);
+ add_parsed_property(tstring(name) + _t("-right"), tokens[0], important);
+ add_parsed_property(tstring(name) + _t("-left"), tokens[0], important);
+ }
+ } else
+
+
+ // Parse border-* shorthand properties
+ if( !t_strcmp(name, _t("border-left")) ||
+ !t_strcmp(name, _t("border-right")) ||
+ !t_strcmp(name, _t("border-top")) ||
+ !t_strcmp(name, _t("border-bottom")))
+ {
+ parse_short_border(name, val, important);
+ } else
+
+ // Parse border-width/style/color shorthand properties
+ if( !t_strcmp(name, _t("border-width")) ||
+ !t_strcmp(name, _t("border-style")) ||
+ !t_strcmp(name, _t("border-color")) )
+ {
+ string_vector nametokens;
+ split_string(name, nametokens, _t("-"));
+
+ string_vector tokens;
+ split_string(val, tokens, _t(" "));
+ if(tokens.size() >= 4)
+ {
+ add_parsed_property(nametokens[0] + _t("-top-") + nametokens[1], tokens[0], important);
+ add_parsed_property(nametokens[0] + _t("-right-") + nametokens[1], tokens[1], important);
+ add_parsed_property(nametokens[0] + _t("-bottom-") + nametokens[1], tokens[2], important);
+ add_parsed_property(nametokens[0] + _t("-left-") + nametokens[1], tokens[3], important);
+ } else if(tokens.size() == 3)
+ {
+ add_parsed_property(nametokens[0] + _t("-top-") + nametokens[1], tokens[0], important);
+ add_parsed_property(nametokens[0] + _t("-right-") + nametokens[1], tokens[1], important);
+ add_parsed_property(nametokens[0] + _t("-left-") + nametokens[1], tokens[1], important);
+ add_parsed_property(nametokens[0] + _t("-bottom-") + nametokens[1], tokens[2], important);
+ } else if(tokens.size() == 2)
+ {
+ add_parsed_property(nametokens[0] + _t("-top-") + nametokens[1], tokens[0], important);
+ add_parsed_property(nametokens[0] + _t("-bottom-") + nametokens[1], tokens[0], important);
+ add_parsed_property(nametokens[0] + _t("-right-") + nametokens[1], tokens[1], important);
+ add_parsed_property(nametokens[0] + _t("-left-") + nametokens[1], tokens[1], important);
+ } else if(tokens.size() == 1)
+ {
+ add_parsed_property(nametokens[0] + _t("-top-") + nametokens[1], tokens[0], important);
+ add_parsed_property(nametokens[0] + _t("-bottom-") + nametokens[1], tokens[0], important);
+ add_parsed_property(nametokens[0] + _t("-right-") + nametokens[1], tokens[0], important);
+ add_parsed_property(nametokens[0] + _t("-left-") + nametokens[1], tokens[0], important);
+ }
+ } else
+
+ // Parse font shorthand properties
+ if(!t_strcmp(name, _t("font")))
+ {
+ parse_short_font(val, important);
+ } else
+ {
+ add_parsed_property(name, val, important);
+ }
+}
+
+void litehtml::style::parse_short_border( const tstring& prefix, const tstring& val, bool important )
+{
+ string_vector tokens;
+ split_string(val, tokens, _t(" "), _t(""), _t("("));
+ if(tokens.size() >= 3)
+ {
+ add_parsed_property(prefix + _t("-width"), tokens[0], important);
+ add_parsed_property(prefix + _t("-style"), tokens[1], important);
+ add_parsed_property(prefix + _t("-color"), tokens[2], important);
+ } else if(tokens.size() == 2)
+ {
+ if(iswdigit(tokens[0][0]) || value_index(val.c_str(), border_width_strings) >= 0)
+ {
+ add_parsed_property(prefix + _t("-width"), tokens[0], important);
+ add_parsed_property(prefix + _t("-style"), tokens[1], important);
+ } else
+ {
+ add_parsed_property(prefix + _t("-style"), tokens[0], important);
+ add_parsed_property(prefix + _t("-color"), tokens[1], important);
+ }
+ }
+}
+
+void litehtml::style::parse_short_background( const tstring& val, const tchar_t* baseurl, bool important )
+{
+ add_parsed_property(_t("background-color"), _t("transparent"), important);
+ add_parsed_property(_t("background-image"), _t(""), important);
+ add_parsed_property(_t("background-image-baseurl"), _t(""), important);
+ add_parsed_property(_t("background-repeat"), _t("repeat"), important);
+ add_parsed_property(_t("background-origin"), _t("padding-box"), important);
+ add_parsed_property(_t("background-clip"), _t("border-box"), important);
+ add_parsed_property(_t("background-attachment"), _t("scroll"), important);
+
+ if(val == _t("none"))
+ {
+ return;
+ }
+
+ string_vector tokens;
+ split_string(val, tokens, _t(" "), _t(""), _t("("));
+ bool origin_found = false;
+ for(string_vector::iterator tok = tokens.begin(); tok != tokens.end(); tok++)
+ {
+ if(tok->substr(0, 3) == _t("url"))
+ {
+ add_parsed_property(_t("background-image"), *tok, important);
+ if(baseurl)
+ {
+ add_parsed_property(_t("background-image-baseurl"), baseurl, important);
+ }
+
+ } else if( value_in_list(tok->c_str(), background_repeat_strings) )
+ {
+ add_parsed_property(_t("background-repeat"), *tok, important);
+ } else if( value_in_list(tok->c_str(), background_attachment_strings) )
+ {
+ add_parsed_property(_t("background-attachment"), *tok, important);
+ } else if( value_in_list(tok->c_str(), background_box_strings) )
+ {
+ if(!origin_found)
+ {
+ add_parsed_property(_t("background-origin"), *tok, important);
+ origin_found = true;
+ } else
+ {
+ add_parsed_property(_t("background-clip"),*tok, important);
+ }
+ } else if( value_in_list(tok->c_str(), _t("left;right;top;bottom;center")) ||
+ iswdigit((*tok)[0]) ||
+ (*tok)[0] == _t('-') ||
+ (*tok)[0] == _t('.') ||
+ (*tok)[0] == _t('+'))
+ {
+ if(m_properties.find(_t("background-position")) != m_properties.end())
+ {
+ m_properties[_t("background-position")].m_value = m_properties[_t("background-position")].m_value + _t(" ") + *tok;
+ } else
+ {
+ add_parsed_property(_t("background-position"), *tok, important);
+ }
+ } else if (web_color::is_color(tok->c_str()))
+ {
+ add_parsed_property(_t("background-color"), *tok, important);
+ }
+ }
+}
+
+void litehtml::style::parse_short_font( const tstring& val, bool important )
+{
+ add_parsed_property(_t("font-style"), _t("normal"), important);
+ add_parsed_property(_t("font-variant"), _t("normal"), important);
+ add_parsed_property(_t("font-weight"), _t("normal"), important);
+ add_parsed_property(_t("font-size"), _t("medium"), important);
+ add_parsed_property(_t("line-height"), _t("normal"), important);
+
+ string_vector tokens;
+ split_string(val, tokens, _t(" "), _t(""), _t("\""));
+
+ int idx = 0;
+ bool was_normal = false;
+ bool is_family = false;
+ tstring font_family;
+ for(string_vector::iterator tok = tokens.begin(); tok != tokens.end(); tok++)
+ {
+ idx = value_index(tok->c_str(), font_style_strings);
+ if(!is_family)
+ {
+ if(idx >= 0)
+ {
+ if(idx == 0 && !was_normal)
+ {
+ add_parsed_property(_t("font-weight"), *tok, important);
+ add_parsed_property(_t("font-variant"), *tok, important);
+ add_parsed_property(_t("font-style"), *tok, important);
+ } else
+ {
+ add_parsed_property(_t("font-style"), *tok, important);
+ }
+ } else
+ {
+ if(value_in_list(tok->c_str(), font_weight_strings))
+ {
+ add_parsed_property(_t("font-weight"), *tok, important);
+ } else
+ {
+ if(value_in_list(tok->c_str(), font_variant_strings))
+ {
+ add_parsed_property(_t("font-variant"), *tok, important);
+ } else if( iswdigit((*tok)[0]) )
+ {
+ string_vector szlh;
+ split_string(*tok, szlh, _t("/"));
+
+ if(szlh.size() == 1)
+ {
+ add_parsed_property(_t("font-size"), szlh[0], important);
+ } else if(szlh.size() >= 2)
+ {
+ add_parsed_property(_t("font-size"), szlh[0], important);
+ add_parsed_property(_t("line-height"), szlh[1], important);
+ }
+ } else
+ {
+ is_family = true;
+ font_family += *tok;
+ }
+ }
+ }
+ } else
+ {
+ font_family += *tok;
+ }
+ }
+ add_parsed_property(_t("font-family"), font_family, important);
+}
+
+void litehtml::style::add_parsed_property( const tstring& name, const tstring& val, bool important )
+{
+ bool is_valid = true;
+ string_map::iterator vals = m_valid_values.find(name);
+ if (vals != m_valid_values.end())
+ {
+ if (!value_in_list(val, vals->second))
+ {
+ is_valid = false;
+ }
+ }
+
+ if (is_valid)
+ {
+ props_map::iterator prop = m_properties.find(name);
+ if (prop != m_properties.end())
+ {
+ if (!prop->second.m_important || (important && prop->second.m_important))
+ {
+ prop->second.m_value = val;
+ prop->second.m_important = important;
+ }
+ }
+ else
+ {
+ m_properties[name] = property_value(val.c_str(), important);
+ }
+ }
+}
+
+void litehtml::style::remove_property( const tstring& name, bool important )
+{
+ props_map::iterator prop = m_properties.find(name);
+ if(prop != m_properties.end())
+ {
+ if( !prop->second.m_important || (important && prop->second.m_important) )
+ {
+ m_properties.erase(prop);
+ }
+ }
+}