7 std::map
<string_id
, string
> style::m_valid_values
=
9 { _display_
, style_display_strings
},
10 { _visibility_
, visibility_strings
},
11 { _position_
, element_position_strings
},
12 { _float_
, element_float_strings
},
13 { _clear_
, element_clear_strings
},
14 { _overflow_
, overflow_strings
},
15 { _box_sizing_
, box_sizing_strings
},
17 { _text_align_
, text_align_strings
},
18 { _vertical_align_
, vertical_align_strings
},
19 { _text_transform_
, text_transform_strings
},
20 { _white_space_
, white_space_strings
},
22 { _font_style_
, font_style_strings
},
23 { _font_variant_
, font_variant_strings
},
24 { _font_weight_
, font_weight_strings
},
26 { _list_style_type_
, list_style_type_strings
},
27 { _list_style_position_
, list_style_position_strings
},
29 { _border_left_style_
, border_style_strings
},
30 { _border_right_style_
, border_style_strings
},
31 { _border_top_style_
, border_style_strings
},
32 { _border_bottom_style_
, border_style_strings
},
33 { _border_collapse_
, border_collapse_strings
},
35 // these 4 properties are comma-separated lists of keywords, see parse_keyword_comma_list
36 { _background_attachment_
, background_attachment_strings
},
37 { _background_repeat_
, background_repeat_strings
},
38 { _background_clip_
, background_box_strings
},
39 { _background_origin_
, background_box_strings
},
41 { _flex_direction_
, flex_direction_strings
},
42 { _flex_wrap_
, flex_wrap_strings
},
43 { _justify_content_
, flex_justify_content_strings
},
44 { _align_items_
, flex_align_items_strings
},
45 { _align_content_
, flex_align_content_strings
},
46 { _align_self_
, flex_align_self_strings
},
48 { _caption_side_
, caption_side_strings
},
51 void style::parse(const string
& txt
, const string
& baseurl
, document_container
* container
)
53 std::vector
<string
> properties
;
54 split_string(txt
, properties
, ";", "", "\"'");
56 for(const auto & property
: properties
)
58 parse_property(property
, baseurl
, container
);
62 void style::parse_property(const string
& txt
, const string
& baseurl
, document_container
* container
)
64 string::size_type pos
= txt
.find_first_of(':');
65 if(pos
!= string::npos
)
67 string name
= txt
.substr(0, pos
);
68 string val
= txt
.substr(pos
+ 1);
70 trim(name
); lcase(name
);
73 if(!name
.empty() && !val
.empty())
76 split_string(val
, vals
, "!");
79 add_property(_id(name
), val
, baseurl
, false, container
);
80 } else if(vals
.size() > 1)
84 add_property(_id(name
), vals
[0], baseurl
, vals
[1] == "important", container
);
90 void style::add_property(string_id name
, const string
& val
, const string
& baseurl
, bool important
, document_container
* container
)
92 if (val
.find("var(") != -1) return add_parsed_property(name
, property_value(val
, important
, prop_type_var
));
93 if (val
== "inherit" && name
!= _font_
) return add_parsed_property(name
, property_value(important
, prop_type_inherit
));
97 css_length len
[4], length
;
101 // keyword-only properties
111 case _vertical_align_
:
112 case _text_transform_
:
119 case _list_style_type_
:
120 case _list_style_position_
:
122 case _border_top_style_
:
123 case _border_bottom_style_
:
124 case _border_left_style_
:
125 case _border_right_style_
:
126 case _border_collapse_
:
128 case _flex_direction_
:
130 case _justify_content_
:
132 case _align_content_
:
137 idx
= value_index(val
, m_valid_values
[name
]);
140 add_parsed_property(name
, property_value(idx
, important
));
147 case _padding_right_
:
149 case _padding_bottom_
:
150 length
.fromString(val
);
151 add_parsed_property(name
, property_value(length
, important
));
159 case _z_index_
: // <integer> | auto
167 case _margin_bottom_
:
168 length
.fromString(val
, "auto", -1);
169 add_parsed_property(name
, property_value(length
, important
));
175 length
.fromString(val
, "none", -1);
176 add_parsed_property(name
, property_value(length
, important
));
180 length
.fromString(val
, "normal", -1);
181 add_parsed_property(name
, property_value(length
, important
));
185 length
.fromString(val
, font_size_strings
, -1);
186 add_parsed_property(name
, property_value(length
, important
));
189 // Parse background shorthand properties
191 parse_background(val
, baseurl
, important
, container
);
194 case _background_image_
:
195 parse_background_image(val
, baseurl
, important
);
198 case _background_attachment_
:
199 case _background_repeat_
:
200 case _background_clip_
:
201 case _background_origin_
:
202 parse_keyword_comma_list(name
, val
, important
);
205 case _background_position_
:
206 parse_background_position(val
, important
);
209 case _background_size_
:
210 parse_background_size(val
, important
);
213 // Parse border spacing properties
214 case _border_spacing_
:
215 parse_two_lengths(val
, len
);
216 add_parsed_property(__litehtml_border_spacing_x_
, property_value(len
[0], important
));
217 add_parsed_property(__litehtml_border_spacing_y_
, property_value(len
[1], important
));
220 // Parse borders shorthand properties
223 string_vector tokens
;
224 split_string(val
, tokens
, " ", "", "(");
225 for (const auto& token
: tokens
)
227 int idx
= value_index(token
, border_style_strings
);
230 property_value
style(idx
, important
);
231 add_parsed_property(_border_left_style_
, style
);
232 add_parsed_property(_border_right_style_
, style
);
233 add_parsed_property(_border_top_style_
, style
);
234 add_parsed_property(_border_bottom_style_
, style
);
236 else if (t_isdigit(token
[0]) || token
[0] == '.' ||
237 value_in_list(token
, border_width_strings
))
239 property_value
width(parse_border_width(token
), important
);
240 add_parsed_property(_border_left_width_
, width
);
241 add_parsed_property(_border_right_width_
, width
);
242 add_parsed_property(_border_top_width_
, width
);
243 add_parsed_property(_border_bottom_width_
, width
);
245 else if (web_color::is_color(token
, container
))
247 web_color _color
= web_color::from_string(token
, container
);
248 property_value
color(_color
, important
);
249 add_parsed_property(_border_left_color_
, color
);
250 add_parsed_property(_border_right_color_
, color
);
251 add_parsed_property(_border_top_color_
, color
);
252 add_parsed_property(_border_bottom_color_
, color
);
261 case _border_bottom_
:
263 string_vector tokens
;
264 split_string(val
, tokens
, " ", "", "(");
265 for (const auto& token
: tokens
)
267 int idx
= value_index(token
, border_style_strings
);
270 add_parsed_property(_id(_s(name
) + "-style"), property_value(idx
, important
));
272 else if (t_isdigit(token
[0]) || token
[0] == '.' ||
273 value_in_list(token
, border_width_strings
))
275 property_value
width(parse_border_width(token
), important
);
276 add_parsed_property(_id(_s(name
) + "-width"), width
);
278 else if (web_color::is_color(token
, container
))
280 web_color color
= web_color::from_string(token
, container
);
281 add_parsed_property(_id(_s(name
) + "-color"), property_value(color
, important
));
287 // Parse border-width/style/color shorthand properties
292 string prop
= name
== _border_width_
? "-width" : name
== _border_style_
? "-style" : "-color";
294 string_vector tokens
;
295 split_string(val
, tokens
, " ");
296 if (tokens
.size() == 4)
298 add_property(_id("border-top" + prop
), tokens
[0], baseurl
, important
, container
);
299 add_property(_id("border-right" + prop
), tokens
[1], baseurl
, important
, container
);
300 add_property(_id("border-bottom" + prop
), tokens
[2], baseurl
, important
, container
);
301 add_property(_id("border-left" + prop
), tokens
[3], baseurl
, important
, container
);
303 else if (tokens
.size() == 3)
305 add_property(_id("border-top" + prop
), tokens
[0], baseurl
, important
, container
);
306 add_property(_id("border-right" + prop
), tokens
[1], baseurl
, important
, container
);
307 add_property(_id("border-left" + prop
), tokens
[1], baseurl
, important
, container
);
308 add_property(_id("border-bottom" + prop
), tokens
[2], baseurl
, important
, container
);
310 else if (tokens
.size() == 2)
312 add_property(_id("border-top" + prop
), tokens
[0], baseurl
, important
, container
);
313 add_property(_id("border-bottom" + prop
), tokens
[0], baseurl
, important
, container
);
314 add_property(_id("border-right" + prop
), tokens
[1], baseurl
, important
, container
);
315 add_property(_id("border-left" + prop
), tokens
[1], baseurl
, important
, container
);
317 else if (tokens
.size() == 1)
319 add_property(_id("border-top" + prop
), tokens
[0], baseurl
, important
, container
);
320 add_property(_id("border-bottom" + prop
), tokens
[0], baseurl
, important
, container
);
321 add_property(_id("border-right" + prop
), tokens
[0], baseurl
, important
, container
);
322 add_property(_id("border-left" + prop
), tokens
[0], baseurl
, important
, container
);
327 case _border_top_width_
:
328 case _border_bottom_width_
:
329 case _border_left_width_
:
330 case _border_right_width_
:
331 length
= parse_border_width(val
);
332 add_parsed_property(name
, property_value(length
, important
));
336 case _background_color_
:
337 case _border_top_color_
:
338 case _border_bottom_color_
:
339 case _border_left_color_
:
340 case _border_right_color_
:
341 if (web_color::is_color(val
, container
))
343 web_color color
= web_color::from_string(val
, container
);
344 add_parsed_property(name
, property_value(color
, important
));
348 // Parse border radius shorthand properties
349 case _border_bottom_left_radius_
:
350 case _border_bottom_right_radius_
:
351 case _border_top_right_radius_
:
352 case _border_top_left_radius_
:
353 parse_two_lengths(val
, len
);
354 add_parsed_property(_id(_s(name
) + "-x"), property_value(len
[0], important
));
355 add_parsed_property(_id(_s(name
) + "-y"), property_value(len
[1], important
));
358 // Parse border-radius shorthand properties
359 case _border_radius_
:
361 string_vector tokens
;
362 split_string(val
, tokens
, "/");
363 if (tokens
.size() == 1)
365 add_property(_border_radius_x_
, tokens
[0], baseurl
, important
, container
);
366 add_property(_border_radius_y_
, tokens
[0], baseurl
, important
, container
);
368 else if (tokens
.size() >= 2)
370 add_property(_border_radius_x_
, tokens
[0], baseurl
, important
, container
);
371 add_property(_border_radius_y_
, tokens
[1], baseurl
, important
, container
);
375 case _border_radius_x_
:
376 case _border_radius_y_
:
378 string_id top_left
, top_right
, bottom_right
, bottom_left
;
379 if (name
== _border_radius_x_
)
381 top_left
= _border_top_left_radius_x_
;
382 top_right
= _border_top_right_radius_x_
;
383 bottom_right
= _border_bottom_right_radius_x_
;
384 bottom_left
= _border_bottom_left_radius_x_
;
388 top_left
= _border_top_left_radius_y_
;
389 top_right
= _border_top_right_radius_y_
;
390 bottom_right
= _border_bottom_right_radius_y_
;
391 bottom_left
= _border_bottom_left_radius_y_
;
394 switch (parse_four_lengths(val
, len
))
397 add_parsed_property(top_left
, property_value(len
[0], important
));
398 add_parsed_property(top_right
, property_value(len
[0], important
));
399 add_parsed_property(bottom_right
, property_value(len
[0], important
));
400 add_parsed_property(bottom_left
, property_value(len
[0], important
));
403 add_parsed_property(top_left
, property_value(len
[0], important
));
404 add_parsed_property(top_right
, property_value(len
[1], important
));
405 add_parsed_property(bottom_right
, property_value(len
[0], important
));
406 add_parsed_property(bottom_left
, property_value(len
[1], important
));
409 add_parsed_property(top_left
, property_value(len
[0], important
));
410 add_parsed_property(top_right
, property_value(len
[1], important
));
411 add_parsed_property(bottom_right
, property_value(len
[2], important
));
412 add_parsed_property(bottom_left
, property_value(len
[1], important
));
415 add_parsed_property(top_left
, property_value(len
[0], important
));
416 add_parsed_property(top_right
, property_value(len
[1], important
));
417 add_parsed_property(bottom_right
, property_value(len
[2], important
));
418 add_parsed_property(bottom_left
, property_value(len
[3], important
));
424 // Parse list-style shorthand properties
427 add_parsed_property(_list_style_type_
, property_value(list_style_type_disc
, important
));
428 add_parsed_property(_list_style_position_
, property_value(list_style_position_outside
, important
));
429 add_parsed_property(_list_style_image_
, property_value("", important
));
430 add_parsed_property(_list_style_image_baseurl_
, property_value("", important
));
432 string_vector tokens
;
433 split_string(val
, tokens
, " ", "", "(");
434 for (const auto& token
: tokens
)
436 int idx
= value_index(token
, list_style_type_strings
);
439 add_parsed_property(_list_style_type_
, property_value(idx
, important
));
443 idx
= value_index(token
, list_style_position_strings
);
446 add_parsed_property(_list_style_position_
, property_value(idx
, important
));
448 else if (!strncmp(token
.c_str(), "url", 3))
450 css::parse_css_url(token
, url
);
451 add_parsed_property(_list_style_image_
, property_value(url
, important
));
452 add_parsed_property(_list_style_image_baseurl_
, property_value(baseurl
, important
));
459 case _list_style_image_
:
460 css::parse_css_url(val
, url
);
461 add_parsed_property(_list_style_image_
, property_value(url
, important
));
462 add_parsed_property(_list_style_image_baseurl_
, property_value(baseurl
, important
));
465 // Parse margin and padding shorthand properties
469 switch (parse_four_lengths(val
, len
))
472 add_parsed_property(_id(_s(name
) + "-top"), property_value(len
[0], important
));
473 add_parsed_property(_id(_s(name
) + "-right"), property_value(len
[1], important
));
474 add_parsed_property(_id(_s(name
) + "-bottom"), property_value(len
[2], important
));
475 add_parsed_property(_id(_s(name
) + "-left"), property_value(len
[3], important
));
478 add_parsed_property(_id(_s(name
) + "-top"), property_value(len
[0], important
));
479 add_parsed_property(_id(_s(name
) + "-right"), property_value(len
[1], important
));
480 add_parsed_property(_id(_s(name
) + "-left"), property_value(len
[1], important
));
481 add_parsed_property(_id(_s(name
) + "-bottom"), property_value(len
[2], important
));
484 add_parsed_property(_id(_s(name
) + "-top"), property_value(len
[0], important
));
485 add_parsed_property(_id(_s(name
) + "-bottom"), property_value(len
[0], important
));
486 add_parsed_property(_id(_s(name
) + "-right"), property_value(len
[1], important
));
487 add_parsed_property(_id(_s(name
) + "-left"), property_value(len
[1], important
));
490 add_parsed_property(_id(_s(name
) + "-top"), property_value(len
[0], important
));
491 add_parsed_property(_id(_s(name
) + "-bottom"), property_value(len
[0], important
));
492 add_parsed_property(_id(_s(name
) + "-right"), property_value(len
[0], important
));
493 add_parsed_property(_id(_s(name
) + "-left"), property_value(len
[0], important
));
499 // Parse font shorthand properties
501 parse_font(val
, important
);
504 // Parse flex-flow shorthand properties
507 string_vector tokens
;
508 split_string(val
, tokens
, " ");
509 for (const auto& tok
: tokens
)
512 if ((idx
= value_index(tok
, flex_direction_strings
)) >= 0)
514 add_parsed_property(_flex_direction_
, property_value(idx
, important
));
516 else if ((idx
= value_index(tok
, flex_wrap_strings
)) >= 0)
518 add_parsed_property(_flex_wrap_
, property_value(idx
, important
));
524 // Parse flex shorthand properties
526 parse_flex(val
, important
);
531 add_parsed_property(name
, property_value(t_strtof(val
), important
));
535 length
.fromString(val
, flex_basis_strings
, -1);
536 add_parsed_property(_flex_basis_
, property_value(length
, important
));
540 add_parsed_property(name
, property_value(val
, important
));
544 css_length
style::parse_border_width(const string
& str
)
547 if (t_isdigit(str
[0]) || str
[0] == '.')
553 int idx
= value_index(str
, border_width_strings
);
556 len
.set_value(border_width_values
[idx
], css_units_px
);
562 void style::parse_two_lengths(const string
& str
, css_length len
[2])
564 string_vector tokens
;
565 split_string(str
, tokens
, " ");
566 if (tokens
.size() == 1)
569 length
.fromString(tokens
[0]);
570 len
[0] = len
[1] = length
;
572 else if (tokens
.size() == 2)
574 len
[0].fromString(tokens
[0]);
575 len
[1].fromString(tokens
[1]);
579 int style::parse_four_lengths(const string
& str
, css_length len
[4])
581 string_vector tokens
;
582 split_string(str
, tokens
, " ");
583 if (tokens
.size() == 0 || tokens
.size() > 4)
587 for (size_t i
= 0; i
< tokens
.size(); i
++)
589 len
[i
].fromString(tokens
[i
]);
591 return (int)tokens
.size();
594 void style::parse_background(const string
& val
, const string
& baseurl
, bool important
, document_container
* container
)
596 string_vector tokens
;
597 split_string(val
, tokens
, ",", "", "(");
598 if (tokens
.empty()) return;
601 string_vector images
;
602 int_vector repeats
, origins
, clips
, attachments
;
603 length_vector x_positions
, y_positions
;
606 for (const auto& token
: tokens
)
609 if (!parse_one_background(token
, container
, bg
))
613 images
.push_back(bg
.m_image
[0]);
614 repeats
.push_back(bg
.m_repeat
[0]);
615 origins
.push_back(bg
.m_origin
[0]);
616 clips
.push_back(bg
.m_clip
[0]);
617 attachments
.push_back(bg
.m_attachment
[0]);
618 x_positions
.push_back(bg
.m_position_x
[0]);
619 y_positions
.push_back(bg
.m_position_y
[0]);
620 sizes
.push_back(bg
.m_size
[0]);
623 add_parsed_property(_background_color_
, property_value(color
, important
));
624 add_parsed_property(_background_image_
, property_value(images
, important
));
625 add_parsed_property(_background_image_baseurl_
, property_value(baseurl
, important
));
626 add_parsed_property(_background_repeat_
, property_value(repeats
, important
));
627 add_parsed_property(_background_origin_
, property_value(origins
, important
));
628 add_parsed_property(_background_clip_
, property_value(clips
, important
));
629 add_parsed_property(_background_attachment_
, property_value(attachments
, important
));
630 add_parsed_property(_background_position_x_
, property_value(x_positions
, important
));
631 add_parsed_property(_background_position_y_
, property_value(y_positions
, important
));
632 add_parsed_property(_background_size_
, property_value(sizes
, important
));
635 bool style::parse_one_background(const string
& val
, document_container
* container
, background
& bg
)
637 bg
.m_color
= web_color::transparent
;
639 bg
.m_repeat
= { background_repeat_repeat
};
640 bg
.m_origin
= { background_box_padding
};
641 bg
.m_clip
= { background_box_border
};
642 bg
.m_attachment
= { background_attachment_scroll
};
643 bg
.m_position_x
= { css_length(0, css_units_percentage
) };
644 bg
.m_position_y
= { css_length(0, css_units_percentage
) };
645 bg
.m_size
= { css_size(css_length::predef_value(background_size_auto
), css_length::predef_value(background_size_auto
)) };
652 string_vector tokens
;
653 split_string(val
, tokens
, " \t\n\r", "", "(");
655 bool color_found
= false;
656 bool image_found
= false;
657 bool origin_found
= false;
658 bool clip_found
= false;
659 bool repeat_found
= false;
660 bool attachment_found
= false;
663 for(const auto& token
: tokens
)
666 if(token
.substr(0, 3) == "url")
668 if (image_found
) return false;
670 css::parse_css_url(token
, url
);
671 bg
.m_image
= { url
};
673 } else if( (idx
= value_index(token
, background_repeat_strings
)) >= 0 )
675 if (repeat_found
) return false;
676 bg
.m_repeat
= { idx
};
678 } else if( (idx
= value_index(token
, background_attachment_strings
)) >= 0 )
680 if (attachment_found
) return false;
681 bg
.m_attachment
= { idx
};
682 attachment_found
= true;
683 } else if( (idx
= value_index(token
, background_box_strings
)) >= 0 )
687 bg
.m_origin
= { idx
};
691 if (clip_found
) return false;
695 } else if( value_in_list(token
, background_position_strings
) ||
696 token
.find('/') != -1 ||
697 t_isdigit(token
[0]) ||
702 position
+= " " + token
;
703 } else if (web_color::is_color(token
, container
))
705 if (color_found
) return false;
706 bg
.m_color
= web_color::from_string(token
, container
);
717 string_vector tokens
;
718 split_string(position
, tokens
, "/");
720 if (tokens
.size() > 2) return false;
722 if (tokens
.size() == 2 && !parse_one_background_size(tokens
[1], bg
.m_size
[0]))
725 if (tokens
.size() > 0 && !parse_one_background_position(tokens
[0], bg
.m_position_x
[0], bg
.m_position_y
[0]))
732 void style::parse_background_image(const string
& val
, const string
& baseurl
, bool important
)
734 string_vector tokens
;
735 split_string(val
, tokens
, ",", "", "(");
736 if (tokens
.empty()) return;
738 string_vector images
;
740 for (const auto& token
: tokens
)
743 css::parse_css_url(token
, url
);
744 images
.push_back(url
);
747 add_parsed_property(_background_image_
, property_value(images
, important
));
748 add_parsed_property(_background_image_baseurl_
, property_value(baseurl
, important
));
751 void style::parse_keyword_comma_list(string_id name
, const string
& val
, bool important
)
753 string_vector tokens
;
754 split_string(val
, tokens
, ",");
755 if (tokens
.empty()) return;
759 for (auto& token
: tokens
)
762 int idx
= value_index(token
, m_valid_values
[name
]);
763 if (idx
== -1) return;
767 add_parsed_property(name
, property_value(vec
, important
));
770 void style::parse_background_position(const string
& val
, bool important
)
772 string_vector tokens
;
773 split_string(val
, tokens
, ",");
774 if (tokens
.empty()) return;
776 length_vector x_positions
, y_positions
;
778 for (const auto& token
: tokens
)
781 if(!parse_one_background_position(token
, x
, y
)) return;
782 x_positions
.push_back(x
);
783 y_positions
.push_back(y
);
786 add_parsed_property(_background_position_x_
, property_value(x_positions
, important
));
787 add_parsed_property(_background_position_y_
, property_value(y_positions
, important
));
790 bool style::parse_one_background_position(const string
& val
, css_length
& x
, css_length
& y
)
793 split_string(val
, pos
, " \t");
795 if (pos
.empty() || pos
.size() > 2)
802 if (value_in_list(pos
[0], "left;right;center"))
804 x
.fromString(pos
[0], "left;right;center");
805 y
.set_value(50, css_units_percentage
);
807 else if (value_in_list(pos
[0], "top;bottom;center"))
809 y
.fromString(pos
[0], "top;bottom;center");
810 x
.set_value(50, css_units_percentage
);
814 x
.fromString(pos
[0], "left;right;center");
815 y
.set_value(50, css_units_percentage
);
818 else if (pos
.size() == 2)
820 if (value_in_list(pos
[0], "left;right"))
822 x
.fromString(pos
[0], "left;right;center");
823 y
.fromString(pos
[1], "top;bottom;center");
825 else if (value_in_list(pos
[0], "top;bottom"))
827 x
.fromString(pos
[1], "left;right;center");
828 y
.fromString(pos
[0], "top;bottom;center");
830 else if (value_in_list(pos
[1], "left;right"))
832 x
.fromString(pos
[1], "left;right;center");
833 y
.fromString(pos
[0], "top;bottom;center");
835 else if (value_in_list(pos
[1], "top;bottom"))
837 x
.fromString(pos
[0], "left;right;center");
838 y
.fromString(pos
[1], "top;bottom;center");
842 x
.fromString(pos
[0], "left;right;center");
843 y
.fromString(pos
[1], "top;bottom;center");
847 if (x
.is_predefined())
852 x
.set_value(0, css_units_percentage
);
855 x
.set_value(100, css_units_percentage
);
858 x
.set_value(50, css_units_percentage
);
862 if (y
.is_predefined())
867 y
.set_value(0, css_units_percentage
);
870 y
.set_value(100, css_units_percentage
);
873 y
.set_value(50, css_units_percentage
);
880 void style::parse_background_size(const string
& val
, bool important
)
882 string_vector tokens
;
883 split_string(val
, tokens
, ",");
884 if (tokens
.empty()) return;
888 for (const auto& token
: tokens
)
891 if (!parse_one_background_size(token
, size
)) return;
892 sizes
.push_back(size
);
895 add_parsed_property(_background_size_
, property_value(sizes
, important
));
898 bool style::parse_one_background_size(const string
& val
, css_size
& size
)
901 split_string(val
, res
, " \t");
907 size
.width
.fromString(res
[0], background_size_strings
);
910 size
.height
.fromString(res
[1], background_size_strings
);
914 size
.height
.predef(background_size_auto
);
919 void style::parse_font(const string
& val
, bool important
)
921 if (val
== "inherit")
923 add_parsed_property(_font_style_
, property_value(important
, prop_type_inherit
));
924 add_parsed_property(_font_variant_
, property_value(important
, prop_type_inherit
));
925 add_parsed_property(_font_weight_
, property_value(important
, prop_type_inherit
));
926 add_parsed_property(_font_size_
, property_value(important
, prop_type_inherit
));
927 add_parsed_property(_line_height_
, property_value(important
, prop_type_inherit
));
931 add_parsed_property(_font_style_
, property_value(font_style_normal
, important
));
932 add_parsed_property(_font_variant_
, property_value(font_variant_normal
, important
));
933 add_parsed_property(_font_weight_
, property_value(font_weight_normal
, important
));
934 add_parsed_property(_font_size_
, property_value(font_size_medium
, important
));
935 add_parsed_property(_line_height_
, property_value(line_height_normal
, important
));
938 string_vector tokens
;
939 split_string(val
, tokens
, " ", "", "\"");
942 bool is_family
= false;
944 for(const auto& token
: tokens
)
948 font_family
+= token
;
952 if((idx
= value_index(token
, font_style_strings
)) >= 0)
956 add_parsed_property(_font_style_
, property_value(font_style_normal
, important
));
957 add_parsed_property(_font_variant_
, property_value(font_variant_normal
, important
));
958 add_parsed_property(_font_weight_
, property_value(font_weight_normal
, important
));
961 add_parsed_property(_font_style_
, property_value(idx
, important
));
963 } else if((idx
= value_index(token
, font_weight_strings
)) >= 0)
965 add_parsed_property(_font_weight_
, property_value(idx
, important
));
966 } else if((idx
= value_index(token
, font_variant_strings
)) >= 0)
968 add_parsed_property(_font_variant_
, property_value(idx
, important
));
970 else if(t_isdigit(token
[0]) || token
[0] == '.' ||
971 value_in_list(token
, font_size_strings
) || token
.find('/') != -1)
974 split_string(token
, szlh
, "/");
976 auto size
= css_length::from_string(szlh
[0], font_size_strings
, -1);
977 add_parsed_property(_font_size_
, property_value(size
, important
));
981 auto height
= css_length::from_string(szlh
[1], "normal", -1);
982 add_parsed_property(_line_height_
, property_value(height
, important
));
987 font_family
+= token
;
990 add_parsed_property(_font_family_
, property_value(font_family
, important
));
993 void style::parse_flex(const string
& val
, bool important
)
995 auto is_number
= [](const string
& val
)
999 if ((ch
< '0' || ch
> '9') && ch
!= '.')
1007 css_length _auto
= css_length::predef_value(flex_basis_auto
);
1009 if (val
== "initial")
1012 add_parsed_property(_flex_grow_
, property_value(0.f
, important
));
1013 add_parsed_property(_flex_shrink_
, property_value(1.f
, important
));
1014 add_parsed_property(_flex_basis_
, property_value(_auto
, important
));
1016 else if (val
== "auto")
1019 add_parsed_property(_flex_grow_
, property_value(1.f
, important
));
1020 add_parsed_property(_flex_shrink_
, property_value(1.f
, important
));
1021 add_parsed_property(_flex_basis_
, property_value(_auto
, important
));
1023 else if (val
== "none")
1026 add_parsed_property(_flex_grow_
, property_value(0.f
, important
));
1027 add_parsed_property(_flex_shrink_
, property_value(0.f
, important
));
1028 add_parsed_property(_flex_basis_
, property_value(_auto
, important
));
1032 string_vector tokens
;
1033 split_string(val
, tokens
, " ");
1034 if (tokens
.size() == 3)
1036 float grow
= t_strtof(tokens
[0]);
1037 float shrink
= t_strtof(tokens
[1]);
1038 auto basis
= css_length::from_string(tokens
[2], flex_basis_strings
, -1);
1040 add_parsed_property(_flex_grow_
, property_value(grow
, important
));
1041 add_parsed_property(_flex_shrink_
, property_value(shrink
, important
));
1042 add_parsed_property(_flex_basis_
, property_value(basis
, important
));
1044 else if (tokens
.size() == 2)
1046 float grow
= t_strtof(tokens
[0]);
1047 add_parsed_property(_flex_grow_
, property_value(grow
, important
));
1049 if (is_number(tokens
[1]))
1051 float shrink
= t_strtof(tokens
[1]);
1052 add_parsed_property(_flex_shrink_
, property_value(shrink
, important
));
1056 auto basis
= css_length::from_string(tokens
[1], flex_basis_strings
, -1);
1057 add_parsed_property(_flex_basis_
, property_value(basis
, important
));
1060 else if (tokens
.size() == 1)
1062 if (is_number(tokens
[0]))
1064 float grow
= t_strtof(tokens
[0]);
1065 add_parsed_property(_flex_grow_
, property_value(grow
, important
));
1069 add_parsed_property(_flex_shrink_
, property_value(1.f
, important
));
1070 add_parsed_property(_flex_basis_
, property_value(css_length(0), important
));
1075 auto basis
= css_length::from_string(tokens
[0], flex_basis_strings
, -1);
1076 add_parsed_property(_flex_basis_
, property_value(basis
, important
));
1082 void style::add_parsed_property( string_id name
, const property_value
& propval
)
1084 auto prop
= m_properties
.find(name
);
1085 if (prop
!= m_properties
.end())
1087 if (!prop
->second
.m_important
|| (propval
.m_important
&& prop
->second
.m_important
))
1089 prop
->second
= propval
;
1094 m_properties
[name
] = propval
;
1098 void style::remove_property( string_id name
, bool important
)
1100 auto prop
= m_properties
.find(name
);
1101 if(prop
!= m_properties
.end())
1103 if( !prop
->second
.m_important
|| (important
&& prop
->second
.m_important
) )
1105 m_properties
.erase(prop
);
1110 void style::combine(const style
& src
)
1112 for (const auto& property
: src
.m_properties
)
1114 add_parsed_property(property
.first
, property
.second
);
1118 const property_value
& style::get_property(string_id name
) const
1120 auto it
= m_properties
.find(name
);
1121 if (it
!= m_properties
.end())
1125 static property_value dummy
;
1129 void style::subst_vars_(string
& str
, const element
* el
)
1133 auto start
= str
.find("var(");
1134 if (start
== -1) break;
1135 if (start
> 0 && isalnum(str
[start
- 1])) break;
1136 auto end
= str
.find(")", start
+ 4);
1137 if (end
== -1) break;
1138 auto name
= str
.substr(start
+ 4, end
- start
- 4);
1140 string val
= el
->get_custom_property(_id(name
), "");
1141 str
.replace(start
, end
- start
+ 1, val
);
1145 void style::subst_vars(const element
* el
)
1147 for (auto& prop
: m_properties
)
1149 if (prop
.second
.m_type
== prop_type_var
)
1151 subst_vars_(prop
.second
.m_string
, el
);
1152 // re-adding the same property
1153 // if it is a custom property it will be readded as a string (currently it is prop_type_var)
1154 // if it is a standard css property it will be parsed and properly added as typed property
1155 add_property(prop
.first
, prop
.second
.m_string
, "", prop
.second
.m_important
, el
->get_document()->container());
1160 } // namespace litehtml