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_items_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_
:
131 case _align_content_
:
135 idx
= value_index(val
, m_valid_values
[name
]);
138 add_parsed_property(name
, property_value(idx
, important
));
144 parse_align_self(name
, val
, important
);
150 case _padding_right_
:
152 case _padding_bottom_
:
153 length
.fromString(val
);
154 add_parsed_property(name
, property_value(length
, important
));
162 case _z_index_
: // <integer> | auto
170 case _margin_bottom_
:
171 length
.fromString(val
, "auto", -1);
172 add_parsed_property(name
, property_value(length
, important
));
178 length
.fromString(val
, "none", -1);
179 add_parsed_property(name
, property_value(length
, important
));
183 length
.fromString(val
, "normal", -1);
184 add_parsed_property(name
, property_value(length
, important
));
188 length
.fromString(val
, font_size_strings
, -1);
189 add_parsed_property(name
, property_value(length
, important
));
192 // Parse background shorthand properties
194 parse_background(val
, baseurl
, important
, container
);
197 case _background_image_
:
198 parse_background_image(val
, baseurl
, important
);
201 case _background_attachment_
:
202 case _background_repeat_
:
203 case _background_clip_
:
204 case _background_origin_
:
205 parse_keyword_comma_list(name
, val
, important
);
208 case _background_position_
:
209 parse_background_position(val
, important
);
212 case _background_size_
:
213 parse_background_size(val
, important
);
216 // Parse border spacing properties
217 case _border_spacing_
:
218 parse_two_lengths(val
, len
);
219 add_parsed_property(__litehtml_border_spacing_x_
, property_value(len
[0], important
));
220 add_parsed_property(__litehtml_border_spacing_y_
, property_value(len
[1], important
));
223 // Parse borders shorthand properties
226 string_vector tokens
;
227 split_string(val
, tokens
, " ", "", "(");
228 for (const auto& token
: tokens
)
230 int idx
= value_index(token
, border_style_strings
);
233 property_value
style(idx
, important
);
234 add_parsed_property(_border_left_style_
, style
);
235 add_parsed_property(_border_right_style_
, style
);
236 add_parsed_property(_border_top_style_
, style
);
237 add_parsed_property(_border_bottom_style_
, style
);
239 else if (t_isdigit(token
[0]) || token
[0] == '.' ||
240 value_in_list(token
, border_width_strings
))
242 property_value
width(parse_border_width(token
), important
);
243 add_parsed_property(_border_left_width_
, width
);
244 add_parsed_property(_border_right_width_
, width
);
245 add_parsed_property(_border_top_width_
, width
);
246 add_parsed_property(_border_bottom_width_
, width
);
248 else if (web_color::is_color(token
, container
))
250 web_color _color
= web_color::from_string(token
, container
);
251 property_value
color(_color
, important
);
252 add_parsed_property(_border_left_color_
, color
);
253 add_parsed_property(_border_right_color_
, color
);
254 add_parsed_property(_border_top_color_
, color
);
255 add_parsed_property(_border_bottom_color_
, color
);
264 case _border_bottom_
:
266 string_vector tokens
;
267 split_string(val
, tokens
, " ", "", "(");
268 for (const auto& token
: tokens
)
270 int idx
= value_index(token
, border_style_strings
);
273 add_parsed_property(_id(_s(name
) + "-style"), property_value(idx
, important
));
275 else if (t_isdigit(token
[0]) || token
[0] == '.' ||
276 value_in_list(token
, border_width_strings
))
278 property_value
width(parse_border_width(token
), important
);
279 add_parsed_property(_id(_s(name
) + "-width"), width
);
281 else if (web_color::is_color(token
, container
))
283 web_color color
= web_color::from_string(token
, container
);
284 add_parsed_property(_id(_s(name
) + "-color"), property_value(color
, important
));
290 // Parse border-width/style/color shorthand properties
295 string prop
= name
== _border_width_
? "-width" : name
== _border_style_
? "-style" : "-color";
297 string_vector tokens
;
298 split_string(val
, tokens
, " ");
299 if (tokens
.size() == 4)
301 add_property(_id("border-top" + prop
), tokens
[0], baseurl
, important
, container
);
302 add_property(_id("border-right" + prop
), tokens
[1], baseurl
, important
, container
);
303 add_property(_id("border-bottom" + prop
), tokens
[2], baseurl
, important
, container
);
304 add_property(_id("border-left" + prop
), tokens
[3], baseurl
, important
, container
);
306 else if (tokens
.size() == 3)
308 add_property(_id("border-top" + prop
), tokens
[0], baseurl
, important
, container
);
309 add_property(_id("border-right" + prop
), tokens
[1], baseurl
, important
, container
);
310 add_property(_id("border-left" + prop
), tokens
[1], baseurl
, important
, container
);
311 add_property(_id("border-bottom" + prop
), tokens
[2], baseurl
, important
, container
);
313 else if (tokens
.size() == 2)
315 add_property(_id("border-top" + prop
), tokens
[0], baseurl
, important
, container
);
316 add_property(_id("border-bottom" + prop
), tokens
[0], baseurl
, important
, container
);
317 add_property(_id("border-right" + prop
), tokens
[1], baseurl
, important
, container
);
318 add_property(_id("border-left" + prop
), tokens
[1], baseurl
, important
, container
);
320 else if (tokens
.size() == 1)
322 add_property(_id("border-top" + prop
), tokens
[0], baseurl
, important
, container
);
323 add_property(_id("border-bottom" + prop
), tokens
[0], baseurl
, important
, container
);
324 add_property(_id("border-right" + prop
), tokens
[0], baseurl
, important
, container
);
325 add_property(_id("border-left" + prop
), tokens
[0], baseurl
, important
, container
);
330 case _border_top_width_
:
331 case _border_bottom_width_
:
332 case _border_left_width_
:
333 case _border_right_width_
:
334 length
= parse_border_width(val
);
335 add_parsed_property(name
, property_value(length
, important
));
339 case _background_color_
:
340 case _border_top_color_
:
341 case _border_bottom_color_
:
342 case _border_left_color_
:
343 case _border_right_color_
:
344 if (web_color::is_color(val
, container
))
346 web_color color
= web_color::from_string(val
, container
);
347 add_parsed_property(name
, property_value(color
, important
));
351 // Parse border radius shorthand properties
352 case _border_bottom_left_radius_
:
353 case _border_bottom_right_radius_
:
354 case _border_top_right_radius_
:
355 case _border_top_left_radius_
:
356 parse_two_lengths(val
, len
);
357 add_parsed_property(_id(_s(name
) + "-x"), property_value(len
[0], important
));
358 add_parsed_property(_id(_s(name
) + "-y"), property_value(len
[1], important
));
361 // Parse border-radius shorthand properties
362 case _border_radius_
:
364 string_vector tokens
;
365 split_string(val
, tokens
, "/");
366 if (tokens
.size() == 1)
368 add_property(_border_radius_x_
, tokens
[0], baseurl
, important
, container
);
369 add_property(_border_radius_y_
, tokens
[0], baseurl
, important
, container
);
371 else if (tokens
.size() >= 2)
373 add_property(_border_radius_x_
, tokens
[0], baseurl
, important
, container
);
374 add_property(_border_radius_y_
, tokens
[1], baseurl
, important
, container
);
378 case _border_radius_x_
:
379 case _border_radius_y_
:
381 string_id top_left
, top_right
, bottom_right
, bottom_left
;
382 if (name
== _border_radius_x_
)
384 top_left
= _border_top_left_radius_x_
;
385 top_right
= _border_top_right_radius_x_
;
386 bottom_right
= _border_bottom_right_radius_x_
;
387 bottom_left
= _border_bottom_left_radius_x_
;
391 top_left
= _border_top_left_radius_y_
;
392 top_right
= _border_top_right_radius_y_
;
393 bottom_right
= _border_bottom_right_radius_y_
;
394 bottom_left
= _border_bottom_left_radius_y_
;
397 switch (parse_four_lengths(val
, len
))
400 add_parsed_property(top_left
, property_value(len
[0], important
));
401 add_parsed_property(top_right
, property_value(len
[0], important
));
402 add_parsed_property(bottom_right
, property_value(len
[0], important
));
403 add_parsed_property(bottom_left
, property_value(len
[0], important
));
406 add_parsed_property(top_left
, property_value(len
[0], important
));
407 add_parsed_property(top_right
, property_value(len
[1], important
));
408 add_parsed_property(bottom_right
, property_value(len
[0], important
));
409 add_parsed_property(bottom_left
, property_value(len
[1], important
));
412 add_parsed_property(top_left
, property_value(len
[0], important
));
413 add_parsed_property(top_right
, property_value(len
[1], important
));
414 add_parsed_property(bottom_right
, property_value(len
[2], important
));
415 add_parsed_property(bottom_left
, property_value(len
[1], important
));
418 add_parsed_property(top_left
, property_value(len
[0], important
));
419 add_parsed_property(top_right
, property_value(len
[1], important
));
420 add_parsed_property(bottom_right
, property_value(len
[2], important
));
421 add_parsed_property(bottom_left
, property_value(len
[3], important
));
427 // Parse list-style shorthand properties
430 add_parsed_property(_list_style_type_
, property_value(list_style_type_disc
, important
));
431 add_parsed_property(_list_style_position_
, property_value(list_style_position_outside
, important
));
432 add_parsed_property(_list_style_image_
, property_value("", important
));
433 add_parsed_property(_list_style_image_baseurl_
, property_value("", important
));
435 string_vector tokens
;
436 split_string(val
, tokens
, " ", "", "(");
437 for (const auto& token
: tokens
)
439 int idx
= value_index(token
, list_style_type_strings
);
442 add_parsed_property(_list_style_type_
, property_value(idx
, important
));
446 idx
= value_index(token
, list_style_position_strings
);
449 add_parsed_property(_list_style_position_
, property_value(idx
, important
));
451 else if (!strncmp(token
.c_str(), "url", 3))
453 css::parse_css_url(token
, url
);
454 add_parsed_property(_list_style_image_
, property_value(url
, important
));
455 add_parsed_property(_list_style_image_baseurl_
, property_value(baseurl
, important
));
462 case _list_style_image_
:
463 css::parse_css_url(val
, url
);
464 add_parsed_property(_list_style_image_
, property_value(url
, important
));
465 add_parsed_property(_list_style_image_baseurl_
, property_value(baseurl
, important
));
468 // Parse margin and padding shorthand properties
472 switch (parse_four_lengths(val
, len
))
475 add_parsed_property(_id(_s(name
) + "-top"), property_value(len
[0], important
));
476 add_parsed_property(_id(_s(name
) + "-right"), property_value(len
[1], important
));
477 add_parsed_property(_id(_s(name
) + "-bottom"), property_value(len
[2], important
));
478 add_parsed_property(_id(_s(name
) + "-left"), property_value(len
[3], important
));
481 add_parsed_property(_id(_s(name
) + "-top"), property_value(len
[0], important
));
482 add_parsed_property(_id(_s(name
) + "-right"), property_value(len
[1], important
));
483 add_parsed_property(_id(_s(name
) + "-left"), property_value(len
[1], important
));
484 add_parsed_property(_id(_s(name
) + "-bottom"), property_value(len
[2], important
));
487 add_parsed_property(_id(_s(name
) + "-top"), property_value(len
[0], important
));
488 add_parsed_property(_id(_s(name
) + "-bottom"), property_value(len
[0], important
));
489 add_parsed_property(_id(_s(name
) + "-right"), property_value(len
[1], important
));
490 add_parsed_property(_id(_s(name
) + "-left"), property_value(len
[1], important
));
493 add_parsed_property(_id(_s(name
) + "-top"), property_value(len
[0], important
));
494 add_parsed_property(_id(_s(name
) + "-bottom"), property_value(len
[0], important
));
495 add_parsed_property(_id(_s(name
) + "-right"), property_value(len
[0], important
));
496 add_parsed_property(_id(_s(name
) + "-left"), property_value(len
[0], important
));
502 // Parse font shorthand properties
504 parse_font(val
, important
);
507 // Parse flex-flow shorthand properties
510 string_vector tokens
;
511 split_string(val
, tokens
, " ");
512 for (const auto& tok
: tokens
)
515 if ((idx
= value_index(tok
, flex_direction_strings
)) >= 0)
517 add_parsed_property(_flex_direction_
, property_value(idx
, important
));
519 else if ((idx
= value_index(tok
, flex_wrap_strings
)) >= 0)
521 add_parsed_property(_flex_wrap_
, property_value(idx
, important
));
527 // Parse flex shorthand properties
529 parse_flex(val
, important
);
534 add_parsed_property(name
, property_value(t_strtof(val
), important
));
538 length
.fromString(val
, flex_basis_strings
, -1);
539 add_parsed_property(_flex_basis_
, property_value(length
, important
));
542 case _order_
: // <integer>
545 int int_val
= (int) strtol(val
.c_str(), &end
, 10);
548 add_parsed_property(name
, property_value(int_val
, important
));
552 case _counter_increment_
:
553 case _counter_reset_
:
555 string_vector tokens
;
556 split_string(val
, tokens
, " ");
557 add_parsed_property(name
, property_value(tokens
, important
));
562 add_parsed_property(name
, property_value(val
, important
));
566 css_length
style::parse_border_width(const string
& str
)
569 if (t_isdigit(str
[0]) || str
[0] == '.')
575 int idx
= value_index(str
, border_width_strings
);
578 len
.set_value(border_width_values
[idx
], css_units_px
);
584 void style::parse_two_lengths(const string
& str
, css_length len
[2])
586 string_vector tokens
;
587 split_string(str
, tokens
, " ");
588 if (tokens
.size() == 1)
591 length
.fromString(tokens
[0]);
592 len
[0] = len
[1] = length
;
594 else if (tokens
.size() == 2)
596 len
[0].fromString(tokens
[0]);
597 len
[1].fromString(tokens
[1]);
601 int style::parse_four_lengths(const string
& str
, css_length len
[4])
603 string_vector tokens
;
604 split_string(str
, tokens
, " ");
605 if (tokens
.size() == 0 || tokens
.size() > 4)
609 for (size_t i
= 0; i
< tokens
.size(); i
++)
611 len
[i
].fromString(tokens
[i
]);
613 return (int)tokens
.size();
616 void style::parse_background(const string
& val
, const string
& baseurl
, bool important
, document_container
* container
)
618 string_vector tokens
;
619 split_string(val
, tokens
, ",", "", "(");
620 if (tokens
.empty()) return;
623 string_vector images
;
624 int_vector repeats
, origins
, clips
, attachments
;
625 length_vector x_positions
, y_positions
;
628 for (const auto& token
: tokens
)
631 if (!parse_one_background(token
, container
, bg
))
635 images
.push_back(bg
.m_image
[0]);
636 repeats
.push_back(bg
.m_repeat
[0]);
637 origins
.push_back(bg
.m_origin
[0]);
638 clips
.push_back(bg
.m_clip
[0]);
639 attachments
.push_back(bg
.m_attachment
[0]);
640 x_positions
.push_back(bg
.m_position_x
[0]);
641 y_positions
.push_back(bg
.m_position_y
[0]);
642 sizes
.push_back(bg
.m_size
[0]);
645 add_parsed_property(_background_color_
, property_value(color
, important
));
646 add_parsed_property(_background_image_
, property_value(images
, important
));
647 add_parsed_property(_background_image_baseurl_
, property_value(baseurl
, important
));
648 add_parsed_property(_background_repeat_
, property_value(repeats
, important
));
649 add_parsed_property(_background_origin_
, property_value(origins
, important
));
650 add_parsed_property(_background_clip_
, property_value(clips
, important
));
651 add_parsed_property(_background_attachment_
, property_value(attachments
, important
));
652 add_parsed_property(_background_position_x_
, property_value(x_positions
, important
));
653 add_parsed_property(_background_position_y_
, property_value(y_positions
, important
));
654 add_parsed_property(_background_size_
, property_value(sizes
, important
));
657 bool style::parse_one_background(const string
& val
, document_container
* container
, background
& bg
)
659 bg
.m_color
= web_color::transparent
;
661 bg
.m_repeat
= { background_repeat_repeat
};
662 bg
.m_origin
= { background_box_padding
};
663 bg
.m_clip
= { background_box_border
};
664 bg
.m_attachment
= { background_attachment_scroll
};
665 bg
.m_position_x
= { css_length(0, css_units_percentage
) };
666 bg
.m_position_y
= { css_length(0, css_units_percentage
) };
667 bg
.m_size
= { css_size(css_length::predef_value(background_size_auto
), css_length::predef_value(background_size_auto
)) };
674 string_vector tokens
;
675 split_string(val
, tokens
, " \t\n\r", "", "(");
677 bool color_found
= false;
678 bool image_found
= false;
679 bool origin_found
= false;
680 bool clip_found
= false;
681 bool repeat_found
= false;
682 bool attachment_found
= false;
685 for(const auto& token
: tokens
)
688 if(token
.substr(0, 3) == "url")
690 if (image_found
) return false;
692 css::parse_css_url(token
, url
);
693 bg
.m_image
= { url
};
695 } else if( (idx
= value_index(token
, background_repeat_strings
)) >= 0 )
697 if (repeat_found
) return false;
698 bg
.m_repeat
= { idx
};
700 } else if( (idx
= value_index(token
, background_attachment_strings
)) >= 0 )
702 if (attachment_found
) return false;
703 bg
.m_attachment
= { idx
};
704 attachment_found
= true;
705 } else if( (idx
= value_index(token
, background_box_strings
)) >= 0 )
709 bg
.m_origin
= { idx
};
713 if (clip_found
) return false;
717 } else if( value_in_list(token
, background_position_strings
) ||
718 token
.find('/') != -1 ||
719 t_isdigit(token
[0]) ||
724 position
+= " " + token
;
725 } else if (web_color::is_color(token
, container
))
727 if (color_found
) return false;
728 bg
.m_color
= web_color::from_string(token
, container
);
739 string_vector tokens
;
740 split_string(position
, tokens
, "/");
742 if (tokens
.size() > 2) return false;
744 if (tokens
.size() == 2 && !parse_one_background_size(tokens
[1], bg
.m_size
[0]))
747 if (tokens
.size() > 0 && !parse_one_background_position(tokens
[0], bg
.m_position_x
[0], bg
.m_position_y
[0]))
754 void style::parse_background_image(const string
& val
, const string
& baseurl
, bool important
)
756 string_vector tokens
;
757 split_string(val
, tokens
, ",", "", "(");
758 if (tokens
.empty()) return;
760 string_vector images
;
762 for (const auto& token
: tokens
)
765 css::parse_css_url(token
, url
);
766 images
.push_back(url
);
769 add_parsed_property(_background_image_
, property_value(images
, important
));
770 add_parsed_property(_background_image_baseurl_
, property_value(baseurl
, important
));
773 void style::parse_keyword_comma_list(string_id name
, const string
& val
, bool important
)
775 string_vector tokens
;
776 split_string(val
, tokens
, ",");
777 if (tokens
.empty()) return;
781 for (auto& token
: tokens
)
784 int idx
= value_index(token
, m_valid_values
[name
]);
785 if (idx
== -1) return;
789 add_parsed_property(name
, property_value(vec
, important
));
792 void style::parse_background_position(const string
& val
, bool important
)
794 string_vector tokens
;
795 split_string(val
, tokens
, ",");
796 if (tokens
.empty()) return;
798 length_vector x_positions
, y_positions
;
800 for (const auto& token
: tokens
)
803 if(!parse_one_background_position(token
, x
, y
)) return;
804 x_positions
.push_back(x
);
805 y_positions
.push_back(y
);
808 add_parsed_property(_background_position_x_
, property_value(x_positions
, important
));
809 add_parsed_property(_background_position_y_
, property_value(y_positions
, important
));
812 bool style::parse_one_background_position(const string
& val
, css_length
& x
, css_length
& y
)
815 split_string(val
, pos
, " \t");
817 if (pos
.empty() || pos
.size() > 2)
824 if (value_in_list(pos
[0], "left;right;center"))
826 x
.fromString(pos
[0], "left;right;center");
827 y
.set_value(50, css_units_percentage
);
829 else if (value_in_list(pos
[0], "top;bottom;center"))
831 y
.fromString(pos
[0], "top;bottom;center");
832 x
.set_value(50, css_units_percentage
);
836 x
.fromString(pos
[0], "left;right;center");
837 y
.set_value(50, css_units_percentage
);
840 else if (pos
.size() == 2)
842 if (value_in_list(pos
[0], "left;right"))
844 x
.fromString(pos
[0], "left;right;center");
845 y
.fromString(pos
[1], "top;bottom;center");
847 else if (value_in_list(pos
[0], "top;bottom"))
849 x
.fromString(pos
[1], "left;right;center");
850 y
.fromString(pos
[0], "top;bottom;center");
852 else if (value_in_list(pos
[1], "left;right"))
854 x
.fromString(pos
[1], "left;right;center");
855 y
.fromString(pos
[0], "top;bottom;center");
857 else if (value_in_list(pos
[1], "top;bottom"))
859 x
.fromString(pos
[0], "left;right;center");
860 y
.fromString(pos
[1], "top;bottom;center");
864 x
.fromString(pos
[0], "left;right;center");
865 y
.fromString(pos
[1], "top;bottom;center");
869 if (x
.is_predefined())
874 x
.set_value(0, css_units_percentage
);
877 x
.set_value(100, css_units_percentage
);
880 x
.set_value(50, css_units_percentage
);
884 if (y
.is_predefined())
889 y
.set_value(0, css_units_percentage
);
892 y
.set_value(100, css_units_percentage
);
895 y
.set_value(50, css_units_percentage
);
902 void style::parse_background_size(const string
& val
, bool important
)
904 string_vector tokens
;
905 split_string(val
, tokens
, ",");
906 if (tokens
.empty()) return;
910 for (const auto& token
: tokens
)
913 if (!parse_one_background_size(token
, size
)) return;
914 sizes
.push_back(size
);
917 add_parsed_property(_background_size_
, property_value(sizes
, important
));
920 bool style::parse_one_background_size(const string
& val
, css_size
& size
)
923 split_string(val
, res
, " \t");
929 size
.width
.fromString(res
[0], background_size_strings
);
932 size
.height
.fromString(res
[1], background_size_strings
);
936 size
.height
.predef(background_size_auto
);
941 void style::parse_font(const string
& val
, bool important
)
943 if (val
== "inherit")
945 add_parsed_property(_font_style_
, property_value(important
, prop_type_inherit
));
946 add_parsed_property(_font_variant_
, property_value(important
, prop_type_inherit
));
947 add_parsed_property(_font_weight_
, property_value(important
, prop_type_inherit
));
948 add_parsed_property(_font_size_
, property_value(important
, prop_type_inherit
));
949 add_parsed_property(_line_height_
, property_value(important
, prop_type_inherit
));
953 add_parsed_property(_font_style_
, property_value(font_style_normal
, important
));
954 add_parsed_property(_font_variant_
, property_value(font_variant_normal
, important
));
955 add_parsed_property(_font_weight_
, property_value(font_weight_normal
, important
));
956 add_parsed_property(_font_size_
, property_value(font_size_medium
, important
));
957 add_parsed_property(_line_height_
, property_value(line_height_normal
, important
));
960 string_vector tokens
;
961 split_string(val
, tokens
, " ", "", "\"");
964 bool is_family
= false;
966 for(const auto& token
: tokens
)
970 font_family
+= token
;
974 if((idx
= value_index(token
, font_style_strings
)) >= 0)
978 add_parsed_property(_font_style_
, property_value(font_style_normal
, important
));
979 add_parsed_property(_font_variant_
, property_value(font_variant_normal
, important
));
980 add_parsed_property(_font_weight_
, property_value(font_weight_normal
, important
));
983 add_parsed_property(_font_style_
, property_value(idx
, important
));
985 } else if((idx
= value_index(token
, font_weight_strings
)) >= 0)
987 add_parsed_property(_font_weight_
, property_value(idx
, important
));
988 } else if((idx
= value_index(token
, font_variant_strings
)) >= 0)
990 add_parsed_property(_font_variant_
, property_value(idx
, important
));
992 else if(t_isdigit(token
[0]) || token
[0] == '.' ||
993 value_in_list(token
, font_size_strings
) || token
.find('/') != -1)
996 split_string(token
, szlh
, "/");
999 auto size
= css_length::from_string(szlh
[0], font_size_strings
, -1);
1000 add_parsed_property(_font_size_
, property_value(size
, important
));
1002 if (szlh
.size() == 2)
1004 auto height
= css_length::from_string(szlh
[1], "normal", -1);
1005 add_parsed_property(_line_height_
, property_value(height
, important
));
1011 font_family
+= token
;
1014 add_parsed_property(_font_family_
, property_value(font_family
, important
));
1017 void style::parse_flex(const string
& val
, bool important
)
1019 css_length _auto
= css_length::predef_value(flex_basis_auto
);
1021 if (val
== "initial")
1024 add_parsed_property(_flex_grow_
, property_value(0.f
, important
));
1025 add_parsed_property(_flex_shrink_
, property_value(1.f
, important
));
1026 add_parsed_property(_flex_basis_
, property_value(_auto
, important
));
1028 else if (val
== "auto")
1031 add_parsed_property(_flex_grow_
, property_value(1.f
, important
));
1032 add_parsed_property(_flex_shrink_
, property_value(1.f
, important
));
1033 add_parsed_property(_flex_basis_
, property_value(_auto
, important
));
1035 else if (val
== "none")
1038 add_parsed_property(_flex_grow_
, property_value(0.f
, important
));
1039 add_parsed_property(_flex_shrink_
, property_value(0.f
, important
));
1040 add_parsed_property(_flex_basis_
, property_value(_auto
, important
));
1044 string_vector tokens
;
1045 split_string(val
, tokens
, " ");
1046 if (tokens
.size() == 3)
1048 float grow
= t_strtof(tokens
[0]);
1049 float shrink
= t_strtof(tokens
[1]);
1050 auto basis
= css_length::from_string(tokens
[2], flex_basis_strings
, -1);
1051 if(!basis
.is_predefined() && basis
.units() == css_units_none
&& basis
.val() == 0)
1053 basis
.set_value(basis
.val(), css_units_px
);
1056 add_parsed_property(_flex_grow_
, property_value(grow
, important
));
1057 add_parsed_property(_flex_shrink_
, property_value(shrink
, important
));
1058 add_parsed_property(_flex_basis_
, property_value(basis
, important
));
1060 else if (tokens
.size() == 2)
1062 float grow
= t_strtof(tokens
[0]);
1063 add_parsed_property(_flex_grow_
, property_value(grow
, important
));
1065 if (litehtml::is_number(tokens
[1]))
1067 float shrink
= t_strtof(tokens
[1]);
1068 add_parsed_property(_flex_shrink_
, property_value(shrink
, important
));
1069 add_parsed_property(_flex_basis_
, property_value(css_length(0), important
));
1073 auto basis
= css_length::from_string(tokens
[1], flex_basis_strings
, -1);
1074 add_parsed_property(_flex_basis_
, property_value(basis
, important
));
1077 else if (tokens
.size() == 1)
1079 if (is_number(tokens
[0]))
1081 float grow
= t_strtof(tokens
[0]);
1082 add_parsed_property(_flex_grow_
, property_value(grow
, important
));
1083 add_parsed_property(_flex_shrink_
, property_value(1.f
, important
));
1084 add_parsed_property(_flex_basis_
, property_value(css_length(0), important
));
1088 auto basis
= css_length::from_string(tokens
[0], flex_basis_strings
, -1);
1089 add_parsed_property(_flex_grow_
, property_value(1.f
, important
));
1090 add_parsed_property(_flex_shrink_
, property_value(1.f
, important
));
1091 add_parsed_property(_flex_basis_
, property_value(basis
, important
));
1097 void style::parse_align_self(string_id name
, const string
& val
, bool important
)
1099 string_vector tokens
;
1100 split_string(val
, tokens
, " ");
1101 if(tokens
.size() == 1)
1103 int idx
= value_index(val
, m_valid_values
[name
]);
1106 add_parsed_property(name
, property_value(idx
, important
));
1112 for(auto &token
: tokens
)
1114 if(token
== "first")
1116 val1
|= flex_align_items_first
;
1117 } else if(token
== "last")
1119 val1
|= flex_align_items_last
;
1120 } else if(token
== "safe")
1122 val1
|= flex_align_items_safe
;
1123 } else if(token
== "unsafe")
1125 val1
|= flex_align_items_unsafe
;
1128 int idx
= value_index(token
, m_valid_values
[name
]);
1137 add_parsed_property(name
, property_value(val1
| val2
, important
));
1142 void style::add_parsed_property( string_id name
, const property_value
& propval
)
1144 auto prop
= m_properties
.find(name
);
1145 if (prop
!= m_properties
.end())
1147 if (!prop
->second
.m_important
|| (propval
.m_important
&& prop
->second
.m_important
))
1149 prop
->second
= propval
;
1154 m_properties
[name
] = propval
;
1158 void style::remove_property( string_id name
, bool important
)
1160 auto prop
= m_properties
.find(name
);
1161 if(prop
!= m_properties
.end())
1163 if( !prop
->second
.m_important
|| (important
&& prop
->second
.m_important
) )
1165 m_properties
.erase(prop
);
1170 void style::combine(const style
& src
)
1172 for (const auto& property
: src
.m_properties
)
1174 add_parsed_property(property
.first
, property
.second
);
1178 const property_value
& style::get_property(string_id name
) const
1180 auto it
= m_properties
.find(name
);
1181 if (it
!= m_properties
.end())
1185 static property_value dummy
;
1189 void style::subst_vars_(string
& str
, const element
* el
)
1193 auto start
= str
.find("var(");
1194 if (start
== -1) break;
1195 if (start
> 0 && isalnum(str
[start
- 1])) break;
1196 auto end
= str
.find(")", start
+ 4);
1197 if (end
== -1) break;
1198 auto name
= str
.substr(start
+ 4, end
- start
- 4);
1200 string val
= el
->get_custom_property(_id(name
), "");
1201 str
.replace(start
, end
- start
+ 1, val
);
1205 void style::subst_vars(const element
* el
)
1207 for (auto& prop
: m_properties
)
1209 if (prop
.second
.m_type
== prop_type_var
)
1211 subst_vars_(prop
.second
.m_string
, el
);
1212 // re-adding the same property
1213 // if it is a custom property it will be readded as a string (currently it is prop_type_var)
1214 // if it is a standard css property it will be parsed and properly added as typed property
1215 add_property(prop
.first
, prop
.second
.m_string
, "", prop
.second
.m_important
, el
->get_document()->container());
1220 } // namespace litehtml