void CL_CSSParserBorderSpacing::parse(CL_CSSBoxProperties &properties, const CL_String &name, const std::vector<CL_CSSToken> &tokens, std::map<CL_String, CL_CSSBoxProperty *> *out_change_set) { CL_CSSBoxLength length1, length2; size_t pos = 0; CL_CSSToken token = next_token(pos, tokens); if (token.type == CL_CSSToken::type_ident && equals(token.value, "inherit") && pos == tokens.size()) { properties.border_spacing.type = CL_CSSBoxBorderSpacing::type_inherit; if (out_change_set) { (*out_change_set)["border-spacing"] = &properties.border_spacing; } return; } else if (is_length(token)) { if (!parse_length(token, length1)) { debug_parse_error(name, tokens); return; } } else { debug_parse_error(name, tokens); return; } if (pos != tokens.size()) { token = next_token(pos, tokens); if (is_length(token) && pos == tokens.size()) { if (parse_length(token, length2)) { properties.border_spacing.type = CL_CSSBoxBorderSpacing::type_two_lengths; properties.border_spacing.length1 = length1; properties.border_spacing.length2 = length2; } } } else { properties.border_spacing.type = CL_CSSBoxBorderSpacing::type_one_length; properties.border_spacing.length1 = length1; } if (out_change_set) { (*out_change_set)["border-spacing"] = &properties.border_spacing; } }
void CL_CSSParserTextDecoration::parse(CL_CSSBoxProperties &properties, const CL_String &name, const std::vector<CL_CSSToken> &tokens, std::map<CL_String, CL_CSSBoxProperty *> *out_change_set) { size_t pos = 0; CL_CSSToken token = next_token(pos, tokens); if (token.type == CL_CSSToken::type_ident && pos == tokens.size()) { if (equals(token.value, "none")) { properties.text_decoration.type = CL_CSSBoxTextDecoration::type_none; } else if (equals(token.value, "inherit")) { properties.text_decoration.type = CL_CSSBoxTextDecoration::type_inherit; } else { int underline = 0; int overline = 0; int line_through = 0; int blink = 0; do { if (token.type == CL_CSSToken::type_ident) { if (equals(token.value, "underline")) underline++; else if (equals(token.value, "overline")) overline++; else if (equals(token.value, "line-through")) line_through++; else if (equals(token.value, "blink")) blink++; } else { debug_parse_error(name, tokens); return; } token = next_token(pos, tokens); } while (token.type != CL_CSSToken::type_null); if (underline < 2 && overline < 2 && line_through < 2 && blink < 2) { properties.text_decoration.type = CL_CSSBoxTextDecoration::type_values; properties.text_decoration.underline = (underline == 1); properties.text_decoration.overline = (overline == 1); properties.text_decoration.line_through = (line_through == 1); properties.text_decoration.blink = (blink == 1); } } } if (out_change_set) { (*out_change_set)["text-decoration"] = &properties.text_decoration; } }
void CSSParserBorder::parse(const std::string &name, const std::vector<CSSToken> &tokens, std::vector<std::unique_ptr<CSSPropertyValue> > &inout_values) { CSSValueBorderWidth border_width; CSSValueBorderStyle border_style; CSSValueBorderColor border_color; bool width_specified = false; bool style_specified = false; bool color_specified = false; size_t pos = 0; while (pos != tokens.size()) { Colorf color; if (!color_specified && parse_color(tokens, pos, color)) { border_color.type = CSSValueBorderColor::type_color; border_color.color = color; color_specified = true; } else { CSSToken token = next_token(pos, tokens); if (token.type == CSSToken::type_ident) { if (equals(token.value, "inherit") && tokens.size() == 1) { border_width.type = CSSValueBorderWidth::type_inherit; border_style.type = CSSValueBorderStyle::type_inherit; border_color.type = CSSValueBorderColor::type_inherit; inout_values.push_back(std::unique_ptr<CSSValueBorderWidth>(new CSSValueBorderWidth(CSSValueBorderWidth::left_value, border_width))); inout_values.push_back(std::unique_ptr<CSSValueBorderWidth>(new CSSValueBorderWidth(CSSValueBorderWidth::right_value, border_width))); inout_values.push_back(std::unique_ptr<CSSValueBorderWidth>(new CSSValueBorderWidth(CSSValueBorderWidth::top_value, border_width))); inout_values.push_back(std::unique_ptr<CSSValueBorderWidth>(new CSSValueBorderWidth(CSSValueBorderWidth::bottom_value, border_width))); inout_values.push_back(std::unique_ptr<CSSValueBorderStyle>(new CSSValueBorderStyle(CSSValueBorderStyle::left_value, border_style))); inout_values.push_back(std::unique_ptr<CSSValueBorderStyle>(new CSSValueBorderStyle(CSSValueBorderStyle::right_value, border_style))); inout_values.push_back(std::unique_ptr<CSSValueBorderStyle>(new CSSValueBorderStyle(CSSValueBorderStyle::top_value, border_style))); inout_values.push_back(std::unique_ptr<CSSValueBorderStyle>(new CSSValueBorderStyle(CSSValueBorderStyle::bottom_value, border_style))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::left_value, border_color))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::right_value, border_color))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::top_value, border_color))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::bottom_value, border_color))); return; } else if (!width_specified && equals(token.value, "thin")) { border_width.type = CSSValueBorderWidth::type_thin; width_specified = true; } else if (!width_specified && equals(token.value, "medium")) { border_width.type = CSSValueBorderWidth::type_medium; width_specified = true; } else if (!width_specified && equals(token.value, "thick")) { border_width.type = CSSValueBorderWidth::type_thick; width_specified = true; } else if (!style_specified && equals(token.value, "none")) { border_style.type = CSSValueBorderStyle::type_none; style_specified = true; } else if (!style_specified && equals(token.value, "hidden")) { border_style.type = CSSValueBorderStyle::type_hidden; style_specified = true; } else if (!style_specified && equals(token.value, "dotted")) { border_style.type = CSSValueBorderStyle::type_dotted; style_specified = true; } else if (!style_specified && equals(token.value, "dashed")) { border_style.type = CSSValueBorderStyle::type_dashed; style_specified = true; } else if (!style_specified && equals(token.value, "solid")) { border_style.type = CSSValueBorderStyle::type_solid; style_specified = true; } else if (!style_specified && equals(token.value, "double")) { border_style.type = CSSValueBorderStyle::type_double; style_specified = true; } else if (!style_specified && equals(token.value, "groove")) { border_style.type = CSSValueBorderStyle::type_groove; style_specified = true; } else if (!style_specified && equals(token.value, "ridge")) { border_style.type = CSSValueBorderStyle::type_ridge; style_specified = true; } else if (!style_specified && equals(token.value, "inset")) { border_style.type = CSSValueBorderStyle::type_inset; style_specified = true; } else if (!style_specified && equals(token.value, "outset")) { border_style.type = CSSValueBorderStyle::type_outset; style_specified = true; } else { debug_parse_error(name, tokens); return; } } else if (is_length(token)) { CSSLength length; if (!width_specified && parse_length(token, length)) { border_width.type = CSSValueBorderWidth::type_length; border_width.length = length; width_specified = true; } else { debug_parse_error(name, tokens); return; } } else { debug_parse_error(name, tokens); return; } } } inout_values.push_back(std::unique_ptr<CSSValueBorderWidth>(new CSSValueBorderWidth(CSSValueBorderWidth::left_value, border_width))); inout_values.push_back(std::unique_ptr<CSSValueBorderWidth>(new CSSValueBorderWidth(CSSValueBorderWidth::right_value, border_width))); inout_values.push_back(std::unique_ptr<CSSValueBorderWidth>(new CSSValueBorderWidth(CSSValueBorderWidth::top_value, border_width))); inout_values.push_back(std::unique_ptr<CSSValueBorderWidth>(new CSSValueBorderWidth(CSSValueBorderWidth::bottom_value, border_width))); inout_values.push_back(std::unique_ptr<CSSValueBorderStyle>(new CSSValueBorderStyle(CSSValueBorderStyle::left_value, border_style))); inout_values.push_back(std::unique_ptr<CSSValueBorderStyle>(new CSSValueBorderStyle(CSSValueBorderStyle::right_value, border_style))); inout_values.push_back(std::unique_ptr<CSSValueBorderStyle>(new CSSValueBorderStyle(CSSValueBorderStyle::top_value, border_style))); inout_values.push_back(std::unique_ptr<CSSValueBorderStyle>(new CSSValueBorderStyle(CSSValueBorderStyle::bottom_value, border_style))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::left_value, border_color))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::right_value, border_color))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::top_value, border_color))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::bottom_value, border_color))); }
void CL_CSSParserPadding::parse(CL_CSSBoxProperties &properties, const CL_String &name, const std::vector<CL_CSSToken> &tokens, std::map<CL_String, CL_CSSBoxProperty *> *out_change_set) { CL_CSSBoxPaddingWidth padding_widths[4]; int count; size_t pos = 0; for (count = 0; count < 4; count++) { CL_CSSToken token = next_token(pos, tokens); if (token.type == CL_CSSToken::type_ident && equals(token.value, "inherit") && count == 0 && pos == tokens.size()) { properties.padding_width_left.type = CL_CSSBoxPaddingWidth::type_inherit; properties.padding_width_top.type = CL_CSSBoxPaddingWidth::type_inherit; properties.padding_width_right.type = CL_CSSBoxPaddingWidth::type_inherit; properties.padding_width_bottom.type = CL_CSSBoxPaddingWidth::type_inherit; return; } else if (is_length(token)) { CL_CSSBoxLength length; if (parse_length(token, length)) { padding_widths[count].type = CL_CSSBoxPaddingWidth::type_length; padding_widths[count].length = length; } else { debug_parse_error(name, tokens); return; } } else if (token.type == CL_CSSToken::type_percentage) { padding_widths[count].type = CL_CSSBoxPaddingWidth::type_percentage; padding_widths[count].percentage = CL_StringHelp::text_to_float(token.value); } else if (token.type == CL_CSSToken::type_delim && token.value == "-") { token = next_token(pos, tokens); if (is_length(token)) { CL_CSSBoxLength length; if (parse_length(token, length)) { length.value = -length.value; padding_widths[count].type = CL_CSSBoxPaddingWidth::type_length; padding_widths[count].length = length; } else { debug_parse_error(name, tokens); return; } } else if (token.type == CL_CSSToken::type_percentage) { padding_widths[count].type = CL_CSSBoxPaddingWidth::type_percentage; padding_widths[count].percentage = -CL_StringHelp::text_to_float(token.value); } else { debug_parse_error(name, tokens); return; } } else if (token.type == CL_CSSToken::type_null) { break; } else { debug_parse_error(name, tokens); return; } } if (pos == tokens.size()) { switch (count) { case 1: properties.padding_width_left = padding_widths[0]; properties.padding_width_top = padding_widths[0]; properties.padding_width_right = padding_widths[0]; properties.padding_width_bottom = padding_widths[0]; break; case 2: properties.padding_width_top = padding_widths[0]; properties.padding_width_bottom = padding_widths[0]; properties.padding_width_left = padding_widths[1]; properties.padding_width_right = padding_widths[1]; break; case 3: properties.padding_width_top = padding_widths[0]; properties.padding_width_left = padding_widths[1]; properties.padding_width_right = padding_widths[1]; properties.padding_width_bottom = padding_widths[2]; break; case 4: properties.padding_width_top = padding_widths[0]; properties.padding_width_right = padding_widths[1]; properties.padding_width_bottom = padding_widths[2]; properties.padding_width_left = padding_widths[3]; break; default: break; } } if (out_change_set) { (*out_change_set)["padding-left"] = &properties.padding_width_left; (*out_change_set)["padding-right"] = &properties.padding_width_right; (*out_change_set)["padding-top"] = &properties.padding_width_top; (*out_change_set)["padding-bottom"] = &properties.padding_width_bottom; } }
void MarginPropertyParser::parse(StylePropertySetter *setter, const std::string &name, StyleParser &parser) { auto &tokens = parser.tokens; StyleSetValue margin_widths[4]; int count; size_t pos = 0; for (count = 0; count < 4; count++) { StyleToken token = next_token(pos, tokens); if (token.type == StyleTokenType::ident && equals(token.value, "auto")) { margin_widths[count] = StyleSetValue::from_keyword("auto"); } else if (token.type == StyleTokenType::ident && equals(token.value, "inherit") && count == 0 && pos == tokens.size()) { margin_widths[0] = StyleSetValue::from_keyword("inherit"); setter->set_value("margin-left", margin_widths[0]); setter->set_value("margin-top", margin_widths[0]); setter->set_value("margin-right", margin_widths[0]); setter->set_value("margin-bottom", margin_widths[0]); return; } else if (is_length(token)) { StyleSetValue length; if (parse_length(token, length)) { margin_widths[count] = length; } else { debug_parse_error(name, tokens); return; } } else if (token.type == StyleTokenType::percentage) { margin_widths[count] = StyleSetValue::from_percentage(StringHelp::text_to_float(token.value)); } else if (token.type == StyleTokenType::delim && token.value == "-") { token = next_token(pos, tokens); if (is_length(token)) { StyleSetValue length; if (parse_length(token, length)) { length.number = -length.number; margin_widths[count] = length; } else { debug_parse_error(name, tokens); return; } } else if (token.type == StyleTokenType::percentage) { margin_widths[count] = StyleSetValue::from_percentage(-StringHelp::text_to_float(token.value)); } else { debug_parse_error(name, tokens); return; } } else if (token.type == StyleTokenType::null) { break; } else { debug_parse_error(name, tokens); return; } } if (pos == tokens.size()) { switch (count) { case 1: setter->set_value("margin-left", margin_widths[0]); setter->set_value("margin-top", margin_widths[0]); setter->set_value("margin-right", margin_widths[0]); setter->set_value("margin-bottom", margin_widths[0]); break; case 2: setter->set_value("margin-top", margin_widths[0]); setter->set_value("margin-bottom", margin_widths[0]); setter->set_value("margin-left", margin_widths[1]); setter->set_value("margin-right", margin_widths[1]); break; case 3: setter->set_value("margin-top", margin_widths[0]); setter->set_value("margin-left", margin_widths[1]); setter->set_value("margin-right", margin_widths[1]); setter->set_value("margin-bottom", margin_widths[2]); break; case 4: setter->set_value("margin-top", margin_widths[0]); setter->set_value("margin-right", margin_widths[1]); setter->set_value("margin-bottom", margin_widths[2]); setter->set_value("margin-left", margin_widths[3]); break; default: break; } } }
void CSSParserBackgroundPosition::parse(const std::string &name, const std::vector<CSSToken> &tokens, std::vector<std::unique_ptr<CSSPropertyValue> > &inout_values) { std::unique_ptr<CSSValueBackgroundPosition> position(new CSSValueBackgroundPosition()); size_t pos = 0; CSSToken token = next_token(pos, tokens); if (token.type == CSSToken::type_ident && equals(token.value, "inherit") && tokens.size() == 1) { position->type = CSSValueBackgroundPosition::type_inherit; inout_values.push_back(std::move(position)); return; } position->type = CSSValueBackgroundPosition::type_value; position->positions.clear(); bool done = false; while (!done) { CSSValueBackgroundPosition::Position bg_pos; bool x_specified = false; bool y_specified = false; bool center_specified = false; while (true) { if (token.type == CSSToken::type_ident) { if (!y_specified && equals(token.value, "top")) { bg_pos.type_y = CSSValueBackgroundPosition::type2_top; y_specified = true; if (center_specified) { bg_pos.type_x = CSSValueBackgroundPosition::type1_center; x_specified = true; center_specified = false; } } else if (!y_specified && equals(token.value, "bottom")) { bg_pos.type_y = CSSValueBackgroundPosition::type2_bottom; y_specified = true; if (center_specified) { bg_pos.type_x = CSSValueBackgroundPosition::type1_center; x_specified = true; center_specified = false; } } else if (!x_specified && equals(token.value, "left")) { bg_pos.type_x = CSSValueBackgroundPosition::type1_left; x_specified = true; if (center_specified) { bg_pos.type_y = CSSValueBackgroundPosition::type2_center; y_specified = true; center_specified = false; } } else if (!x_specified && equals(token.value, "right")) { bg_pos.type_x = CSSValueBackgroundPosition::type1_right; x_specified = true; if (center_specified) { bg_pos.type_y = CSSValueBackgroundPosition::type2_center; y_specified = true; center_specified = false; } } else if (equals(token.value, "center")) { if (center_specified) { bg_pos.type_x = CSSValueBackgroundPosition::type1_center; x_specified = true; center_specified = false; } if (x_specified && !y_specified) { bg_pos.type_y = CSSValueBackgroundPosition::type2_center; y_specified = true; } else if (y_specified && !x_specified) { bg_pos.type_x = CSSValueBackgroundPosition::type1_center; x_specified = true; } else if (!x_specified && !y_specified) { center_specified = true; } else { debug_parse_error(name, tokens); return; } } } else if (is_length(token)) { CSSLength length; if (parse_length(token, length)) { if (center_specified) { bg_pos.type_x = CSSValueBackgroundPosition::type1_center; x_specified = true; center_specified = false; } if (!x_specified && !y_specified) { bg_pos.type_x = CSSValueBackgroundPosition::type1_length; bg_pos.length_x = length; x_specified = true; } else if (x_specified && !y_specified) { bg_pos.type_y = CSSValueBackgroundPosition::type2_length; bg_pos.length_y = length; y_specified = true; } else { debug_parse_error(name, tokens); return; } } else { debug_parse_error(name, tokens); return; } } else if (token.type == CSSToken::type_percentage) { if (center_specified) { bg_pos.type_x = CSSValueBackgroundPosition::type1_center; x_specified = true; center_specified = false; } if (!x_specified && !y_specified) { bg_pos.type_x = CSSValueBackgroundPosition::type1_percentage; bg_pos.percentage_x = StringHelp::text_to_float(token.value); x_specified = true; } else if (x_specified && !y_specified) { bg_pos.type_y = CSSValueBackgroundPosition::type2_percentage; bg_pos.percentage_y = StringHelp::text_to_float(token.value); y_specified = true; } else { debug_parse_error(name, tokens); return; } } else if (token.type == CSSToken::type_delim && token.value == "-") { token = next_token(pos, tokens); if (is_length(token)) { CSSLength length; if (parse_length(token, length)) { length.value = -length.value; if (center_specified) { bg_pos.type_x = CSSValueBackgroundPosition::type1_center; x_specified = true; center_specified = false; } if (!x_specified && !y_specified) { bg_pos.type_x = CSSValueBackgroundPosition::type1_length; bg_pos.length_x = length; x_specified = true; } else if (x_specified && !y_specified) { bg_pos.type_y = CSSValueBackgroundPosition::type2_length; bg_pos.length_y = length; y_specified = true; } else { debug_parse_error(name, tokens); return; } } else { debug_parse_error(name, tokens); return; } } else if (token.type == CSSToken::type_percentage) { if (center_specified) { bg_pos.type_x = CSSValueBackgroundPosition::type1_center; x_specified = true; center_specified = false; } if (!x_specified && !y_specified) { bg_pos.type_x = CSSValueBackgroundPosition::type1_percentage; bg_pos.percentage_x = -StringHelp::text_to_float(token.value); x_specified = true; } else if (x_specified && !y_specified) { bg_pos.type_y = CSSValueBackgroundPosition::type2_percentage; bg_pos.percentage_y = -StringHelp::text_to_float(token.value); y_specified = true; } else { debug_parse_error(name, tokens); return; } } else { debug_parse_error(name, tokens); return; } } else { debug_parse_error(name, tokens); return; } if (pos == tokens.size()) { done = true; break; } else { token = next_token(pos, tokens); if (token.type == CSSToken::type_delim && token.value == ",") break; } } if (!x_specified) bg_pos.type_x = CSSValueBackgroundPosition::type1_center; else if (!y_specified) bg_pos.type_y = CSSValueBackgroundPosition::type2_center; position->positions.push_back(bg_pos); } inout_values.push_back(std::move(position)); }
void CSSParserOutline::parse(const std::string &name, const std::vector<CSSToken> &tokens, std::vector<std::unique_ptr<CSSPropertyValue> > &inout_values) { std::unique_ptr<CSSValueOutlineWidth> outline_width(new CSSValueOutlineWidth()); std::unique_ptr<CSSValueOutlineStyle> outline_style(new CSSValueOutlineStyle()); std::unique_ptr<CSSValueOutlineColor> outline_color(new CSSValueOutlineColor()); bool width_specified = false; bool style_specified = false; bool color_specified = false; size_t pos = 0; while (pos != tokens.size()) { Colorf color; if (!color_specified && parse_color(tokens, pos, color)) { outline_color->type = CSSValueOutlineColor::type_color; outline_color->color = color; color_specified = true; } else { CSSToken token = next_token(pos, tokens); if (token.type == CSSToken::type_ident) { if (equals(token.value, "inherit") && tokens.size() == 1) { outline_width->type = CSSValueOutlineWidth::type_inherit; outline_style->type = CSSValueOutlineStyle::type_inherit; outline_color->type = CSSValueOutlineColor::type_inherit; inout_values.push_back(std::move(outline_width)); inout_values.push_back(std::move(outline_style)); inout_values.push_back(std::move(outline_color)); return; } else if (!width_specified && equals(token.value, "thin")) { outline_width->type = CSSValueOutlineWidth::type_thin; width_specified = true; } else if (!width_specified && equals(token.value, "medium")) { outline_width->type = CSSValueOutlineWidth::type_medium; width_specified = true; } else if (!width_specified && equals(token.value, "thick")) { outline_width->type = CSSValueOutlineWidth::type_thick; width_specified = true; } else if (!style_specified && equals(token.value, "none")) { outline_style->type = CSSValueOutlineStyle::type_none; style_specified = true; } else if (!style_specified && equals(token.value, "hidden")) { outline_style->type = CSSValueOutlineStyle::type_hidden; style_specified = true; } else if (!style_specified && equals(token.value, "dotted")) { outline_style->type = CSSValueOutlineStyle::type_dotted; style_specified = true; } else if (!style_specified && equals(token.value, "dashed")) { outline_style->type = CSSValueOutlineStyle::type_dashed; style_specified = true; } else if (!style_specified && equals(token.value, "solid")) { outline_style->type = CSSValueOutlineStyle::type_solid; style_specified = true; } else if (!style_specified && equals(token.value, "double")) { outline_style->type = CSSValueOutlineStyle::type_double; style_specified = true; } else if (!style_specified && equals(token.value, "groove")) { outline_style->type = CSSValueOutlineStyle::type_groove; style_specified = true; } else if (!style_specified && equals(token.value, "ridge")) { outline_style->type = CSSValueOutlineStyle::type_ridge; style_specified = true; } else if (!style_specified && equals(token.value, "inset")) { outline_style->type = CSSValueOutlineStyle::type_inset; style_specified = true; } else if (!style_specified && equals(token.value, "outset")) { outline_style->type = CSSValueOutlineStyle::type_outset; style_specified = true; } else if (!color_specified && equals(token.value, "invert")) { outline_color->type = CSSValueOutlineColor::type_invert; color_specified = true; } else { debug_parse_error(name, tokens); return; } } else if (is_length(token)) { CSSLength length; if (!width_specified && parse_length(token, length)) { outline_width->type = CSSValueOutlineWidth::type_length; outline_width->length = length; width_specified = true; } else { debug_parse_error(name, tokens); return; } } else { debug_parse_error(name, tokens); return; } } } inout_values.push_back(std::move(outline_width)); inout_values.push_back(std::move(outline_style)); inout_values.push_back(std::move(outline_color)); }
void CL_CSSParserBackgroundPosition::parse(CL_CSSBoxProperties &properties, const CL_String &name, const std::vector<CL_CSSToken> &tokens, std::map<CL_String, CL_CSSBoxProperty *> *out_change_set) { size_t pos = 0; CL_CSSToken token = next_token(pos, tokens); if (token.type == CL_CSSToken::type_ident && equals(token.value, "inherit") && tokens.size() == 1) { properties.background_position.type = CL_CSSBoxBackgroundPosition::type_inherit; if (out_change_set) { (*out_change_set)["background-position"] = &properties.background_position; } return; } CL_CSSBoxBackgroundPosition position; position.type = CL_CSSBoxBackgroundPosition::type_value; position.positions.clear(); bool done = false; while (!done) { CL_CSSBoxBackgroundPosition::Position bg_pos; bool x_specified = false; bool y_specified = false; bool center_specified = false; while (true) { if (token.type == CL_CSSToken::type_ident) { if (!y_specified && equals(token.value, "top")) { bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_top; y_specified = true; if (center_specified) { bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_center; x_specified = true; center_specified = false; } } else if (!y_specified && equals(token.value, "bottom")) { bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_bottom; y_specified = true; if (center_specified) { bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_center; x_specified = true; center_specified = false; } } else if (!x_specified && equals(token.value, "left")) { bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_left; x_specified = true; if (center_specified) { bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_center; y_specified = true; center_specified = false; } } else if (!x_specified && equals(token.value, "right")) { bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_right; x_specified = true; if (center_specified) { bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_center; y_specified = true; center_specified = false; } } else if (equals(token.value, "center")) { if (center_specified) { bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_center; x_specified = true; center_specified = false; } if (x_specified && !y_specified) { bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_center; y_specified = true; } else if (y_specified && !x_specified) { bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_center; x_specified = true; } else if (!x_specified && !y_specified) { center_specified = true; } else { debug_parse_error(name, tokens); return; } } } else if (is_length(token)) { CL_CSSBoxLength length; if (parse_length(token, length)) { if (center_specified) { bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_center; x_specified = true; center_specified = false; } if (!x_specified && !y_specified) { bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_length; bg_pos.length_x = length; x_specified = true; } else if (x_specified && !y_specified) { bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_length; bg_pos.length_y = length; y_specified = true; } else { debug_parse_error(name, tokens); return; } } else { debug_parse_error(name, tokens); return; } } else if (token.type == CL_CSSToken::type_percentage) { if (center_specified) { bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_center; x_specified = true; center_specified = false; } if (!x_specified && !y_specified) { bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_percentage; bg_pos.percentage_x = CL_StringHelp::text_to_float(token.value); x_specified = true; } else if (x_specified && !y_specified) { bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_percentage; bg_pos.percentage_y = CL_StringHelp::text_to_float(token.value); y_specified = true; } else { debug_parse_error(name, tokens); return; } } else if (token.type == CL_CSSToken::type_delim && token.value == "-") { token = next_token(pos, tokens); if (is_length(token)) { CL_CSSBoxLength length; if (parse_length(token, length)) { length.value = -length.value; if (center_specified) { bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_center; x_specified = true; center_specified = false; } if (!x_specified && !y_specified) { bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_length; bg_pos.length_x = length; x_specified = true; } else if (x_specified && !y_specified) { bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_length; bg_pos.length_y = length; y_specified = true; } else { debug_parse_error(name, tokens); return; } } else { debug_parse_error(name, tokens); return; } } else if (token.type == CL_CSSToken::type_percentage) { if (center_specified) { bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_center; x_specified = true; center_specified = false; } if (!x_specified && !y_specified) { bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_percentage; bg_pos.percentage_x = -CL_StringHelp::text_to_float(token.value); x_specified = true; } else if (x_specified && !y_specified) { bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_percentage; bg_pos.percentage_y = -CL_StringHelp::text_to_float(token.value); y_specified = true; } else { debug_parse_error(name, tokens); return; } } else { debug_parse_error(name, tokens); return; } } else { debug_parse_error(name, tokens); return; } if (pos == tokens.size()) { done = true; break; } else { token = next_token(pos, tokens); if (token.type == CL_CSSToken::type_delim && token.value == ",") break; } } if (!x_specified) bg_pos.type_x = CL_CSSBoxBackgroundPosition::type1_center; else if (!y_specified) bg_pos.type_y = CL_CSSBoxBackgroundPosition::type2_center; position.positions.push_back(bg_pos); } properties.background_position = position; if (out_change_set) { (*out_change_set)["background-position"] = &properties.background_position; } }
void CSSParserFont::parse(const std::string &propname, const std::vector<CSSToken> &tokens, std::vector<std::unique_ptr<CSSPropertyValue> > &inout_values) { std::unique_ptr<CSSValueFontStyle> style(new CSSValueFontStyle()); std::unique_ptr<CSSValueFontVariant> variant(new CSSValueFontVariant()); std::unique_ptr<CSSValueFontWeight> weight(new CSSValueFontWeight()); std::unique_ptr<CSSValueFontSize> size(new CSSValueFontSize()); std::unique_ptr<CSSValueLineHeight> line_height(new CSSValueLineHeight()); std::unique_ptr<CSSValueFontFamily> family(new CSSValueFontFamily()); style->type = CSSValueFontStyle::type_normal; variant->type = CSSValueFontVariant::type_normal; weight->type = CSSValueFontWeight::type_normal; size->type = CSSValueFontSize::type_medium; line_height->type = CSSValueLineHeight::type_normal; family->type = CSSValueFontFamily::type_names; family->names.push_back(CSSValueFontFamilyName()); bool font_style_set = false; bool font_variant_set = false; bool font_weight_set = false; int normal_count = 0; size_t pos = 0; CSSToken token; while (pos < tokens.size()) { token = next_token(pos, tokens); if (token.type == CSSToken::type_ident) { if (tokens.size() == 1 && (equals(token.value, "caption") || equals(token.value, "icon") || equals(token.value, "menu") || equals(token.value, "message-box") || equals(token.value, "small-caption") || equals(token.value, "status-bar"))) { inout_values.push_back(std::move(style)); inout_values.push_back(std::move(variant)); inout_values.push_back(std::move(weight)); inout_values.push_back(std::move(size)); inout_values.push_back(std::move(line_height)); inout_values.push_back(std::move(family)); return; } else if (equals(token.value, "inherit") && tokens.size() == 1) { style->type = CSSValueFontStyle::type_inherit; variant->type = CSSValueFontVariant::type_inherit; weight->type = CSSValueFontWeight::type_inherit; size->type = CSSValueFontSize::type_inherit; line_height->type = CSSValueLineHeight::type_inherit; family->type = CSSValueFontFamily::type_inherit; inout_values.push_back(std::move(style)); inout_values.push_back(std::move(variant)); inout_values.push_back(std::move(weight)); inout_values.push_back(std::move(size)); inout_values.push_back(std::move(line_height)); inout_values.push_back(std::move(family)); return; } else if (equals(token.value, "normal")) // font-style or font-weight or font-variant { int allowed = 3; if (font_style_set) allowed--; if (font_weight_set) allowed--; if (font_variant_set) allowed--; if (normal_count < allowed) normal_count++; } else if (equals(token.value, "italic") && !font_style_set) // font-style { font_style_set = true; style->type = CSSValueFontStyle::type_italic; } else if (equals(token.value, "oblique") && !font_style_set) // font-style { font_style_set = true; style->type = CSSValueFontStyle::type_oblique; } else if (equals(token.value, "small-caps") && !font_variant_set) // font-variant { font_style_set = true; variant->type = CSSValueFontVariant::type_small_caps; } else if (equals(token.value, "bold") && !font_weight_set) // font-weight { font_weight_set = true; weight->type = CSSValueFontWeight::type_bold; } else if (equals(token.value, "bolder") && !font_weight_set) // font-weight { font_weight_set = true; weight->type = CSSValueFontWeight::type_bolder; } else if (equals(token.value, "lighter") && !font_weight_set) // font-weight { font_weight_set = true; weight->type = CSSValueFontWeight::type_lighter; } else if (token.value == "100" && !font_weight_set) // font-weight { font_weight_set = true; weight->type = CSSValueFontWeight::type_100; } else if (token.value == "200" && !font_weight_set) // font-weight { font_weight_set = true; weight->type = CSSValueFontWeight::type_200; } else if (token.value == "300" && !font_weight_set) // font-weight { font_weight_set = true; weight->type = CSSValueFontWeight::type_300; } else if (token.value == "400" && !font_weight_set) // font-weight { font_weight_set = true; weight->type = CSSValueFontWeight::type_400; } else if (token.value == "500" && !font_weight_set) // font-weight { font_weight_set = true; weight->type = CSSValueFontWeight::type_500; } else if (token.value == "600" && !font_weight_set) // font-weight { font_weight_set = true; weight->type = CSSValueFontWeight::type_600; } else if (token.value == "700" && !font_weight_set) // font-weight { font_weight_set = true; weight->type = CSSValueFontWeight::type_700; } else if (token.value == "800" && !font_weight_set) // font-weight { font_weight_set = true; weight->type = CSSValueFontWeight::type_800; } else if (token.value == "900" && !font_weight_set) // font-weight { font_weight_set = true; weight->type = CSSValueFontWeight::type_900; } else { break; } } else { break; } } if (pos == tokens.size()) { debug_parse_error(propname, tokens); return; } if (token.type == CSSToken::type_ident) { if (equals(token.value, "xx-small")) size->type = CSSValueFontSize::type_xx_small; else if (equals(token.value, "x-small")) size->type = CSSValueFontSize::type_x_small; else if (equals(token.value, "small")) size->type = CSSValueFontSize::type_small; else if (equals(token.value, "medium")) size->type = CSSValueFontSize::type_medium; else if (equals(token.value, "large")) size->type = CSSValueFontSize::type_large; else if (equals(token.value, "x-large")) size->type = CSSValueFontSize::type_x_large; else if (equals(token.value, "xx-large")) size->type = CSSValueFontSize::type_xx_large; else if (equals(token.value, "smaller")) size->type = CSSValueFontSize::type_smaller; else if (equals(token.value, "larger")) size->type = CSSValueFontSize::type_larger; else if (equals(token.value, "inherit")) size->type = CSSValueFontSize::type_inherit; else { debug_parse_error(propname, tokens); return; } } else if (is_length(token)) { CSSLength length; if (parse_length(token, length)) { size->type = CSSValueFontSize::type_length; size->length = length; } else { debug_parse_error(propname, tokens); return; } } else if (token.type == CSSToken::type_percentage) { size->type = CSSValueFontSize::type_percentage; size->percentage = StringHelp::text_to_float(token.value); } else { debug_parse_error(propname, tokens); return; } token = next_token(pos, tokens); if (token.type == CSSToken::type_delim && token.value == "/") { token = next_token(pos, tokens); if (token.type == CSSToken::type_ident) { if (equals(token.value, "normal")) line_height->type = CSSValueLineHeight::type_normal; else if (equals(token.value, "inherit")) line_height->type = CSSValueLineHeight::type_inherit; else { debug_parse_error(propname, tokens); return; } } else if (token.type == CSSToken::type_number) { line_height->type = CSSValueLineHeight::type_number; line_height->number = StringHelp::text_to_float(token.value); } else if (is_length(token)) { CSSLength length; if (parse_length(token, length)) { line_height->type = CSSValueLineHeight::type_length; line_height->length = length; } else { debug_parse_error(propname, tokens); return; } } else if (token.type == CSSToken::type_percentage) { line_height->type = CSSValueLineHeight::type_percentage; line_height->percentage = StringHelp::text_to_float(token.value); } else { debug_parse_error(propname, tokens); return; } token = next_token(pos, tokens); } family->names.clear(); while (true) { if (token.type == CSSToken::type_ident) { CSSValueFontFamilyName name; if (equals(token.value, "serif")) { name.type = CSSValueFontFamilyName::type_serif; } else if (equals(token.value, "sans-serif")) { name.type = CSSValueFontFamilyName::type_sans_serif; } else if (equals(token.value, "cursive")) { name.type = CSSValueFontFamilyName::type_cursive; } else if (equals(token.value, "fantasy")) { name.type = CSSValueFontFamilyName::type_fantasy; } else if (equals(token.value, "monospace")) { name.type = CSSValueFontFamilyName::type_monospace; } else if (equals(token.value, "default")) { // reserved for future use return; } else if (equals(token.value, "initial")) { // reserved for future use return; } else { name.type = CSSValueFontFamilyName::type_family_name; } if (name.type == CSSValueFontFamilyName::type_family_name) { name.name = token.value; while (pos != tokens.size()) { token = tokens[pos++]; if (token.type == CSSToken::type_whitespace) { name.name += " "; } else if (token.type == CSSToken::type_ident) { name.name += token.value; } else if (token.type == CSSToken::type_delim && token.value == ",") { break; } } family->names.push_back(name); if (pos == tokens.size()) break; token = next_token(pos, tokens); } else { family->names.push_back(name); if (pos == tokens.size()) break; token = next_token(pos, tokens); if (token.type != CSSToken::type_delim || token.value != ",") { debug_parse_error(propname, tokens); return; } token = next_token(pos, tokens); } } else if (token.type == CSSToken::type_string) { CSSValueFontFamilyName name; name.type = CSSValueFontFamilyName::type_family_name; name.name = token.value; family->names.push_back(name); if (pos == tokens.size()) break; token = next_token(pos, tokens); if (token.type != CSSToken::type_delim || token.value != ",") { debug_parse_error(propname, tokens); return; } token = next_token(pos, tokens); } else { debug_parse_error(propname, tokens); return; } } inout_values.push_back(std::move(style)); inout_values.push_back(std::move(variant)); inout_values.push_back(std::move(weight)); inout_values.push_back(std::move(size)); inout_values.push_back(std::move(line_height)); inout_values.push_back(std::move(family)); }
void CSSParserBorderColor::parse(const std::string &name, const std::vector<CSSToken> &tokens, std::vector<std::unique_ptr<CSSPropertyValue> > &inout_values) { CSSValueBorderColor border_colors[4]; int count; size_t pos = 0; for (count = 0; count < 4; count++) { Colorf color; if (parse_color(tokens, pos, color)) { border_colors[count].type = CSSValueBorderColor::type_color; border_colors[count].color = color; } else { CSSToken token = next_token(pos, tokens); if (token.type == CSSToken::type_ident) { if (equals(token.value, "inherit")) { if (count == 0 && pos == tokens.size()) { border_colors[0].type = CSSValueBorderColor::type_inherit; inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::left_value, border_colors[0]))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::right_value, border_colors[0]))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::top_value, border_colors[0]))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::bottom_value, border_colors[0]))); } else { debug_parse_error(name, tokens); } return; } else { debug_parse_error(name, tokens); return; } } else if (token.type == CSSToken::type_null) { break; } else { debug_parse_error(name, tokens); return; } } } if (pos == tokens.size()) { switch (count) { case 1: inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::left_value, border_colors[0]))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::right_value, border_colors[0]))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::top_value, border_colors[0]))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::bottom_value, border_colors[0]))); break; case 2: inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::top_value, border_colors[0]))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::bottom_value, border_colors[0]))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::left_value, border_colors[1]))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::right_value, border_colors[1]))); break; case 3: inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::top_value, border_colors[0]))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::left_value, border_colors[1]))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::right_value, border_colors[1]))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::bottom_value, border_colors[2]))); break; case 4: inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::top_value, border_colors[0]))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::right_value, border_colors[1]))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::left_value, border_colors[2]))); inout_values.push_back(std::unique_ptr<CSSValueBorderColor>(new CSSValueBorderColor(CSSValueBorderColor::bottom_value, border_colors[3]))); break; default: break; } } }
void CSSParserBorderRadius::parse(const std::string &name, const std::vector<CSSToken> &tokens, std::vector<std::unique_ptr<CSSPropertyValue> > &inout_values) { CSSValueBorderRadius radius[4]; size_t pos = 0; CSSToken token = next_token(pos, tokens); if (token.type == CSSToken::type_ident && equals(token.value, "inherit") && pos == tokens.size()) { radius[0].type = CSSValueBorderRadius::type_inherit; inout_values.push_back(std::unique_ptr<CSSValueBorderRadius>(new CSSValueBorderRadius(CSSValueBorderRadius::top_left_value, radius[0]))); inout_values.push_back(std::unique_ptr<CSSValueBorderRadius>(new CSSValueBorderRadius(CSSValueBorderRadius::top_right_value, radius[0]))); inout_values.push_back(std::unique_ptr<CSSValueBorderRadius>(new CSSValueBorderRadius(CSSValueBorderRadius::bottom_left_value, radius[0]))); inout_values.push_back(std::unique_ptr<CSSValueBorderRadius>(new CSSValueBorderRadius(CSSValueBorderRadius::bottom_right_value, radius[0]))); return; } int num_x_values = 0; int num_y_values = 0; for (int i = 0; i < 4; i++) { if (is_length(token)) { if (!parse_length(token, radius[i].length1)) { debug_parse_error(name, tokens); return; } radius[i].type = CSSValueBorderRadius::type_one_value; radius[i].value_type1 = CSSValueBorderRadius::value_type_length; } else if (token.type == CSSToken::type_percentage) { radius[i].type = CSSValueBorderRadius::type_one_value; radius[i].value_type1 = CSSValueBorderRadius::value_type_percentage; radius[i].percentage1 = StringHelp::text_to_float(token.value); } else { debug_parse_error(name, tokens); return; } num_x_values = i+1; token = next_token(pos, tokens); if (token.type == CSSToken::type_null) break; else if (i != 0 && token.type == CSSToken::type_delim && token.value == "/") break; } if (token.type == CSSToken::type_delim && token.value == "/") { token = next_token(pos, tokens); for (int i = 0; i < 4; i++) { if (is_length(token) && parse_length(token, radius[i].length2)) { radius[i].type = CSSValueBorderRadius::type_two_values; } else if (token.type == CSSToken::type_percentage) { radius[i].type = CSSValueBorderRadius::type_two_values; radius[i].value_type2 = CSSValueBorderRadius::value_type_percentage; radius[i].percentage2 = StringHelp::text_to_float(token.value); } else { debug_parse_error(name, tokens); return; } num_y_values = i+1; token = next_token(pos, tokens); if (token.type == CSSToken::type_null) break; } } else if (token.type != CSSToken::type_null) { debug_parse_error(name, tokens); return; } if (num_y_values > 0) { if (num_x_values < num_y_values) { for (int i = num_x_values; i < num_y_values; i++) { radius[i].type = CSSValueBorderRadius::type_two_values; radius[i].value_type1 = radius[i].value_type2; radius[i].length1 = radius[i].length2; radius[i].percentage1 = radius[i].percentage2; } num_x_values = num_y_values; } else if (num_y_values < num_x_values) { for (int i = num_y_values; i < num_x_values; i++) { radius[i].type = CSSValueBorderRadius::type_two_values; radius[i].value_type2 = radius[i].value_type1; radius[i].length2 = radius[i].length1; radius[i].percentage2 = radius[i].percentage1; } num_y_values = num_x_values; } } for (int i = num_x_values; i < 4; i++) radius[i] = radius[i-1]; inout_values.push_back(std::unique_ptr<CSSValueBorderRadius>(new CSSValueBorderRadius(CSSValueBorderRadius::top_right_value, radius[0]))); inout_values.push_back(std::unique_ptr<CSSValueBorderRadius>(new CSSValueBorderRadius(CSSValueBorderRadius::bottom_left_value, radius[1]))); inout_values.push_back(std::unique_ptr<CSSValueBorderRadius>(new CSSValueBorderRadius(CSSValueBorderRadius::bottom_right_value, radius[2]))); inout_values.push_back(std::unique_ptr<CSSValueBorderRadius>(new CSSValueBorderRadius(CSSValueBorderRadius::top_left_value, radius[3]))); }