text: #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);
  		}
  	}
  }
  