summaryrefslogtreecommitdiff
path: root/libs/litehtml
diff options
context:
space:
mode:
Diffstat (limited to 'libs/litehtml')
-rw-r--r--libs/litehtml/include/litehtml.h1
-rw-r--r--libs/litehtml/include/litehtml/codepoint.h4
-rw-r--r--libs/litehtml/include/litehtml/css_parser.h1
-rw-r--r--libs/litehtml/include/litehtml/css_properties.h111
-rw-r--r--libs/litehtml/include/litehtml/css_selector.h3
-rw-r--r--libs/litehtml/include/litehtml/css_tokenizer.h31
-rw-r--r--libs/litehtml/include/litehtml/document.h25
-rw-r--r--libs/litehtml/include/litehtml/document_container.h9
-rw-r--r--libs/litehtml/include/litehtml/el_cdata.h2
-rw-r--r--libs/litehtml/include/litehtml/el_comment.h2
-rw-r--r--libs/litehtml/include/litehtml/el_image.h1
-rw-r--r--libs/litehtml/include/litehtml/el_script.h2
-rw-r--r--libs/litehtml/include/litehtml/el_space.h1
-rw-r--r--libs/litehtml/include/litehtml/el_style.h3
-rw-r--r--libs/litehtml/include/litehtml/el_text.h3
-rw-r--r--libs/litehtml/include/litehtml/element.h13
-rw-r--r--libs/litehtml/include/litehtml/encodings.h1
-rw-r--r--libs/litehtml/include/litehtml/flex_item.h2
-rw-r--r--libs/litehtml/include/litehtml/font_description.h45
-rw-r--r--libs/litehtml/include/litehtml/gradient.h11
-rw-r--r--libs/litehtml/include/litehtml/html.h24
-rw-r--r--libs/litehtml/include/litehtml/html_microsyntaxes.h20
-rw-r--r--libs/litehtml/include/litehtml/html_tag.h4
-rw-r--r--libs/litehtml/include/litehtml/iterators.h3
-rw-r--r--libs/litehtml/include/litehtml/line_box.h36
-rw-r--r--libs/litehtml/include/litehtml/media_query.h10
-rw-r--r--libs/litehtml/include/litehtml/render_item.h9
-rw-r--r--libs/litehtml/include/litehtml/string_id.h15
-rw-r--r--libs/litehtml/include/litehtml/style.h24
-rw-r--r--libs/litehtml/include/litehtml/stylesheet.h3
-rw-r--r--libs/litehtml/include/litehtml/tstring_view.h2
-rw-r--r--libs/litehtml/include/litehtml/types.h163
-rw-r--r--libs/litehtml/include/litehtml/url.h2
-rw-r--r--libs/litehtml/include/litehtml/url_path.h2
-rw-r--r--libs/litehtml/include/litehtml/web_color.h3
-rw-r--r--libs/litehtml/src/background.cpp5
-rw-r--r--libs/litehtml/src/css_parser.cpp92
-rw-r--r--libs/litehtml/src/css_properties.cpp126
-rw-r--r--libs/litehtml/src/css_selector.cpp32
-rw-r--r--libs/litehtml/src/css_tokenizer.cpp39
-rw-r--r--libs/litehtml/src/document.cpp159
-rw-r--r--libs/litehtml/src/document_container.cpp2
-rw-r--r--libs/litehtml/src/el_anchor.cpp2
-rw-r--r--libs/litehtml/src/el_base.cpp4
-rw-r--r--libs/litehtml/src/el_body.cpp1
-rw-r--r--libs/litehtml/src/el_break.cpp1
-rw-r--r--libs/litehtml/src/el_cdata.cpp1
-rw-r--r--libs/litehtml/src/el_comment.cpp1
-rw-r--r--libs/litehtml/src/el_div.cpp2
-rw-r--r--libs/litehtml/src/el_font.cpp2
-rw-r--r--libs/litehtml/src/el_image.cpp4
-rw-r--r--libs/litehtml/src/el_link.cpp4
-rw-r--r--libs/litehtml/src/el_para.cpp1
-rw-r--r--libs/litehtml/src/el_script.cpp1
-rw-r--r--libs/litehtml/src/el_style.cpp14
-rw-r--r--libs/litehtml/src/el_table.cpp79
-rw-r--r--libs/litehtml/src/el_td.cpp2
-rw-r--r--libs/litehtml/src/el_text.cpp3
-rw-r--r--libs/litehtml/src/el_title.cpp2
-rw-r--r--libs/litehtml/src/el_tr.cpp2
-rw-r--r--libs/litehtml/src/element.cpp6
-rw-r--r--libs/litehtml/src/encodings.cpp4
-rw-r--r--libs/litehtml/src/flex_item.cpp4
-rw-r--r--libs/litehtml/src/flex_line.cpp2
-rw-r--r--libs/litehtml/src/formatting_context.cpp1
-rw-r--r--libs/litehtml/src/gumbo/CMakeLists.txt2
-rw-r--r--libs/litehtml/src/gumbo/char_ref.c2
-rw-r--r--libs/litehtml/src/gumbo/char_ref.rl2
-rw-r--r--libs/litehtml/src/gumbo/include/gumbo.h5
-rw-r--r--libs/litehtml/src/gumbo/include/gumbo/tag_enum.h1
-rw-r--r--libs/litehtml/src/gumbo/include/gumbo/tag_gperf.h352
-rw-r--r--libs/litehtml/src/gumbo/include/gumbo/tag_sizes.h2
-rw-r--r--libs/litehtml/src/gumbo/include/gumbo/tag_strings.h1
-rw-r--r--libs/litehtml/src/gumbo/parser.c218
-rw-r--r--libs/litehtml/src/html_microsyntaxes.cpp1
-rw-r--r--libs/litehtml/src/html_tag.cpp33
-rw-r--r--libs/litehtml/src/iterators.cpp3
-rw-r--r--libs/litehtml/src/line_box.cpp404
-rw-r--r--libs/litehtml/src/media_query.cpp36
-rw-r--r--libs/litehtml/src/render_block.cpp5
-rw-r--r--libs/litehtml/src/render_block_context.cpp1
-rw-r--r--libs/litehtml/src/render_flex.cpp2
-rw-r--r--libs/litehtml/src/render_image.cpp3
-rw-r--r--libs/litehtml/src/render_inline_context.cpp7
-rw-r--r--libs/litehtml/src/render_item.cpp65
-rw-r--r--libs/litehtml/src/render_table.cpp1
-rw-r--r--libs/litehtml/src/string_id.cpp8
-rw-r--r--libs/litehtml/src/style.cpp223
-rw-r--r--libs/litehtml/src/stylesheet.cpp12
-rw-r--r--libs/litehtml/src/url.cpp1
-rw-r--r--libs/litehtml/src/utf8_strings.cpp3
-rw-r--r--libs/litehtml/src/web_color.cpp22
92 files changed, 1588 insertions, 1016 deletions
diff --git a/libs/litehtml/include/litehtml.h b/libs/litehtml/include/litehtml.h
index 2537aee839..5687703dff 100644
--- a/libs/litehtml/include/litehtml.h
+++ b/libs/litehtml/include/litehtml.h
@@ -7,5 +7,6 @@
#include <litehtml/stylesheet.h>
#include <litehtml/element.h>
#include <litehtml/utf8_strings.h>
+#include <litehtml/document_container.h>
#endif // LITEHTML_H
diff --git a/libs/litehtml/include/litehtml/codepoint.h b/libs/litehtml/include/litehtml/codepoint.h
index 52dd495559..3e06e86e00 100644
--- a/libs/litehtml/include/litehtml/codepoint.h
+++ b/libs/litehtml/include/litehtml/codepoint.h
@@ -30,10 +30,6 @@
#ifndef LITEHTML_CODEPOINT_H__
#define LITEHTML_CODEPOINT_H__
-#include <string>
-
-#include "os_types.h"
-
namespace litehtml {
bool is_ascii_codepoint(char c);
diff --git a/libs/litehtml/include/litehtml/css_parser.h b/libs/litehtml/include/litehtml/css_parser.h
index cbd88e3b84..eb49099fb9 100644
--- a/libs/litehtml/include/litehtml/css_parser.h
+++ b/libs/litehtml/include/litehtml/css_parser.h
@@ -3,6 +3,7 @@
#include "css_tokenizer.h"
#include "stylesheet.h"
+#include <functional>
namespace litehtml
{
diff --git a/libs/litehtml/include/litehtml/css_properties.h b/libs/litehtml/include/litehtml/css_properties.h
index b7f8e7e784..a904b9cced 100644
--- a/libs/litehtml/include/litehtml/css_properties.h
+++ b/libs/litehtml/include/litehtml/css_properties.h
@@ -1,7 +1,7 @@
#ifndef LITEHTML_CSS_PROPERTIES_H
#define LITEHTML_CSS_PROPERTIES_H
-#include "os_types.h"
+#include "string_id.h"
#include "types.h"
#include "css_margins.h"
#include "borders.h"
@@ -13,6 +13,19 @@ namespace litehtml
class html_tag;
class document;
+ template<class CssT, class CompT>
+ class css_property
+ {
+ public:
+ CssT css_value;
+ CompT computed_value;
+
+ css_property(const CssT& css_val, const CompT& computed_val) : css_value(css_val), computed_value(computed_val) {}
+ };
+
+ // CSS Properties types
+ using css_line_height_t = css_property<css_length, int>;
+
class css_properties
{
private:
@@ -22,6 +35,7 @@ namespace litehtml
white_space m_white_space;
style_display m_display;
visibility m_visibility;
+ appearance m_appearance;
box_sizing m_box_sizing;
css_length m_z_index;
vertical_align m_vertical_align;
@@ -39,7 +53,7 @@ namespace litehtml
css_offsets m_css_offsets;
css_length m_css_text_indent;
css_length m_css_line_height;
- int m_line_height;
+ css_line_height_t m_line_height {{}, 0};
list_style_type m_list_style_type;
list_style_position m_list_style_position;
string m_list_style_image;
@@ -50,7 +64,13 @@ namespace litehtml
string m_font_family;
css_length m_font_weight;
font_style m_font_style;
- string m_text_decoration;
+ int m_text_decoration_line = text_decoration_line_none;
+ text_decoration_style m_text_decoration_style = text_decoration_style_solid;
+ css_length m_text_decoration_thickness;
+ web_color m_text_decoration_color;
+ string m_text_emphasis_style;
+ web_color m_text_emphasis_color;
+ int m_text_emphasis_position;
font_metrics m_font_metrics;
text_transform m_text_transform;
web_color m_color;
@@ -88,6 +108,7 @@ namespace litehtml
m_white_space(white_space_normal),
m_display(display_inline),
m_visibility(visibility_visible),
+ m_appearance(appearance_none),
m_box_sizing(box_sizing_content_box),
m_z_index(0),
m_vertical_align(va_baseline),
@@ -105,7 +126,6 @@ namespace litehtml
m_css_offsets(),
m_css_text_indent(),
m_css_line_height(0),
- m_line_height(0),
m_list_style_type(list_style_type_none),
m_list_style_position(list_style_position_outside),
m_bg(),
@@ -148,6 +168,9 @@ namespace litehtml
visibility get_visibility() const;
void set_visibility(visibility mVisibility);
+ appearance get_appearance() const;
+ void set_appearance(appearance mAppearance);
+
box_sizing get_box_sizing() const;
void set_box_sizing(box_sizing mBoxSizing);
@@ -196,8 +219,8 @@ namespace litehtml
const css_length &get_text_indent() const;
void set_text_indent(const css_length &mCssTextIndent);
- int get_line_height() const;
- void set_line_height(int mLineHeight);
+ const css_line_height_t& line_height() const;
+ css_line_height_t& line_height_w();
list_style_type get_list_style_type() const;
void set_list_style_type(list_style_type mListStyleType);
@@ -205,10 +228,10 @@ namespace litehtml
list_style_position get_list_style_position() const;
void set_list_style_position(list_style_position mListStylePosition);
- string get_list_style_image() const;
+ const string& get_list_style_image() const;
void set_list_style_image(const string& url);
- string get_list_style_image_baseurl() const;
+ const string& get_list_style_image_baseurl() const;
void set_list_style_image_baseurl(const string& url);
const background &get_bg() const;
@@ -229,10 +252,10 @@ namespace litehtml
web_color get_color() const;
void set_color(web_color color);
- string get_cursor() const;
+ const string& get_cursor() const;
void set_cursor(const string& cursor);
- string get_content() const;
+ const string& get_content() const;
void set_content(const string& content);
border_collapse get_border_collapse() const;
@@ -259,6 +282,15 @@ namespace litehtml
int get_order() const;
void set_order(int order);
+
+ int get_text_decoration_line() const;
+ text_decoration_style get_text_decoration_style() const;
+ const css_length& get_text_decoration_thickness() const;
+ const web_color& get_text_decoration_color() const;
+
+ string get_text_emphasis_style() const;
+ web_color get_text_emphasis_color() const;
+ int get_text_emphasis_position() const;
};
inline element_position css_properties::get_position() const
@@ -321,6 +353,16 @@ namespace litehtml
m_visibility = mVisibility;
}
+ inline appearance css_properties::get_appearance() const
+ {
+ return m_appearance;
+ }
+
+ inline void css_properties::set_appearance(appearance mAppearance)
+ {
+ m_appearance = mAppearance;
+ }
+
inline box_sizing css_properties::get_box_sizing() const
{
return m_box_sizing;
@@ -481,14 +523,14 @@ namespace litehtml
m_css_text_indent = mCssTextIndent;
}
- inline int css_properties::get_line_height() const
+ inline const css_line_height_t& css_properties::line_height() const
{
return m_line_height;
}
- inline void css_properties::set_line_height(int mLineHeight)
+ inline css_line_height_t& css_properties::line_height_w()
{
- m_line_height = mLineHeight;
+ return m_line_height;
}
inline list_style_type css_properties::get_list_style_type() const
@@ -511,10 +553,10 @@ namespace litehtml
m_list_style_position = mListStylePosition;
}
- inline string css_properties::get_list_style_image() const { return m_list_style_image; }
+ inline const string& css_properties::get_list_style_image() const { return m_list_style_image; }
inline void css_properties::set_list_style_image(const string& url) { m_list_style_image = url; }
- inline string css_properties::get_list_style_image_baseurl() const { return m_list_style_image_baseurl; }
+ inline const string& css_properties::get_list_style_image_baseurl() const { return m_list_style_image_baseurl; }
inline void css_properties::set_list_style_image_baseurl(const string& url) { m_list_style_image_baseurl = url; }
inline const background &css_properties::get_bg() const
@@ -570,10 +612,10 @@ namespace litehtml
inline web_color css_properties::get_color() const { return m_color; }
inline void css_properties::set_color(web_color color) { m_color = color; }
- inline string css_properties::get_cursor() const { return m_cursor; }
+ inline const string& css_properties::get_cursor() const { return m_cursor; }
inline void css_properties::set_cursor(const string& cursor) { m_cursor = cursor; }
- inline string css_properties::get_content() const { return m_content; }
+ inline const string& css_properties::get_content() const { return m_content; }
inline void css_properties::set_content(const string& content) { m_content = content; }
inline border_collapse css_properties::get_border_collapse() const
@@ -669,6 +711,41 @@ namespace litehtml
{
m_order = order;
}
+
+ inline int css_properties::get_text_decoration_line() const
+ {
+ return m_text_decoration_line;
+ }
+
+ inline text_decoration_style css_properties::get_text_decoration_style() const
+ {
+ return m_text_decoration_style;
+ }
+
+ inline const css_length& css_properties::get_text_decoration_thickness() const
+ {
+ return m_text_decoration_thickness;
+ }
+
+ inline const web_color& css_properties::get_text_decoration_color() const
+ {
+ return m_text_decoration_color;
+ }
+
+ inline string css_properties::get_text_emphasis_style() const
+ {
+ return m_text_emphasis_style;
+ }
+
+ inline web_color css_properties::get_text_emphasis_color() const
+ {
+ return m_text_emphasis_color;
+ }
+
+ inline int css_properties::get_text_emphasis_position() const
+ {
+ return m_text_emphasis_position;
+ }
}
#endif //LITEHTML_CSS_PROPERTIES_H
diff --git a/libs/litehtml/include/litehtml/css_selector.h b/libs/litehtml/include/litehtml/css_selector.h
index 042f1691e4..57aa2846b5 100644
--- a/libs/litehtml/include/litehtml/css_selector.h
+++ b/libs/litehtml/include/litehtml/css_selector.h
@@ -1,6 +1,7 @@
#ifndef LH_CSS_SELECTOR_H
#define LH_CSS_SELECTOR_H
+#include "string_id.h"
#include "style.h"
#include "media_query.h"
#include "css_tokenizer.h"
@@ -154,7 +155,7 @@ namespace litehtml
string_id prefix; // [prefix|name]
string_id name; // .name, #name, [name], :name
string value; // [name=value], :lang(value)
-
+
attr_matcher matcher; // <attr-matcher> = ~= |= ^= $= *=
bool caseless_match; // value is matched ASCII case-insensitively
diff --git a/libs/litehtml/include/litehtml/css_tokenizer.h b/libs/litehtml/include/litehtml/css_tokenizer.h
index 119c925c79..f4a61af49c 100644
--- a/libs/litehtml/include/litehtml/css_tokenizer.h
+++ b/libs/litehtml/include/litehtml/css_tokenizer.h
@@ -1,6 +1,9 @@
#ifndef LH_CSS_TOKENIZER_H
#define LH_CSS_TOKENIZER_H
+#include "types.h"
+#include <cstdio>
+
namespace litehtml
{
@@ -11,7 +14,7 @@ namespace litehtml
enum css_token_type
{
WHITESPACE = ' ',
-
+
// Giving EOF and some chars explicit names to facilitate debugging and to get rid of warning C4063: case '41' is not a valid value for switch of enum 'litehtml::css_token_type'
_EOF = EOF,
LEFT_BRACE = '{',
@@ -26,7 +29,7 @@ enum css_token_type
BANG = '!',
DOT = '.',
AMPERSAND = '&',
-
+
IDENT = -20, // do not collide with any unicode chars
FUNCTION, // calc(
AT_KEYWORD, // @media
@@ -62,12 +65,12 @@ enum css_hash_type
};
// css_token: CSS token or component value ("fat" token)
-// Tokens exist in uncomponentized form only a short time after tokenization, most of the time they are "fat".
+// Tokens exist in uncomponentized form only a short time after tokenization, most of the time they are "fat".
// All functions in css_parser work regardless of whether tokens are fat or not, as per standard.
// All functions outside of css_parser that parse media queries, selectors, property values assume tokens are componentized.
struct css_token
{
- css_token(css_token_type type = css_token_type(),
+ css_token(css_token_type type = css_token_type(),
float number = 0, css_number_type number_type = css_number_integer, string str = "")
: type(type), str(str), n{number, number_type}
{
@@ -87,13 +90,13 @@ struct css_token
case HASH:
hash_type = token.hash_type;
break;
-
+
case NUMBER:
case PERCENTAGE:
case DIMENSION:
n = token.n;
break;
-
+
case CV_FUNCTION:
case CURLY_BLOCK:
case ROUND_BLOCK:
@@ -104,17 +107,17 @@ struct css_token
default:;
}
}
-
+
css_token& operator=(const css_token& token)
{
this->~css_token();
new(this) css_token(token);
return *this;
}
-
+
~css_token()
- {
- str.~string();
+ {
+ str.~string();
if (is_component_value()) value.~vector();
}
@@ -132,7 +135,7 @@ struct css_token
};
union {
string str; // STRING, URL
- string name; // HASH, IDENT, AT_KEYWORD, FUNCTION, CV_FUNCTION
+ string name; // HASH, IDENT, AT_KEYWORD, FUNCTION, CV_FUNCTION
string unit; // DIMENSION
};
struct number {
@@ -144,7 +147,7 @@ struct css_token
number n;
vector<css_token> value; // CV_FUNCTION, XXX_BLOCK
};
-
+
string repr; // https://www.w3.org/TR/css-syntax-3/#representation
};
@@ -155,7 +158,7 @@ class css_tokenizer
{
public:
css_tokenizer(const string& input) : str(input), index(0), current_char(0) {}
-
+
css_token_vector tokenize();
private:
@@ -188,7 +191,7 @@ private:
void consume_comments();
int consume_escaped_code_point();
css_token consume_string_token(int ending_code_point);
-
+
static bool would_start_ident_sequence(three_chars chars);
string consume_ident_sequence();
diff --git a/libs/litehtml/include/litehtml/document.h b/libs/litehtml/include/litehtml/document.h
index 7119636ffe..9be8465411 100644
--- a/libs/litehtml/include/litehtml/document.h
+++ b/libs/litehtml/include/litehtml/document.h
@@ -1,10 +1,12 @@
#ifndef LH_DOCUMENT_H
#define LH_DOCUMENT_H
-#include "style.h"
+#include "stylesheet.h"
#include "types.h"
#include "master_css.h"
#include "encodings.h"
+#include "font_description.h"
+
typedef struct GumboInternalOutput GumboOutput;
namespace litehtml
@@ -16,7 +18,7 @@ namespace litehtml
string text;
string baseurl;
string media;
-
+
css_text() = default;
css_text(const char* txt, const char* url, const char* media_str)
@@ -50,6 +52,7 @@ namespace litehtml
std::shared_ptr<element> m_root;
std::shared_ptr<render_item> m_root_render;
document_container* m_container;
+ fonts_map m_fonts;
css_text::vector m_css;
litehtml::css m_styles;
litehtml::web_color m_def_color;
@@ -58,7 +61,8 @@ namespace litehtml
litehtml::size m_size;
litehtml::size m_content_size;
position::vector m_fixed_boxes;
- element::ptr m_over_element;
+ std::shared_ptr<element> m_over_element;
+ std::shared_ptr<element> m_active_element;
std::list<shared_ptr<render_item>> m_tabular_elements;
media_query_list_list::vector m_media_lists;
media_features m_media;
@@ -72,7 +76,7 @@ namespace litehtml
document_container* container() { return m_container; }
document_mode mode() const { return m_mode; }
- uint_ptr get_font(const char* name, int size, const char* weight, const char* style, const char* decoration, font_metrics* fm);
+ uint_ptr get_font(const font_description& descr, font_metrics* fm);
int render(int max_width, render_type rt = render_all);
void draw(uint_ptr hdc, int x, int y, const position* clip);
web_color get_def_color() { return m_def_color; }
@@ -86,9 +90,10 @@ namespace litehtml
bool on_mouse_over(int x, int y, int client_x, int client_y, position::vector& redraw_boxes);
bool on_lbutton_down(int x, int y, int client_x, int client_y, position::vector& redraw_boxes);
bool on_lbutton_up(int x, int y, int client_x, int client_y, position::vector& redraw_boxes);
+ bool on_button_cancel(position::vector& redraw_boxes);
bool on_mouse_leave(position::vector& redraw_boxes);
- element::ptr create_element(const char* tag_name, const string_map& attributes);
- element::ptr root();
+ std::shared_ptr<element> create_element(const char* tag_name, const string_map& attributes);
+ std::shared_ptr<element> root();
std::shared_ptr<render_item> root_render();
void get_fixed_boxes(position::vector& fixed_boxes);
void add_fixed_box(const position& pos);
@@ -97,7 +102,7 @@ namespace litehtml
bool lang_changed();
bool match_lang(const string& lang);
void add_tabular(const std::shared_ptr<render_item>& el);
- element::const_ptr get_over_element() const { return m_over_element; }
+ std::shared_ptr<const element> get_over_element() const { return m_over_element; }
void append_children_from_string(element& parent, const char* str);
void dump(dumper& cout);
@@ -108,9 +113,9 @@ namespace litehtml
document_container* container,
const string& master_styles = litehtml::master_css,
const string& user_styles = "");
-
+
private:
- uint_ptr add_font(const char* name, int size, const char* weight, const char* style, const char* decoration, font_metrics* fm);
+ uint_ptr add_font(const font_description& descr, font_metrics* fm);
GumboOutput* parse_html(estring str);
void create_node(void* gnode, elements_list& elements, bool parseTextNode);
@@ -120,7 +125,7 @@ namespace litehtml
void fix_table_parent(const std::shared_ptr<render_item> & el_ptr, style_display disp, const char* disp_str);
};
- inline element::ptr document::root()
+ inline std::shared_ptr<element> document::root()
{
return m_root;
}
diff --git a/libs/litehtml/include/litehtml/document_container.h b/libs/litehtml/include/litehtml/document_container.h
index 95efe1eb6b..47cdc4b9d3 100644
--- a/libs/litehtml/include/litehtml/document_container.h
+++ b/libs/litehtml/include/litehtml/document_container.h
@@ -1,12 +1,12 @@
#ifndef LH_DOCUMENT_CONTAINER_H
#define LH_DOCUMENT_CONTAINER_H
-#include "os_types.h"
#include "types.h"
#include "web_color.h"
#include "background.h"
#include "borders.h"
#include "element.h"
+#include "font_description.h"
#include <memory>
#include <functional>
@@ -22,7 +22,7 @@ namespace litehtml
int index;
uint_ptr font;
};
-
+
enum mouse_event
{
mouse_event_enter,
@@ -35,7 +35,7 @@ namespace litehtml
public:
fonts_map m_fonts;
- virtual litehtml::uint_ptr create_font(const char* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) = 0;
+ virtual litehtml::uint_ptr create_font(const font_description& descr, const document* doc, litehtml::font_metrics* fm) = 0;
virtual void delete_font(litehtml::uint_ptr hFont) = 0;
virtual int text_width(const char* text, litehtml::uint_ptr hFont) = 0;
virtual void draw_text(litehtml::uint_ptr hdc, const char* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) = 0;
@@ -56,13 +56,14 @@ namespace litehtml
virtual void set_base_url(const char* base_url) = 0;
virtual void link(const std::shared_ptr<litehtml::document>& doc, const litehtml::element::ptr& el) = 0;
virtual void on_anchor_click(const char* url, const litehtml::element::ptr& el) = 0;
+ virtual bool on_element_click(const litehtml::element::ptr& /*el*/) { return false; };
virtual void on_mouse_event(const litehtml::element::ptr& el, litehtml::mouse_event event) = 0;
virtual void set_cursor(const char* cursor) = 0;
virtual void transform_text(litehtml::string& text, litehtml::text_transform tt) = 0;
virtual void import_css(litehtml::string& text, const litehtml::string& url, litehtml::string& baseurl) = 0;
virtual void set_clip(const litehtml::position& pos, const litehtml::border_radiuses& bdr_radius) = 0;
virtual void del_clip() = 0;
- virtual void get_client_rect(litehtml::position& client) const = 0;
+ virtual void get_viewport(litehtml::position& viewport) const = 0;
virtual litehtml::element::ptr create_element( const char* tag_name,
const litehtml::string_map& attributes,
const std::shared_ptr<litehtml::document>& doc) = 0;
diff --git a/libs/litehtml/include/litehtml/el_cdata.h b/libs/litehtml/include/litehtml/el_cdata.h
index 838cd92b1e..3e9db43b88 100644
--- a/libs/litehtml/include/litehtml/el_cdata.h
+++ b/libs/litehtml/include/litehtml/el_cdata.h
@@ -1,7 +1,7 @@
#ifndef LH_EL_CDATA_H
#define LH_EL_CDATA_H
-#include "html_tag.h"
+#include "element.h"
namespace litehtml
{
diff --git a/libs/litehtml/include/litehtml/el_comment.h b/libs/litehtml/include/litehtml/el_comment.h
index 379318ffbe..fa8e72fc91 100644
--- a/libs/litehtml/include/litehtml/el_comment.h
+++ b/libs/litehtml/include/litehtml/el_comment.h
@@ -1,7 +1,7 @@
#ifndef LH_EL_COMMENT_H
#define LH_EL_COMMENT_H
-#include "html_tag.h"
+#include "element.h"
namespace litehtml
{
diff --git a/libs/litehtml/include/litehtml/el_image.h b/libs/litehtml/include/litehtml/el_image.h
index 2b73940815..b67de11941 100644
--- a/libs/litehtml/include/litehtml/el_image.h
+++ b/libs/litehtml/include/litehtml/el_image.h
@@ -2,6 +2,7 @@
#define LH_EL_IMAGE_H
#include "html_tag.h"
+#include "document.h"
namespace litehtml
{
diff --git a/libs/litehtml/include/litehtml/el_script.h b/libs/litehtml/include/litehtml/el_script.h
index e0a0374057..0353b15796 100644
--- a/libs/litehtml/include/litehtml/el_script.h
+++ b/libs/litehtml/include/litehtml/el_script.h
@@ -1,7 +1,7 @@
#ifndef LH_EL_SCRIPT_H
#define LH_EL_SCRIPT_H
-#include "html_tag.h"
+#include "element.h"
namespace litehtml
{
diff --git a/libs/litehtml/include/litehtml/el_space.h b/libs/litehtml/include/litehtml/el_space.h
index 53c170f13a..6d447f7103 100644
--- a/libs/litehtml/include/litehtml/el_space.h
+++ b/libs/litehtml/include/litehtml/el_space.h
@@ -1,7 +1,6 @@
#ifndef LH_EL_SPACE_H
#define LH_EL_SPACE_H
-#include "html_tag.h"
#include "el_text.h"
namespace litehtml
diff --git a/libs/litehtml/include/litehtml/el_style.h b/libs/litehtml/include/litehtml/el_style.h
index 62f1546259..60c0b50c67 100644
--- a/libs/litehtml/include/litehtml/el_style.h
+++ b/libs/litehtml/include/litehtml/el_style.h
@@ -1,7 +1,7 @@
#ifndef LH_EL_STYLE_H
#define LH_EL_STYLE_H
-#include "html_tag.h"
+#include "element.h"
namespace litehtml
{
@@ -13,6 +13,7 @@ namespace litehtml
void parse_attributes() override;
bool appendChild(const ptr &el) override;
+ void compute_styles(bool recursive) override;
string_id tag() const override;
const char* get_tagName() const override;
};
diff --git a/libs/litehtml/include/litehtml/el_text.h b/libs/litehtml/include/litehtml/el_text.h
index ea54cc9c66..f3da930825 100644
--- a/libs/litehtml/include/litehtml/el_text.h
+++ b/libs/litehtml/include/litehtml/el_text.h
@@ -1,7 +1,8 @@
#ifndef LH_EL_TEXT_H
#define LH_EL_TEXT_H
-#include "html_tag.h"
+#include "element.h"
+#include "document.h"
namespace litehtml
{
diff --git a/libs/litehtml/include/litehtml/element.h b/libs/litehtml/include/litehtml/element.h
index 67dd1ae251..d18976c9f0 100644
--- a/libs/litehtml/include/litehtml/element.h
+++ b/libs/litehtml/include/litehtml/element.h
@@ -1,12 +1,12 @@
#ifndef LH_ELEMENT_H
#define LH_ELEMENT_H
+#include <functional>
#include <memory>
#include <tuple>
#include <list>
+#include "types.h"
#include "stylesheet.h"
-#include "css_offsets.h"
-#include "css_margins.h"
#include "css_properties.h"
namespace litehtml
@@ -94,7 +94,7 @@ namespace litehtml
virtual bool on_mouse_over();
virtual bool on_mouse_leave();
virtual bool on_lbutton_down();
- virtual bool on_lbutton_up();
+ virtual bool on_lbutton_up(bool is_click = true);
virtual void on_click();
virtual bool set_pseudo_class(string_id cls, bool add);
virtual bool set_class(const char* pclass, bool add);
@@ -155,7 +155,9 @@ namespace litehtml
inline bool litehtml::element::in_normal_flow() const
{
- if(css().get_position() != element_position_absolute && css().get_display() != display_none)
+ if(css().get_position() != element_position_absolute &&
+ css().get_display() != display_none &&
+ css().get_position() != element_position_fixed)
{
return true;
}
@@ -207,8 +209,7 @@ namespace litehtml
if (css().get_display() == display_block ||
css().get_display() == display_flex ||
css().get_display() == display_table ||
- css().get_display() == display_list_item ||
- css().get_display() == display_flex)
+ css().get_display() == display_list_item)
{
return true;
}
diff --git a/libs/litehtml/include/litehtml/encodings.h b/libs/litehtml/include/litehtml/encodings.h
index 2dd9d5e0f5..ec5cb03e83 100644
--- a/libs/litehtml/include/litehtml/encodings.h
+++ b/libs/litehtml/include/litehtml/encodings.h
@@ -1,6 +1,7 @@
#ifndef LH_ENCODINGS_H
#define LH_ENCODINGS_H
+#include "types.h"
namespace litehtml
{
diff --git a/libs/litehtml/include/litehtml/flex_item.h b/libs/litehtml/include/litehtml/flex_item.h
index 0c4244ae2d..4ad53ac11a 100644
--- a/libs/litehtml/include/litehtml/flex_item.h
+++ b/libs/litehtml/include/litehtml/flex_item.h
@@ -1,8 +1,8 @@
#ifndef LITEHTML_FLEX_ITEM_H
#define LITEHTML_FLEX_ITEM_H
-#include <functional>
#include "formatting_context.h"
+#include "render_item.h"
namespace litehtml
{
diff --git a/libs/litehtml/include/litehtml/font_description.h b/libs/litehtml/include/litehtml/font_description.h
new file mode 100644
index 0000000000..c4c3ee7224
--- /dev/null
+++ b/libs/litehtml/include/litehtml/font_description.h
@@ -0,0 +1,45 @@
+#ifndef LITEHTML_FONT_DESCRIPTION
+#define LITEHTML_FONT_DESCRIPTION
+
+#include <string>
+#include "types.h"
+#include "css_length.h"
+#include "web_color.h"
+
+namespace litehtml
+{
+ struct font_description
+ {
+ std::string family; // Font Family
+ int size = 0; // Font size
+ font_style style = font_style_normal; // Font stype, see the enum font_style
+ int weight; // Font weight.
+ int decoration_line = text_decoration_line_none; // Decoration line. A bitset of flags of the enum text_decoration_line
+ css_length decoration_thickness; // Decoration line thickness in pixels. See predefined values in enumtext_decoration_thickness
+ text_decoration_style decoration_style = text_decoration_style_solid; // Decoration line style. See enum text_decoration_style
+ web_color decoration_color = web_color::current_color; // Decoration line color
+ std::string emphasis_style; // Text emphasis style
+ web_color emphasis_color = web_color::current_color; // Text emphasis color
+ int emphasis_position = text_emphasis_position_over; // Text emphasis position
+
+ std::string hash() const
+ {
+ std::string out;
+ out += family;
+ out += ":sz=" + std::to_string(size);
+ out += ":st=" + std::to_string(style);
+ out += ":w=" + std::to_string(weight);
+ out += ":dl=" + std::to_string(decoration_line);
+ out += ":dt=" + decoration_thickness.to_string();
+ out += ":ds=" + std::to_string(decoration_style);
+ out += ":dc=" + decoration_color.to_string();
+ out += ":ephs=" + emphasis_style;
+ out += ":ephc=" + emphasis_color.to_string();
+ out += ":ephp=" + std::to_string(emphasis_position);
+
+ return out;
+ }
+ };
+}
+
+#endif \ No newline at end of file
diff --git a/libs/litehtml/include/litehtml/gradient.h b/libs/litehtml/include/litehtml/gradient.h
index 6313eb75b2..1bfe77cde0 100644
--- a/libs/litehtml/include/litehtml/gradient.h
+++ b/libs/litehtml/include/litehtml/gradient.h
@@ -1,6 +1,11 @@
#ifndef LITEHTML_GRADIENT_H
#define LITEHTML_GRADIENT_H
+#include "css_length.h"
+#include "string_id.h"
+#include "types.h"
+#include "web_color.h"
+
namespace litehtml
{
enum gradient_side
@@ -129,7 +134,7 @@ namespace litehtml
explicit gradient(string_id type = empty_id)
{
m_type = type;
-
+
// linear gradient: m_side default is gradient_side_none (use angle)
// radial,conic gradient: m_side default is gradient_side_x_center | gradient_side_y_center (see parse_gradient)
m_side = gradient_side_none;
@@ -144,7 +149,7 @@ namespace litehtml
// <radial-size> https://drafts.csswg.org/css-images-3/#valdef-radial-gradient-radial-size
// if radius is specified radial_extent will be set to none, see parse_radial_size
- radial_extent = radial_extent_farthest_corner;
+ radial_extent = radial_extent_farthest_corner;
radial_radius_x.predef(0);
radial_radius_y.predef(0);
@@ -182,7 +187,7 @@ namespace litehtml
gradient m_gradient;
image() : type(type_none) {}
-
+
bool is_empty() const
{
switch (type)
diff --git a/libs/litehtml/include/litehtml/html.h b/libs/litehtml/include/litehtml/html.h
index cd0500aabe..9b725d9a66 100644
--- a/libs/litehtml/include/litehtml/html.h
+++ b/libs/litehtml/include/litehtml/html.h
@@ -6,19 +6,8 @@
#include <cctype>
#include <cstring>
#include <algorithm>
-#include <functional>
-#include "os_types.h"
#include "types.h"
-#include "string_id.h"
-#include "utf8_strings.h"
-#include "background.h"
-#include "borders.h"
-#include "web_color.h"
#include "media_query.h"
-#include "html_microsyntaxes.h"
-#include "html_tag.h"
-#include "document_container.h"
-#include "document.h"
namespace litehtml
{
@@ -36,15 +25,10 @@ namespace litehtml
double t_strtod(const char* string, char** endPtr = nullptr);
string get_escaped_string(const string& in_str);
- template<typename X, typename A>
- bool is_one_of(X x, A a)
+ template<typename T, typename... Opts>
+ bool is_one_of(T val, Opts ...opts)
{
- return x == a;
- }
- template<typename X, typename A, typename... AA>
- bool is_one_of(X x, A a, AA... aa)
- {
- return x == a || is_one_of(x, aa...);
+ return (... || (val == opts));
}
template<class T>
const T& at(const vector<T>& vec, int index /*may be negative*/)
@@ -155,7 +139,7 @@ namespace litehtml
return (c >= '0' && c <= '9');
}
const auto is_digit = t_isdigit;
-
+
inline bool is_hex_digit(int ch) {
return is_digit(ch) || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F');
}
diff --git a/libs/litehtml/include/litehtml/html_microsyntaxes.h b/libs/litehtml/include/litehtml/html_microsyntaxes.h
index 193dd20d62..04c7445ee5 100644
--- a/libs/litehtml/include/litehtml/html_microsyntaxes.h
+++ b/libs/litehtml/include/litehtml/html_microsyntaxes.h
@@ -1,20 +1,22 @@
#ifndef LH_HTML_MICROSYNTAXES_H
#define LH_HTML_MICROSYNTAXES_H
+#include "types.h"
+
namespace litehtml
{
-bool html_parse_integer(const string& str, int& val);
-bool html_parse_non_negative_integer(const string& str, int& val);
+ bool html_parse_integer(const string& str, int& val);
+ bool html_parse_non_negative_integer(const string& str, int& val);
-enum html_dimension_type
-{
- html_length,
- html_percentage
-};
+ enum html_dimension_type
+ {
+ html_length,
+ html_percentage
+ };
-bool html_parse_dimension_value(const string& str, float& val, html_dimension_type& type);
-bool html_parse_nonzero_dimension_value(const string& str, float& val, html_dimension_type& type);
+ bool html_parse_dimension_value(const string& str, float& val, html_dimension_type& type);
+ bool html_parse_nonzero_dimension_value(const string& str, float& val, html_dimension_type& type);
} // namespace litehtml
diff --git a/libs/litehtml/include/litehtml/html_tag.h b/libs/litehtml/include/litehtml/html_tag.h
index 63cd64498a..d8c9dfa40b 100644
--- a/libs/litehtml/include/litehtml/html_tag.h
+++ b/libs/litehtml/include/litehtml/html_tag.h
@@ -4,8 +4,6 @@
#include "element.h"
#include "style.h"
#include "background.h"
-#include "css_margins.h"
-#include "borders.h"
#include "css_selector.h"
#include "stylesheet.h"
#include "line_box.h"
@@ -61,7 +59,7 @@ namespace litehtml
bool on_mouse_over() override;
bool on_mouse_leave() override;
bool on_lbutton_down() override;
- bool on_lbutton_up() override;
+ bool on_lbutton_up(bool is_click) override;
void on_click() override;
bool set_pseudo_class(string_id cls, bool add) override;
bool set_class(const char* pclass, bool add) override;
diff --git a/libs/litehtml/include/litehtml/iterators.h b/libs/litehtml/include/litehtml/iterators.h
index b1a678d7b4..b7e1887c16 100644
--- a/libs/litehtml/include/litehtml/iterators.h
+++ b/libs/litehtml/include/litehtml/iterators.h
@@ -2,7 +2,6 @@
#define LH_ITERATORS_H
#include "types.h"
-#include <list>
#include <functional>
namespace litehtml
@@ -45,7 +44,7 @@ namespace litehtml
~elements_iterator() = default;
void process(const std::shared_ptr<render_item>& container, const std::function<void (std::shared_ptr<render_item>&, iterator_item_type)>& func);
-
+
private:
void next_idx();
};
diff --git a/libs/litehtml/include/litehtml/line_box.h b/libs/litehtml/include/litehtml/line_box.h
index 6e945c9fdc..eac00d13d3 100644
--- a/libs/litehtml/include/litehtml/line_box.h
+++ b/libs/litehtml/include/litehtml/line_box.h
@@ -1,9 +1,8 @@
#ifndef LH_LINE_BOX_H
#define LH_LINE_BOX_H
-#include <vector>
#include <memory>
-#include "os_types.h"
+#include "css_properties.h"
#include "types.h"
namespace litehtml
@@ -40,15 +39,16 @@ namespace litehtml
};
protected:
std::shared_ptr<render_item> m_element;
- int m_rendered_min_width;
+ int m_rendered_min_width = 0;
+ int m_items_top = 0;
+ int m_items_bottom = 0;
public:
- explicit line_box_item(const std::shared_ptr<render_item>& element) : m_element(element), m_rendered_min_width(0) {}
- line_box_item() : m_element(), m_rendered_min_width(0) {};
+ explicit line_box_item(const std::shared_ptr<render_item>& element) : m_element(element) {}
line_box_item(const line_box_item& el) = default;
line_box_item(line_box_item&&) = default;
virtual ~line_box_item();
- int height() const { return right() - left(); }
+ virtual int height() const;
const std::shared_ptr<render_item>& get_el() const { return m_element; }
virtual position& pos();
virtual void place_to(int x, int y);
@@ -60,6 +60,15 @@ namespace litehtml
virtual element_type get_type() const { return type_text_part; }
virtual int get_rendered_min_width() const { return m_rendered_min_width; }
virtual void set_rendered_min_width(int min_width) { m_rendered_min_width = min_width; }
+
+ void reset_items_height() { m_items_top = m_items_bottom = 0; }
+ void add_item_height(int item_top, int item_bottom)
+ {
+ m_items_top = std::min(m_items_top, item_top);
+ m_items_bottom = std::max(m_items_bottom, item_bottom);
+ }
+ int get_items_top() const { return m_items_top; }
+ int get_items_bottom() const { return m_items_bottom; }
};
class lbi_start : public line_box_item
@@ -68,9 +77,10 @@ namespace litehtml
position m_pos;
public:
explicit lbi_start(const std::shared_ptr<render_item>& element);
- virtual ~lbi_start() override;
+ ~lbi_start() override;
void place_to(int x, int y) override;
+ int height() const override;
int width() const override;
position& pos() override { return m_pos; }
int top() const override;
@@ -110,10 +120,10 @@ namespace litehtml
{
struct va_context
{
- int baseline;
+ int line_height = 0;
+ int baseline = 0;
font_metrics fm;
-
- va_context() : baseline(0) {}
+ line_box_item* start_lbi = nullptr;
};
int m_top;
@@ -121,21 +131,19 @@ namespace litehtml
int m_right;
int m_height;
int m_width;
- int m_line_height;
- int m_default_line_height;
+ css_line_height_t m_default_line_height;
font_metrics m_font_metrics;
int m_baseline;
text_align m_text_align;
int m_min_width;
std::list< std::unique_ptr<line_box_item> > m_items;
public:
- line_box(int top, int left, int right, int line_height, const font_metrics& fm, text_align align) :
+ line_box(int top, int left, int right, const css_line_height_t& line_height, const font_metrics& fm, text_align align) :
m_top(top),
m_left(left),
m_right(right),
m_height(0),
m_width(0),
- m_line_height(0),
m_default_line_height(line_height),
m_font_metrics(fm),
m_baseline(0),
diff --git a/libs/litehtml/include/litehtml/media_query.h b/libs/litehtml/include/litehtml/media_query.h
index 94ed205e52..163191a512 100644
--- a/libs/litehtml/include/litehtml/media_query.h
+++ b/libs/litehtml/include/litehtml/media_query.h
@@ -1,6 +1,10 @@
#ifndef LH_MEDIA_QUERY_H
#define LH_MEDIA_QUERY_H
+#include "css_tokenizer.h"
+#include "string_id.h"
+#include "types.h"
+
namespace litehtml
{
// https://drafts.csswg.org/mediaqueries/#evaluating
@@ -53,7 +57,7 @@ namespace litehtml
{
string_id op = _and_; // _not_ _and_ _or_
vector<media_in_parens> m_conditions;
-
+
trilean check(const media_features& features) const;
};
@@ -68,7 +72,7 @@ namespace litehtml
short op2 = 0;
bool verify_and_convert_units(string_id syntax, css_token val[2] = 0, css_token val2[2] = 0, shared_ptr<document> doc = 0);
-
+
bool compare(int x) const { return compare((float)x); }
bool compare(float x) const;
bool check(const media_features& features) const;
@@ -92,7 +96,7 @@ namespace litehtml
media_query_list parse_media_query_list(const css_token_vector& tokens, shared_ptr<document> doc);
media_query_list parse_media_query_list(const string& str, shared_ptr<document> doc);
-
+
class media_query_list_list
{
public:
diff --git a/libs/litehtml/include/litehtml/render_item.h b/libs/litehtml/include/litehtml/render_item.h
index d67fc42624..fedc1f3887 100644
--- a/libs/litehtml/include/litehtml/render_item.h
+++ b/libs/litehtml/include/litehtml/render_item.h
@@ -2,13 +2,14 @@
#define LH_RENDER_ITEM_H
#include <memory>
-#include <utility>
#include <list>
#include <tuple>
+#include "html.h"
#include "types.h"
#include "line_box.h"
#include "table.h"
#include "formatting_context.h"
+#include "element.h"
namespace litehtml
{
@@ -348,7 +349,8 @@ namespace litehtml
m_element->css().get_float() == float_none &&
m_margins.top >= 0 &&
!is_flex_item() &&
- !is_root();
+ !is_root() &&
+ !is_one_of(css().get_overflow(), overflow_hidden, overflow_scroll, overflow_auto);
}
bool collapse_bottom_margin() const
@@ -358,7 +360,8 @@ namespace litehtml
m_element->in_normal_flow() &&
m_element->css().get_float() == float_none &&
m_margins.bottom >= 0 &&
- !is_root();
+ !is_root() &&
+ !is_one_of(css().get_overflow(), overflow_hidden, overflow_scroll, overflow_auto);
}
bool is_visible() const
diff --git a/libs/litehtml/include/litehtml/string_id.h b/libs/litehtml/include/litehtml/string_id.h
index a488b32792..6373ec9e4d 100644
--- a/libs/litehtml/include/litehtml/string_id.h
+++ b/libs/litehtml/include/litehtml/string_id.h
@@ -1,6 +1,8 @@
#ifndef LH_STRING_ID_H
#define LH_STRING_ID_H
+#include <string>
+
namespace litehtml
{
@@ -252,6 +254,14 @@ STRING_ID(
_font_size_,
_line_height_,
_text_decoration_,
+ _text_decoration_style_,
+ _text_decoration_line_,
+ _text_decoration_color_,
+ _text_decoration_thickness_,
+ _text_emphasis_,
+ _text_emphasis_style_,
+ _text_emphasis_color_,
+ _text_emphasis_position_,
_white_space_,
_text_align_,
@@ -267,6 +277,7 @@ STRING_ID(
_overflow_,
_display_,
_visibility_,
+ _appearance_,
_box_sizing_,
_z_index_,
_float_,
@@ -346,8 +357,8 @@ STRING_ID(
extern const string_id empty_id; // _id("")
extern const string_id star_id; // _id("*")
-string_id _id(const string& str);
-const string& _s(string_id id);
+string_id _id(const std::string& str);
+const std::string& _s(string_id id);
} // namespace litehtml
diff --git a/libs/litehtml/include/litehtml/style.h b/libs/litehtml/include/litehtml/style.h
index 256fd8f3ca..e68a05b725 100644
--- a/libs/litehtml/include/litehtml/style.h
+++ b/libs/litehtml/include/litehtml/style.h
@@ -1,7 +1,12 @@
#ifndef LH_STYLE_H
#define LH_STYLE_H
+#include "background.h"
+#include "css_length.h"
+#include "css_position.h"
#include "css_tokenizer.h"
+#include "gradient.h"
+#include "web_color.h"
namespace litehtml
{
@@ -28,7 +33,7 @@ namespace litehtml
bool m_has_var = false; // css_token_vector, parsing is delayed because of var()
property_value() {}
- template<class T> property_value(const T& val, bool important, bool has_var = false)
+ template<class T> property_value(const T& val, bool important, bool has_var = false)
: base(val), m_important(important), m_has_var(has_var) {}
};
@@ -73,26 +78,33 @@ namespace litehtml
void parse_keyword_comma_list(string_id name, const css_token_vector& tokens, bool important);
void parse_background_position(const css_token_vector& tokens, bool important);
void parse_background_size(const css_token_vector& tokens, bool important);
-
+
void parse_border(const css_token_vector& tokens, bool important, document_container* container);
void parse_border_side(string_id name, const css_token_vector& tokens, bool important, document_container* container);
void parse_border_radius(const css_token_vector& tokens, bool important);
-
+
bool parse_list_style_image(const css_token& tok, string& url);
void parse_list_style(const css_token_vector& tokens, string baseurl, bool important);
void parse_font(css_token_vector tokens, bool important);
-
+ void parse_text_decoration(const css_token_vector& tokens, bool important, document_container* container);
+ bool parse_text_decoration_color(const css_token& token, bool important, document_container* container);
+ void parse_text_decoration_line(const css_token_vector& tokens, bool important);
+
+ void parse_text_emphasis(const css_token_vector& tokens, bool important, document_container* container);
+ bool parse_text_emphasis_color(const css_token& token, bool important, document_container* container);
+ void parse_text_emphasis_position(const css_token_vector& tokens, bool important);
+
void parse_flex_flow(const css_token_vector& tokens, bool important);
void parse_flex(const css_token_vector& tokens, bool important);
void parse_align_self(string_id name, const css_token_vector& tokens, bool important);
-
+
void add_parsed_property(string_id name, const property_value& propval);
void add_length_property(string_id name, css_token val, string keywords, int options, bool important);
template<class T> void add_four_properties(string_id top_name, T val[4], int n, bool important);
void remove_property(string_id name, bool important);
};
-
+
bool parse_url(const css_token& token, string& url);
bool parse_length(const css_token& tok, css_length& length, int options, string keywords = "");
bool parse_angle(const css_token& tok, float& angle, bool percents_allowed = false);
diff --git a/libs/litehtml/include/litehtml/stylesheet.h b/libs/litehtml/include/litehtml/stylesheet.h
index 179f2de69b..f81bac7121 100644
--- a/libs/litehtml/include/litehtml/stylesheet.h
+++ b/libs/litehtml/include/litehtml/stylesheet.h
@@ -1,7 +1,6 @@
#ifndef LH_STYLESHEET_H
#define LH_STYLESHEET_H
-#include "style.h"
#include "css_selector.h"
#include "css_tokenizer.h"
@@ -28,7 +27,7 @@ public:
using vector = std::vector<ptr>;
enum rule_type { qualified, at };
-
+
raw_rule(rule_type type, string name = "") : type(type), name(name) {}
rule_type type;
diff --git a/libs/litehtml/include/litehtml/tstring_view.h b/libs/litehtml/include/litehtml/tstring_view.h
index 74bf5d3241..9c3c74f5fe 100644
--- a/libs/litehtml/include/litehtml/tstring_view.h
+++ b/libs/litehtml/include/litehtml/tstring_view.h
@@ -33,8 +33,6 @@
#include <cstddef>
#include <ostream>
-#include "types.h"
-
namespace litehtml {
// tstring_view is a string reference type that provides a view into a string
diff --git a/libs/litehtml/include/litehtml/types.h b/libs/litehtml/include/litehtml/types.h
index c92998cd43..43cafc3bff 100644
--- a/libs/litehtml/include/litehtml/types.h
+++ b/libs/litehtml/include/litehtml/types.h
@@ -7,7 +7,6 @@
#include <vector>
#include <map>
#include <list>
-#include <set>
#include <variant>
#include <optional>
#include <algorithm>
@@ -50,10 +49,46 @@ namespace litehtml
limited_quirks_mode
};
- const unsigned int font_decoration_none = 0x00;
- const unsigned int font_decoration_underline = 0x01;
- const unsigned int font_decoration_linethrough = 0x02;
- const unsigned int font_decoration_overline = 0x04;
+ #define style_text_decoration_line_strings "none;underline;overline;line-through"
+
+ enum text_decoration_line
+ {
+ text_decoration_line_none = 0x00,
+ text_decoration_line_underline = 0x01,
+ text_decoration_line_overline = 0x02,
+ text_decoration_line_line_through = 0x04,
+ };
+
+ #define style_text_decoration_style_strings "solid;double;dotted;dashed;wavy"
+
+ enum text_decoration_style
+ {
+ text_decoration_style_solid,
+ text_decoration_style_double,
+ text_decoration_style_dotted,
+ text_decoration_style_dashed,
+ text_decoration_style_wavy,
+ text_decoration_style_max,
+ };
+
+ #define style_text_decoration_thickness_strings "auto;from-font"
+
+ enum text_decoration_thickness
+ {
+ text_decoration_thickness_auto,
+ text_decoration_thickness_from_font,
+ };
+
+ #define style_text_emphasis_position_strings "over;under;left;right"
+
+ enum text_emphasis_position
+ {
+ text_emphasis_position_over = 0x00,
+ text_emphasis_position_under = 0x01,
+ text_emphasis_position_left = 0x02,
+ text_emphasis_position_right = 0x04,
+ };
+
using byte = unsigned char;
using ucode_t = unsigned int;
@@ -103,23 +138,19 @@ namespace litehtml
{
using vector = std::vector<position>;
- int x;
- int y;
- int width;
- int height;
+ int x = 0;
+ int y = 0;
+ int width = 0;
+ int height = 0;
- position()
- {
- x = y = width = height = 0;
- }
+ position() = default;
- position(int x, int y, int width, int height)
- {
- this->x = x;
- this->y = y;
- this->width = width;
- this->height = height;
- }
+ position(int _x, int _y, int _width, int _height) :
+ x(_x),
+ y(_y),
+ width(_width),
+ height(_height)
+ {}
int right() const { return x + width; }
int bottom() const { return y + height; }
@@ -152,12 +183,18 @@ namespace litehtml
height = sz.height;
}
+ bool operator==(const position& val)
+ {
+ return x == val.x && y == val.y && width == val.width && height == val.height;
+ }
+
void move_to(int _x, int _y)
{
x = _x;
y = _y;
}
+ [[nodiscard]]
bool does_intersect(const position* val) const
{
if(!val) return true;
@@ -174,45 +211,56 @@ namespace litehtml
val->top() <= bottom() );
}
- bool empty() const
+ [[nodiscard]]
+ position intersect(const position& src) const
{
- if(!width && !height)
+ position dest;
+ int dest_x = std::max(src.x, x);
+ int dest_y = std::max(src.y, y);
+ int dest_x2 = std::min(src.right(), right());
+ int dest_y2 = std::min(src.bottom(), bottom());
+
+ if (dest_x2 > dest_x && dest_y2 > dest_y)
{
- return true;
+ dest.x = dest_x;
+ dest.y = dest_y;
+ dest.width = dest_x2 - dest_x;
+ dest.height = dest_y2 - dest_y;
}
- return false;
+ else
+ {
+ dest.width = 0;
+ dest.height = 0;
+ }
+
+ return dest;
}
+ [[nodiscard]]
+ bool empty() const
+ {
+ return !width && !height;
+ }
+
+ [[nodiscard]]
bool is_point_inside(int _x, int _y) const
{
- if(_x >= left() && _x < right() && _y >= top() && _y < bottom())
- {
- return true;
- }
- return false;
+ return (_x >= left() && _x < right() && _y >= top() && _y < bottom());
}
};
struct font_metrics
{
- int font_size;
- int height;
- int ascent;
- int descent;
- int x_height;
- int ch_width;
- bool draw_spaces;
-
- font_metrics()
- {
- font_size = 0;
- height = 0;
- ascent = 0;
- descent = 0;
- x_height = 0;
- ch_width = 0;
- draw_spaces = true;
- }
+ int font_size = 0; // Font size in pixels. The same as size argument of the create_font function
+ int height = 0; // Font height in pixels.
+ int ascent = 0; // The distance from the baseline to the top of a line of text.
+ int descent = 0; // The distance from the baseline to the bottom of a line of text.
+ int x_height = 0; // Height of the symbol x
+ int ch_width = 0; // Height of the symbol 0
+ bool draw_spaces = true; // True to call draw text function for spaces. If False, just use space width without draw.
+ int sub_shift = 0; // The baseline shift for subscripts.
+ int super_shift = 0; // The baseline shift for superscripts.
+
int base_line() const { return descent; }
};
@@ -830,6 +878,27 @@ namespace litehtml
_baseline_type m_type;
};
+#define appearance_strings "none;auto;menulist-button;textfield;button;checkbox;listbox;menulist;meter;progress-bar;push-button;radio;searchfield;slider-horizontal;square-button;textarea"
+
+ enum appearance
+ {
+ appearance_none,
+ appearance_auto,
+ appearance_menulist_button,
+ appearance_textfield,
+ appearance_button,
+ appearance_checkbox,
+ appearance_listbox,
+ appearance_menulist,
+ appearance_meter,
+ appearance_progress_bar,
+ appearance_push_button,
+ appearance_radio,
+ appearance_searchfield,
+ appearance_slider_horizontal,
+ appearance_square_button,
+ appearance_textarea,
+ };
#define box_sizing_strings "content-box;border-box"
diff --git a/libs/litehtml/include/litehtml/url.h b/libs/litehtml/include/litehtml/url.h
index 83f98a752e..fae3db0a01 100644
--- a/libs/litehtml/include/litehtml/url.h
+++ b/libs/litehtml/include/litehtml/url.h
@@ -30,8 +30,6 @@
#ifndef LITEHTML_URL_H__
#define LITEHTML_URL_H__
-#include <ostream>
-
#include "types.h"
// https://datatracker.ietf.org/doc/html/rfc3986
diff --git a/libs/litehtml/include/litehtml/url_path.h b/libs/litehtml/include/litehtml/url_path.h
index 6ba68b03b8..f936659186 100644
--- a/libs/litehtml/include/litehtml/url_path.h
+++ b/libs/litehtml/include/litehtml/url_path.h
@@ -30,8 +30,6 @@
#ifndef LITEHTML_URL_PATH_H__
#define LITEHTML_URL_PATH_H__
-#include <ostream>
-
#include "types.h"
namespace litehtml {
diff --git a/libs/litehtml/include/litehtml/web_color.h b/libs/litehtml/include/litehtml/web_color.h
index 9bc198dbcd..ba59ae66db 100644
--- a/libs/litehtml/include/litehtml/web_color.h
+++ b/libs/litehtml/include/litehtml/web_color.h
@@ -1,6 +1,9 @@
#ifndef LH_WEB_COLOR_H
#define LH_WEB_COLOR_H
+#include "css_tokenizer.h"
+#include "types.h"
+
namespace litehtml
{
class document_container;
diff --git a/libs/litehtml/src/background.cpp b/libs/litehtml/src/background.cpp
index 3ef69b862d..eaf115da72 100644
--- a/libs/litehtml/src/background.cpp
+++ b/libs/litehtml/src/background.cpp
@@ -1,8 +1,9 @@
#include <cmath>
-#include "html.h"
#include "background.h"
#include "render_item.h"
+#include "document.h"
+#include "document_container.h"
#ifndef M_PI
# define M_PI 3.14159265358979323846
@@ -807,7 +808,7 @@ bool litehtml::background_layer::gradient_base::prepare_color_points(float line_
{
if (!color_points.empty())
{
- color_points.back().hint = item.length ?
+ color_points.back().hint = item.length ?
normalize_length(*item.length, line_len) :
*item.angle / 360;
}
diff --git a/libs/litehtml/src/css_parser.cpp b/libs/litehtml/src/css_parser.cpp
index 24e49a78c8..3a78b00645 100644
--- a/libs/litehtml/src/css_parser.cpp
+++ b/libs/litehtml/src/css_parser.cpp
@@ -1,3 +1,4 @@
+#include "encodings.h"
#include "html.h"
#include "css_parser.h"
@@ -38,7 +39,48 @@ void filter_code_points(string& input)
input = result;
}
-void remove_whitespace(css_token_vector& tokens, keep_whitespace_fn keep_whitespace)
+static const size_t kLargeSize = 50;
+static void remove_whitespace_large(css_token_vector& tokens, keep_whitespace_fn keep_whitespace);
+static void remove_whitespace_small(css_token_vector& tokens, keep_whitespace_fn keep_whitespace);
+
+void remove_whitespace_large(css_token_vector& tokens, keep_whitespace_fn keep_whitespace)
+{
+ std::vector<int> keep_idx;
+ keep_idx.reserve(tokens.size());
+ for (int i = 0; i < static_cast<int>(tokens.size()); ++i)
+ {
+ auto &tok = tokens[i];
+ bool keep = true;
+ if (tok.type == ' ')
+ {
+ const auto &left = i > 0 ? tokens[i - 1] : css_token();
+ const auto &right = at(tokens, i + 1);
+ keep = keep_whitespace && keep_whitespace(left, right);
+ }
+ else if (tok.is_component_value())
+ {
+ if (tok.value.size() > kLargeSize)
+ remove_whitespace_large(tok.value, keep_whitespace);
+ else
+ remove_whitespace_small(tok.value, keep_whitespace);
+ }
+ if (keep)
+ keep_idx.push_back(i);
+ }
+
+ if (keep_idx.size() == tokens.size())
+ return;
+ else
+ {
+ css_token_vector tmp;
+ tmp.reserve(keep_idx.size());
+ for (auto idx : keep_idx)
+ tmp.push_back(tokens[idx]);
+ tokens.swap(tmp);
+ }
+}
+
+void remove_whitespace_small(css_token_vector& tokens, keep_whitespace_fn keep_whitespace)
{
for (int i = 0; i < (int)tokens.size(); i++)
{
@@ -48,13 +90,27 @@ void remove_whitespace(css_token_vector& tokens, keep_whitespace_fn keep_whitesp
const auto& left = i > 0 ? tokens[i - 1] : css_token();
const auto& right = at(tokens, i + 1);
bool keep = keep_whitespace && keep_whitespace(left, right);
- if (!keep) remove(tokens, i), i--;
+ if (!keep)
+ remove(tokens, i), i--;
}
else if (tok.is_component_value())
- remove_whitespace(tok.value, keep_whitespace);
+ {
+ if (tok.value.size() > kLargeSize)
+ remove_whitespace_large(tok.value, keep_whitespace);
+ else
+ remove_whitespace_small(tok.value, keep_whitespace);
+ }
}
}
+void remove_whitespace(css_token_vector& tokens, keep_whitespace_fn keep_whitespace)
+{
+ if (tokens.size() > kLargeSize)
+ remove_whitespace_large(tokens, keep_whitespace);
+ else
+ remove_whitespace_small(tokens, keep_whitespace);
+}
+
void componentize(css_token_vector& tokens)
{
css_parser parser(tokens);
@@ -85,17 +141,17 @@ css_token_vector normalize(string input, int options, keep_whitespace_fn keep_wh
}
// https://www.w3.org/TR/css-syntax-3/#parse-stylesheet
-// I don't create a stylesheet because its only perpose is to pass a list of rules to
+// I don't create a stylesheet because its only perpose is to pass a list of rules to
// parse_css_stylesheet. I just return the list of rules directly instead.
raw_rule::vector css_parser::parse_stylesheet(const string& input, bool top_level)
{
// 1. If input is a byte stream for stylesheet, decode bytes from input, and set input to the result.
// not implemented, utf-8 is always assumed
string str = decode(input, encoding::utf_8); // decoding potentially broken UTF-8 into valid UTF-8
-
+
// 2. Normalize input, and set input to the result.
auto tokens = normalize(str);
-
+
return parse_stylesheet(tokens, top_level);
}
raw_rule::vector css_parser::parse_stylesheet(const css_token_vector& input, bool top_level)
@@ -147,7 +203,7 @@ raw_rule::vector css_parser::consume_list_of_rules(bool top_level)
// If the top-level flag is set, do nothing.
if (top_level) break;
- // Otherwise, reconsume the current input token. Consume a qualified rule.
+ // Otherwise, reconsume the current input token. Consume a qualified rule.
// If anything is returned, append it to the list of rules.
m_index--;
rule = consume_qualified_rule();
@@ -208,7 +264,7 @@ raw_rule::ptr css_parser::consume_qualified_rule()
// https://www.w3.org/TR/css-syntax-3/#consume-at-rule
raw_rule::ptr css_parser::consume_at_rule()
{
- // Consume the next input token. Create a new at-rule with its name set to the value of the current input token,
+ // Consume the next input token. Create a new at-rule with its name set to the value of the current input token,
// its prelude initially set to an empty list, and its value initially set to nothing.
css_token token = next_token();
raw_rule::ptr rule = make_shared<raw_rule>(raw_rule::at, token.str);
@@ -251,7 +307,7 @@ css_token css_parser::consume_simple_block(char opening_bracket)
// Create a simple block with its associated token set to the current input token and with its value initially set to an empty list.
auto block_type = css_token_type(-100 - opening_bracket); // see css_token_type
css_token block(block_type);
-
+
char closing_bracket = mirror(opening_bracket);
while (true)
@@ -289,11 +345,11 @@ css_token css_parser::consume_component_value()
// If the current input token is a <{-token>, <[-token>, or <(-token>, consume a simple block and return it.
case '{': case '[': case '(':
return consume_simple_block((char)token.ch);
-
+
// Otherwise, if the current input token is a <function-token>, consume a function and return it.
case FUNCTION:
return consume_function(token.name);
-
+
// Otherwise, return the current input token.
default:
return token;
@@ -343,7 +399,7 @@ void trim_whitespace(css_token_vector& tokens)
// next token is guaranteed to be IDENT
raw_declaration css_parser::consume_declaration()
{
- // Consume the next input token. Create a new declaration with its name set to the value of
+ // Consume the next input token. Create a new declaration with its name set to the value of
// the current input token and its value initially set to an empty list.
css_token token = next_token();
raw_declaration decl = {token.name};
@@ -364,13 +420,13 @@ raw_declaration css_parser::consume_declaration()
// 3. While the next input token is a <whitespace-token>, consume the next input token.
while (peek_token().type == ' ') next_token();
- // 4. As long as the next input token is anything other than an <EOF-token>,
+ // 4. As long as the next input token is anything other than an <EOF-token>,
// consume a component value and append it to the declaration’s value.
while (peek_token().type != EOF)
value.push_back(consume_component_value());
- // 5. If the last two non-<whitespace-token>s in the declaration’s value are a <delim-token> with the value "!"
- // followed by an <ident-token> with a value that is an ASCII case-insensitive match for "important",
+ // 5. If the last two non-<whitespace-token>s in the declaration’s value are a <delim-token> with the value "!"
+ // followed by an <ident-token> with a value that is an ASCII case-insensitive match for "important",
// remove them from the declaration’s value and set the declaration’s important flag to true.
trim_whitespace(value); // deviation from standard: removing leading whitespace as well
@@ -417,7 +473,7 @@ void css_parser::consume_style_block_contents(/*out*/ raw_declaration::vector& d
case IDENT: {
// Initialize a temporary list initially filled with the current input token.
css_token_vector temp = { token };
- // As long as the next input token is anything other than a <semicolon-token> or <EOF-token>,
+ // As long as the next input token is anything other than a <semicolon-token> or <EOF-token>,
// consume a component value and append it to the temporary list.
while (!is_one_of(peek_token().type, ';', EOF))
temp.push_back(consume_component_value());
@@ -437,7 +493,7 @@ void css_parser::consume_style_block_contents(/*out*/ raw_declaration::vector& d
break;
}
default:
- // This is a parse error. Reconsume the current input token. As long as the next input token is
+ // This is a parse error. Reconsume the current input token. As long as the next input token is
// anything other than a <;> or <EOF>, consume a component value and throw away the returned value.
css_parse_error("unexpected token in a style block");
m_index--;
@@ -511,4 +567,4 @@ bool skip_whitespace(const css_token_vector& tokens, int& index)
return index != start;
}
-} // namespace litehtml \ No newline at end of file
+} // namespace litehtml
diff --git a/libs/litehtml/src/css_properties.cpp b/libs/litehtml/src/css_properties.cpp
index 9100a998e0..6014babb3b 100644
--- a/libs/litehtml/src/css_properties.cpp
+++ b/libs/litehtml/src/css_properties.cpp
@@ -1,13 +1,15 @@
#include "html.h"
#include "css_properties.h"
#include <cmath>
+#include "document.h"
+#include "html_tag.h"
+#include "document_container.h"
#define offset(member) ((uint_ptr)&this->member - (uint_ptr)this)
+//#define offset(func) [](const css_properties& css) { return css.func; }
void litehtml::css_properties::compute(const html_tag* el, const document::ptr& doc)
{
- compute_font(el, doc);
- int font_size = get_font_size();
m_color = el->get_property<web_color>(_color_, true, web_color::black, offset(m_color));
m_el_position = (element_position) el->get_property<int>( _position_, false, element_position_static, offset(m_el_position));
@@ -15,6 +17,7 @@ void litehtml::css_properties::compute(const html_tag* el, const document::ptr&
m_visibility = (visibility) el->get_property<int>( _visibility_, true, visibility_visible, offset(m_visibility));
m_float = (element_float) el->get_property<int>( _float_, false, float_none, offset(m_float));
m_clear = (element_clear) el->get_property<int>( _clear_, false, clear_none, offset(m_clear));
+ m_appearance = (appearance) el->get_property<int>( _appearance_, false, appearance_none, offset(m_appearance));
m_box_sizing = (box_sizing) el->get_property<int>( _box_sizing_, false, box_sizing_content_box, offset(m_box_sizing));
m_overflow = (overflow) el->get_property<int>( _overflow_, false, overflow_visible, offset(m_overflow));
m_text_align = (text_align) el->get_property<int>( _text_align_, true, text_align_left, offset(m_text_align));
@@ -97,10 +100,16 @@ void litehtml::css_properties::compute(const html_tag* el, const document::ptr&
{
m_display = display_block;
}
+ } else if(el->is_replaced() && m_display == display_inline)
+ {
+ m_display = display_inline_block;
}
}
// 5. Otherwise, the remaining 'display' property values apply as specified.
+ compute_font(el, doc);
+ int font_size = get_font_size();
+
const css_length _auto = css_length::predef_value(0);
const css_length none = _auto, normal = _auto;
@@ -217,17 +226,17 @@ void litehtml::css_properties::compute(const html_tag* el, const document::ptr&
m_css_text_indent = el->get_property<css_length>(_text_indent_, true, 0, offset(m_css_text_indent));
doc->cvt_units(m_css_text_indent, m_font_metrics, 0);
- m_css_line_height = el->get_property<css_length>(_line_height_, true, normal, offset(m_css_line_height));
- if(m_css_line_height.is_predefined())
+ m_line_height.css_value = el->get_property<css_length>(_line_height_, true, normal, offset(m_line_height.css_value));
+ if(m_line_height.css_value.is_predefined())
{
- m_line_height = m_font_metrics.height;
- } else if(m_css_line_height.units() == css_units_none)
+ m_line_height.computed_value = m_font_metrics.height;
+ } else if(m_line_height.css_value.units() == css_units_none)
{
- m_line_height = (int) std::nearbyint(m_css_line_height.val() * font_size);
+ m_line_height.computed_value = (int) std::nearbyint(m_line_height.css_value.val() * font_size);
} else
{
- m_line_height = doc->to_pixels(m_css_line_height, m_font_metrics, m_font_metrics.font_size);
- m_css_line_height = (float) m_line_height;
+ m_line_height.computed_value = doc->to_pixels(m_line_height.css_value, m_font_metrics, m_font_metrics.font_size);
+ m_line_height.css_value = (float) m_line_height.computed_value;
}
m_list_style_type = (list_style_type) el->get_property<int>(_list_style_type_, true, list_style_type_disc, offset(m_list_style_type));
@@ -281,7 +290,7 @@ void litehtml::css_properties::compute_font(const html_tag* el, const document::
{
parent_sz = doc_font_size;
}
-
+
int font_size = parent_sz;
if(sz.is_predefined())
@@ -347,22 +356,96 @@ void litehtml::css_properties::compute_font(const html_tag* el, const document::
font_size = doc->to_pixels(sz, fm, 0);
}
}
-
+
m_font_size = (float)font_size;
// initialize font
m_font_family = el->get_property<string>( _font_family_, true, doc->container()->get_default_font_name(), offset(m_font_family));
m_font_weight = el->get_property<css_length>(_font_weight_, true, css_length::predef_value(font_weight_normal), offset(m_font_weight));
m_font_style = (font_style) el->get_property<int>( _font_style_, true, font_style_normal, offset(m_font_style));
- m_text_decoration = el->get_property<string>( _text_decoration_, true, "none", offset(m_text_decoration));
-
- m_font = doc->get_font(
- m_font_family.c_str(),
- font_size,
- m_font_weight.is_predefined() ? index_value(m_font_weight.predef(), font_weight_strings).c_str() : std::to_string(m_font_weight.val()).c_str(),
- index_value(m_font_style, font_style_strings).c_str(),
- m_text_decoration.c_str(),
- &m_font_metrics);
+ bool propagate_decoration = !is_one_of(m_display, display_inline_block, display_inline_table, display_inline_flex) &&
+ m_float == float_none && !is_one_of(m_el_position, element_position_absolute, element_position_fixed);
+
+ m_text_decoration_line = el->get_property<int>(_text_decoration_line_, propagate_decoration, text_decoration_line_none, offset(m_text_decoration_line));
+
+ // Merge parent text decoration with child text decoration
+ if (propagate_decoration && el->parent())
+ {
+ m_text_decoration_line |= el->parent()->css().get_text_decoration_line();
+ }
+
+ if(m_text_decoration_line)
+ {
+ m_text_decoration_thickness = el->get_property<css_length>(_text_decoration_thickness_, propagate_decoration, css_length::predef_value(text_decoration_thickness_auto), offset(m_text_decoration_thickness));
+ m_text_decoration_style = (text_decoration_style) el->get_property<int>(_text_decoration_style_, propagate_decoration, text_decoration_style_solid, offset(m_text_decoration_style));
+ m_text_decoration_color = get_color_property(el, _text_decoration_color_, propagate_decoration, web_color::current_color, offset(m_text_decoration_color));
+ } else
+ {
+ m_text_decoration_thickness = css_length::predef_value(text_decoration_thickness_auto);
+ m_text_decoration_color = web_color::current_color;
+ }
+
+ // text-emphasis
+ m_text_emphasis_style = el->get_property<string>(_text_emphasis_style_, true, "", offset(m_text_emphasis_style));
+ m_text_emphasis_position = el->get_property<int>(_text_emphasis_position_, true, text_emphasis_position_over, offset(m_text_emphasis_position));
+ m_text_emphasis_color = get_color_property(el, _text_emphasis_color_, true, web_color::current_color, offset(m_text_emphasis_color));
+
+ if(el->parent())
+ {
+ if(m_text_emphasis_style.empty() || m_text_emphasis_style == "initial" || m_text_emphasis_style == "unset")
+ {
+ m_text_emphasis_style = el->parent()->css().get_text_emphasis_style();
+ }
+ if(m_text_emphasis_color == web_color::current_color)
+ {
+ m_text_emphasis_color = el->parent()->css().get_text_emphasis_color();
+ }
+ m_text_emphasis_position |= el->parent()->css().get_text_emphasis_position();
+ }
+
+ if(m_font_weight.is_predefined())
+ {
+ switch(m_font_weight.predef())
+ {
+ case font_weight_bold:
+ m_font_weight = 700;
+ break;
+ case font_weight_bolder:
+ {
+ const int inherited = (int) el->parent()->css().m_font_weight.val();
+ if(inherited < 400) m_font_weight = 400;
+ else if(inherited >= 400 && inherited < 600) m_font_weight = 700;
+ else m_font_weight = 900;
+ }
+ break;
+ case font_weight_lighter:
+ {
+ const int inherited = (int) el->parent()->css().m_font_weight.val();
+ if(inherited < 600) m_font_weight = 100;
+ else if(inherited >= 600 && inherited < 800) m_font_weight = 400;
+ else m_font_weight = 700;
+ }
+ break;
+ default:
+ m_font_weight = 400;
+ break;
+ }
+ }
+
+ font_description descr;
+ descr.family = m_font_family;
+ descr.size = font_size;
+ descr.style = m_font_style;
+ descr.weight = (int) m_font_weight.val();
+ descr.decoration_line = m_text_decoration_line;
+ descr.decoration_thickness = m_text_decoration_thickness;
+ descr.decoration_style = m_text_decoration_style;
+ descr.decoration_color = m_text_decoration_color;
+ descr.emphasis_style = m_text_emphasis_style;
+ descr.emphasis_color = m_text_emphasis_color;
+ descr.emphasis_position = m_text_emphasis_position;
+
+ m_font = doc->get_font(descr, &m_font_metrics);
}
void litehtml::css_properties::compute_background(const html_tag* el, const document::ptr& doc)
@@ -462,6 +545,7 @@ std::vector<std::tuple<litehtml::string, litehtml::string>> litehtml::css_proper
ret.emplace_back("overflow", index_value(m_overflow, overflow_strings));
ret.emplace_back("white_space", index_value(m_white_space, white_space_strings));
ret.emplace_back("visibility", index_value(m_visibility, visibility_strings));
+ ret.emplace_back("appearance", index_value(m_appearance, appearance_strings));
ret.emplace_back("box_sizing", index_value(m_box_sizing, box_sizing_strings));
ret.emplace_back("z_index", m_z_index.to_string());
ret.emplace_back("vertical_align", index_value(m_vertical_align, vertical_align_strings));
@@ -478,7 +562,7 @@ std::vector<std::tuple<litehtml::string, litehtml::string>> litehtml::css_proper
ret.emplace_back("max_height", m_css_max_width.to_string());
ret.emplace_back("offsets", m_css_offsets.to_string());
ret.emplace_back("text_indent", m_css_text_indent.to_string());
- ret.emplace_back("line_height", std::to_string(m_line_height));
+ ret.emplace_back("line_height", std::to_string(m_line_height.computed_value));
ret.emplace_back("list_style_type", index_value(m_list_style_type, list_style_type_strings));
ret.emplace_back("list_style_position", index_value(m_list_style_position, list_style_position_strings));
ret.emplace_back("border_spacing_x", m_css_border_spacing_x.to_string());
diff --git a/libs/litehtml/src/css_selector.cpp b/libs/litehtml/src/css_selector.cpp
index 43e5a5e33d..56a11e337d 100644
--- a/libs/litehtml/src/css_selector.cpp
+++ b/libs/litehtml/src/css_selector.cpp
@@ -2,6 +2,8 @@
#include "css_selector.h"
#include "css_parser.h"
#include "internal.h"
+#include "document.h"
+#include <set>
namespace litehtml
{
@@ -20,7 +22,7 @@ void css_selector::calc_specificity()
} else
{
m_specificity.c++;
- }
+ }
}
if(m_left)
{
@@ -273,17 +275,17 @@ bool to_int(string s, int& number)
const char* ptr = s.c_str();
char* end;
int n = strtol(ptr, &end, 10);
-
+
if (end != ptr + s.size())
return false;
-
+
number = n;
return true;
}
// https://www.w3.org/TR/css-syntax-3/#anb-syntax
// I don't use the formal grammar because it creates a lot of unnecessary complexity.
-// Deviations from the standard:
+// Deviations from the standard:
// * escapes are not allowed
// * comments are allowed inside numbers and identifiers: ev/**/en
an_b parse_an_b(string s)
@@ -336,9 +338,9 @@ int find_of_keyword(const css_token_vector& tokens)
}
// :nth-child(An+B [of S]?) https://www.w3.org/TR/selectors-4/#the-nth-child-pseudo
-// :nth-last-child(An+B [of S]?)
+// :nth-last-child(An+B [of S]?)
// where S is a forgiving <complex-selector-list>
-//
+//
// :nth-of-type(An+B) https://www.w3.org/TR/selectors-4/#the-nth-of-type-pseudo
// :nth-last-of-type(An+B)
//
@@ -356,7 +358,7 @@ css_attribute_selector parse_nth_child(const css_token& token, bool of_keyword,
// The standard doesn't specify if pseudo-elements are allowed in this selector list.
// But specifying them will make selector match nothing anyway because
- // "The structural pseudo-classes only apply to elements in the document tree;
+ // "The structural pseudo-classes only apply to elements in the document tree;
// they must never match pseudo-elements." https://www.w3.org/TR/selectors-4/#structural-pseudos
// So I parse as if they were not allowed.
selector.selector_list = parse_selector_list(selector_tokens, forgiving_mode + forbid_pseudo_elements, mode);
@@ -374,10 +376,10 @@ css_attribute_selector parse_nth_child(const css_token& token, bool of_keyword,
an_b x = parse_an_b(str);
if (!x.valid) return {};
-
+
selector.a = x.a;
selector.b = x.b;
-
+
return selector;
}
@@ -540,7 +542,7 @@ css_attribute_selector parse_pseudo_element(const css_token_vector& tokens, int&
{
if (!is_one_of(b.ident(), "before", "after")) // first-line/letter are not supported
return {};
-
+
index += 2;
return {select_pseudo_element, b.ident()};
}
@@ -575,7 +577,7 @@ css_element_selector::ptr parse_compound_selector(const css_token_vector& tokens
// <subclass-selector>*
while (css_attribute_selector sel = parse_subclass_selector(tokens, index, mode))
selector->m_attrs.push_back(sel);
-
+
// [ <pseudo-element-selector> <pseudo-class-selector>* ]*
while (true)
{
@@ -613,7 +615,7 @@ int parse_combinator(const css_token_vector& tokens, int& index)
skip_whitespace(tokens, index);
return tok.ch;
}
-
+
return ws ? ' ' : 0;
}
@@ -662,10 +664,10 @@ bool has_selector(const css_selector& selector, attr_select_type type, const str
if (sel.type == type && (name == "" || equal_i(_s(sel.name), name)))
return true;
}
-
+
if (selector.m_left)
return has_selector(*selector.m_left, type, name);
-
+
return false;
}
@@ -691,7 +693,7 @@ css_selector::vector parse_selector_list(const css_token_vector& tokens, int opt
// in forgiving mode, ignore the bad selector
if (options & forgiving_mode)
continue;
-
+
// in strict mode, entire selector-list fails to parse because of one bad selector
return {};
}
diff --git a/libs/litehtml/src/css_tokenizer.cpp b/libs/litehtml/src/css_tokenizer.cpp
index b2b8761fa4..3daf31f7d0 100644
--- a/libs/litehtml/src/css_tokenizer.cpp
+++ b/libs/litehtml/src/css_tokenizer.cpp
@@ -1,4 +1,5 @@
#include "html.h"
+#include "utf8_strings.h"
#include "css_tokenizer.h"
namespace litehtml
@@ -118,7 +119,7 @@ void css_tokenizer::consume_comments()
if (str[index] == '/' && str[index + 1] == '*')
{
int i = (int)str.find("*/", index + 2);
-
+
if (i != -1)
index = i + 2;
else
@@ -199,7 +200,7 @@ css_token css_tokenizer::consume_string_token(int ending_code_point)
// Otherwise, if the next input code point is a newline, consume it.
else if (str[index] == '\n')
index++;
- // Otherwise, (the stream starts with a valid escape) consume an escaped code point and
+ // Otherwise, (the stream starts with a valid escape) consume an escaped code point and
// append the returned code point to the <string-token>’s value.
else
append_char(token.str, consume_escaped_code_point());
@@ -224,7 +225,7 @@ bool css_tokenizer::would_start_ident_sequence(three_chars chars)
if (c1 == '-')
{
- // If the second code point is an ident-start code point or a U+002D HYPHEN-MINUS, or
+ // If the second code point is an ident-start code point or a U+002D HYPHEN-MINUS, or
// the second and third code points are a valid escape, return true. Otherwise, return false.
return is_ident_start_code_point(c2) || c2 == '-' || (c2 == '\\' && c3 != '\n');
}
@@ -291,13 +292,13 @@ double css_tokenizer::convert_string_to_number(const string& str)
// Divide the string into seven components, in order from left to right:
- // 1. A sign: a single U+002B (+) or U+002D (-), or the empty string.
+ // 1. A sign: a single U+002B (+) or U+002D (-), or the empty string.
// Let s be the number -1 if the sign is U+002D (-); otherwise, let s be the number 1.
double s = 1;
if (*p == '-') s = -1, p++;
else if (*p == '+') p++;
- // 2. An integer part: zero or more digits. If there is at least one digit, let i be the number formed by
+ // 2. An integer part: zero or more digits. If there is at least one digit, let i be the number formed by
// interpreting the digits as a base-10 integer; otherwise, let i be the number 0.
double i = 0;
while (is_digit(*p)) i = i * 10 + digit_value(*p++);
@@ -305,8 +306,8 @@ double css_tokenizer::convert_string_to_number(const string& str)
// 3. A decimal point: a single U+002E (.), or the empty string.
if (*p == '.') p++;
- // 4. A fractional part: zero or more digits. If there is at least one digit, let f be the number formed by
- // interpreting the digits as a base-10 integer and d be the number of digits;
+ // 4. A fractional part: zero or more digits. If there is at least one digit, let f be the number formed by
+ // interpreting the digits as a base-10 integer and d be the number of digits;
// otherwise, let f and d be the number 0.
double f = 0, d = 0;
while (is_digit(*p)) f = f * 10 + digit_value(*p++), d++;
@@ -314,13 +315,13 @@ double css_tokenizer::convert_string_to_number(const string& str)
// 5. An exponent indicator: a single U+0045 (E) or U+0065 (e), or the empty string.
if (*p == 'e' || *p == 'E') p++;
- // 6. An exponent sign: a single U+002B (+) or U+002D (-), or the empty string.
+ // 6. An exponent sign: a single U+002B (+) or U+002D (-), or the empty string.
// Let t be the number -1 if the sign is U+002D (-); otherwise, let t be the number 1.
double t = 1;
if (*p == '-') t = -1, p++;
else if (*p == '+') p++;
- // 7. An exponent: zero or more digits. If there is at least one digit, let e be the number formed by
+ // 7. An exponent: zero or more digits. If there is at least one digit, let e be the number formed by
// interpreting the digits as a base-10 integer; otherwise, let e be the number 0.
double e = 0;
while (is_digit(*p)) e = e * 10 + digit_value(*p++);
@@ -358,11 +359,11 @@ double css_tokenizer::consume_number(css_number_type& type)
append_char(repr, str[index++]);
}
- // 5. If the next 2 or 3 input code points are U+0045 (E) or U+0065 (e),
+ // 5. If the next 2 or 3 input code points are U+0045 (E) or U+0065 (e),
// optionally followed by U+002D (-) or U+002B (+), followed by a digit, then:
bool a = lowcase(str[index]) == 'e' && is_one_of(str[index+1], '+', '-') && is_digit(str[index+2]);
bool b = lowcase(str[index]) == 'e' && is_digit(str[index+1]);
-
+
if (a || b)
{
// 1. Consume them.
@@ -394,7 +395,7 @@ css_token css_tokenizer::consume_numeric_token()
// If the next 3 input code points would start an ident sequence, then:
if (would_start_ident_sequence(peek_chars()))
{
- // 1. Create a <dimension-token> with the same value and type flag as number, and
+ // 1. Create a <dimension-token> with the same value and type flag as number, and
// a unit set initially to the empty string.
css_token token(DIMENSION, number, type);
@@ -405,7 +406,7 @@ css_token css_tokenizer::consume_numeric_token()
return token;
}
- // Otherwise, if the next input code point is U+0025 (%), consume it.
+ // Otherwise, if the next input code point is U+0025 (%), consume it.
// Create a <percentage-token> with the same value as number, and return it.
if (str[index] == '%')
{
@@ -491,7 +492,7 @@ css_token css_tokenizer::consume_url_token()
return {BAD_URL};
case '\\':
- // If the stream starts with a valid escape, consume an escaped code point and
+ // If the stream starts with a valid escape, consume an escaped code point and
// append the returned code point to the <url-token>’s value.
if (str[index] != '\n')
append_char(token.str, consume_escaped_code_point());
@@ -522,7 +523,7 @@ css_token css_tokenizer::consume_ident_like_token()
// Consume an ident sequence, and let string be the result.
auto string = consume_ident_sequence();
- // If string’s value is an ASCII case-insensitive match for "url", and the next input code point is
+ // If string’s value is an ASCII case-insensitive match for "url", and the next input code point is
// U+0028 ((), consume it.
if (lowcase(string) == "url" && str[index] == '(')
{
@@ -543,7 +544,7 @@ css_token css_tokenizer::consume_ident_like_token()
}
}
- // Otherwise, if the next input code point is U+0028 ((), consume it.
+ // Otherwise, if the next input code point is U+0028 ((), consume it.
// Create a <function-token> with its value set to string and return it.
else if (str[index] == '(')
{
@@ -629,7 +630,7 @@ css_token css_tokenizer::consume_token()
index += 2;
token.type = CDC;
}
- // Otherwise, if the input stream starts with an ident sequence, reconsume the current input code point,
+ // Otherwise, if the input stream starts with an ident sequence, reconsume the current input code point,
// consume an ident-like token, and return it.
else if (would_start_ident_sequence({ ch, next._1, next._2 }))
{
@@ -654,7 +655,7 @@ css_token css_tokenizer::consume_token()
break;
case '@':
- // If the next 3 input code points would start an ident sequence, consume an ident sequence,
+ // If the next 3 input code points would start an ident sequence, consume an ident sequence,
// create an <at-keyword-token> with its value set to the returned value, and return it.
if (would_start_ident_sequence(peek_chars()))
{
@@ -667,7 +668,7 @@ css_token css_tokenizer::consume_token()
break;
case '\\':
- // If the input stream starts with a valid escape, reconsume the current input code point,
+ // If the input stream starts with a valid escape, reconsume the current input code point,
// consume an ident-like token, and return it.
if (str[index] != '\n')
{
diff --git a/libs/litehtml/src/document.cpp b/libs/litehtml/src/document.cpp
index 13bfe0e991..d498914081 100644
--- a/libs/litehtml/src/document.cpp
+++ b/libs/litehtml/src/document.cpp
@@ -25,6 +25,7 @@
#include "render_item.h"
#include "render_table.h"
#include "render_block.h"
+#include "document_container.h"
namespace litehtml
{
@@ -36,13 +37,20 @@ document::document(document_container* container)
document::~document()
{
- m_over_element = nullptr;
+ m_over_element = m_active_element = nullptr;
+ if(m_container)
+ {
+ for(auto& font : m_fonts)
+ {
+ m_container->delete_font(font.second.font);
+ }
+ }
}
document::ptr document::createFromString(
- const estring& str,
- document_container* container,
- const string& master_styles,
+ const estring& str,
+ document_container* container,
+ const string& master_styles,
const string& user_styles )
{
// Create litehtml::document
@@ -125,7 +133,7 @@ document::ptr document::createFromString(
doc->m_root_render = doc->m_root->create_render_item(nullptr);
// Now the m_tabular_elements is filled with tabular elements.
- // We have to check the tabular elements for missing table elements
+ // We have to check the tabular elements for missing table elements
// and create the anonymous boxes in visual table layout
doc->fix_tables_layout();
@@ -209,7 +217,7 @@ GumboOutput* document::parse_html(estring str)
{
// https://html.spec.whatwg.org/multipage/parsing.html#the-input-byte-stream
encoding_sniffing_algorithm(str);
- // cannot store output in local variable because gumbo keeps pointers into it,
+ // cannot store output in local variable because gumbo keeps pointers into it,
// which will be accessed later in gumbo_tag_from_original_text
if (str.encoding == encoding::utf_8)
m_text = str;
@@ -434,83 +442,18 @@ element::ptr document::create_element(const char* tag_name, const string_map& at
return newTag;
}
-uint_ptr document::add_font( const char* name, int size, const char* weight, const char* style, const char* decoration, font_metrics* fm )
+uint_ptr document::add_font( const font_description& descr, font_metrics* fm )
{
uint_ptr ret = 0;
- if(!name)
- {
- name = m_container->get_default_font_name();
- }
-
- char strSize[20];
- t_itoa(size, strSize, 20, 10);
+ std::string key = descr.hash();
- string key = name;
- key += ":";
- key += strSize;
- key += ":";
- key += weight;
- key += ":";
- key += style;
- key += ":";
- key += decoration;
-
- if(m_container->m_fonts.find(key) == m_container->m_fonts.end())
+ if(m_fonts.find(key) == m_fonts.end())
{
- font_style fs = (font_style) value_index(style, font_style_strings, font_style_normal);
- int fw = value_index(weight, font_weight_strings, -1);
- if(fw >= 0)
- {
- switch(fw)
- {
- case font_weight_bold:
- fw = 700;
- break;
- case font_weight_bolder:
- fw = 600;
- break;
- case font_weight_lighter:
- fw = 300;
- break;
- case font_weight_normal:
- fw = 400;
- break;
- }
- } else
- {
- fw = atoi(weight);
- if(fw < 100)
- {
- fw = 400;
- }
- }
-
- unsigned int decor = 0;
+ font_item fi = {0, {}};
- if(decoration)
- {
- std::vector<string> tokens;
- split_string(decoration, tokens, " ");
- for(auto & token : tokens)
- {
- if(!t_strcasecmp(token.c_str(), "underline"))
- {
- decor |= font_decoration_underline;
- } else if(!t_strcasecmp(token.c_str(), "line-through"))
- {
- decor |= font_decoration_linethrough;
- } else if(!t_strcasecmp(token.c_str(), "overline"))
- {
- decor |= font_decoration_overline;
- }
- }
- }
-
- font_item fi= {0, {}};
-
- fi.font = m_container->create_font(name, size, fw, fs, decor, &fi.metrics);
- m_container->m_fonts[key] = fi;
+ fi.font = m_container->create_font(descr, this, &fi.metrics);
+ m_fonts[key] = fi;
ret = fi.font;
if(fm)
{
@@ -520,33 +463,18 @@ uint_ptr document::add_font( const char* name, int size, const char* weight, con
return ret;
}
-uint_ptr document::get_font( const char* name, int size, const char* weight, const char* style, const char* decoration, font_metrics* fm )
+uint_ptr document::get_font( const font_description& descr, font_metrics* fm )
{
- if(!size)
+ if(!descr.size)
{
return 0;
}
- if(!name)
- {
- name = m_container->get_default_font_name();
- }
-
- char strSize[20];
- t_itoa(size, strSize, 20, 10);
- string key = name;
- key += ":";
- key += strSize;
- key += ":";
- key += weight;
- key += ":";
- key += style;
- key += ":";
- key += decoration;
+ auto key = descr.hash();
- auto el = m_container->m_fonts.find(key);
+ auto el = m_fonts.find(key);
- if(el != m_container->m_fonts.end())
+ if(el != m_fonts.end())
{
if(fm)
{
@@ -554,7 +482,7 @@ uint_ptr document::get_font( const char* name, int size, const char* weight, con
}
return el->second.font;
}
- return add_font(name, size, weight, style, decoration, fm);
+ return add_font(descr, fm);
}
int document::render( int max_width, render_type rt )
@@ -562,12 +490,12 @@ int document::render( int max_width, render_type rt )
int ret = 0;
if(m_root && m_root_render)
{
- position client_rc;
- m_container->get_client_rect(client_rc);
+ position viewport;
+ m_container->get_viewport(viewport);
containing_block_context cb_context;
cb_context.width = max_width;
cb_context.width.type = containing_block_context::cbc_value_type_absolute;
- cb_context.height = client_rc.height;
+ cb_context.height = viewport.height;
cb_context.height.type = containing_block_context::cbc_value_type_absolute;
if(rt == render_fixed_only)
@@ -737,9 +665,9 @@ bool document::on_mouse_over( int x, int y, int client_x, int client_y, position
}
cursor = m_over_element->css().get_cursor();
}
-
+
m_container->set_cursor(cursor.c_str());
-
+
if(state_was_changed)
{
m_container->on_mouse_event(m_over_element, mouse_event_enter);
@@ -773,6 +701,7 @@ bool document::on_lbutton_down( int x, int y, int client_x, int client_y, positi
}
element::ptr over_el = m_root_render->get_element_by_point(x, y, client_x, client_y);
+ m_active_element = over_el;
bool state_was_changed = false;
@@ -826,7 +755,7 @@ bool document::on_lbutton_up( int /*x*/, int /*y*/, int /*client_x*/, int /*clie
}
if(m_over_element)
{
- if(m_over_element->on_lbutton_up())
+ if(m_over_element->on_lbutton_up(m_active_element == m_over_element))
{
return m_root->find_styles_changes(redraw_boxes);
}
@@ -834,6 +763,26 @@ bool document::on_lbutton_up( int /*x*/, int /*y*/, int /*client_x*/, int /*clie
return false;
}
+bool document::on_button_cancel(position::vector& redraw_boxes) {
+ if(!m_root || !m_root_render)
+ {
+ return false;
+ }
+ m_active_element = nullptr;
+ if(m_over_element)
+ {
+ if(m_over_element->on_mouse_leave())
+ {
+ m_container->on_mouse_event(m_over_element, mouse_event_leave);
+ }
+ if(m_over_element->on_lbutton_up(false))
+ {
+ return m_root->find_styles_changes(redraw_boxes);
+ }
+ }
+ return false;
+}
+
void document::get_fixed_boxes( position::vector& fixed_boxes )
{
fixed_boxes = m_fixed_boxes;
@@ -1129,7 +1078,7 @@ void document::append_children_from_string(element& parent, const char* str)
child->compute_styles();
// Now the m_tabular_elements is filled with tabular elements.
- // We have to check the tabular elements for missing table elements
+ // We have to check the tabular elements for missing table elements
// and create the anonymous boxes in visual table layout
fix_tables_layout();
diff --git a/libs/litehtml/src/document_container.cpp b/libs/litehtml/src/document_container.cpp
index 8c3aea61bd..95f45c62cb 100644
--- a/libs/litehtml/src/document_container.cpp
+++ b/libs/litehtml/src/document_container.cpp
@@ -1,4 +1,4 @@
-#include "html.h"
+#include "utf8_strings.h"
#include "document_container.h"
void litehtml::document_container::split_text(const char* text, const std::function<void(const char*)>& on_word, const std::function<void(const char*)>& on_space)
diff --git a/libs/litehtml/src/el_anchor.cpp b/libs/litehtml/src/el_anchor.cpp
index 372e4afb50..2491c60033 100644
--- a/libs/litehtml/src/el_anchor.cpp
+++ b/libs/litehtml/src/el_anchor.cpp
@@ -1,6 +1,6 @@
-#include "html.h"
#include "el_anchor.h"
#include "document.h"
+#include "document_container.h"
litehtml::el_anchor::el_anchor(const std::shared_ptr<litehtml::document>& doc) : html_tag(doc)
{
diff --git a/libs/litehtml/src/el_base.cpp b/libs/litehtml/src/el_base.cpp
index baf0256539..b2db13e09f 100644
--- a/libs/litehtml/src/el_base.cpp
+++ b/libs/litehtml/src/el_base.cpp
@@ -1,10 +1,10 @@
-#include "html.h"
#include "el_base.h"
#include "document.h"
+#include "document_container.h"
litehtml::el_base::el_base(const std::shared_ptr<document>& doc) : html_tag(doc)
{
-
+
}
void litehtml::el_base::parse_attributes()
diff --git a/libs/litehtml/src/el_body.cpp b/libs/litehtml/src/el_body.cpp
index 3d35f8f758..899f27f041 100644
--- a/libs/litehtml/src/el_body.cpp
+++ b/libs/litehtml/src/el_body.cpp
@@ -1,4 +1,3 @@
-#include "html.h"
#include "el_body.h"
#include "document.h"
diff --git a/libs/litehtml/src/el_break.cpp b/libs/litehtml/src/el_break.cpp
index f13b2e3cf8..f190d06c1b 100644
--- a/libs/litehtml/src/el_break.cpp
+++ b/libs/litehtml/src/el_break.cpp
@@ -1,4 +1,3 @@
-#include "html.h"
#include "el_break.h"
litehtml::el_break::el_break(const std::shared_ptr<litehtml::document>& doc) : html_tag(doc)
diff --git a/libs/litehtml/src/el_cdata.cpp b/libs/litehtml/src/el_cdata.cpp
index e5948bff13..c3b431b3f7 100644
--- a/libs/litehtml/src/el_cdata.cpp
+++ b/libs/litehtml/src/el_cdata.cpp
@@ -1,4 +1,3 @@
-#include "html.h"
#include "el_cdata.h"
litehtml::el_cdata::el_cdata(const std::shared_ptr<document>& doc) : element(doc)
diff --git a/libs/litehtml/src/el_comment.cpp b/libs/litehtml/src/el_comment.cpp
index 1ec934d046..1a29a51662 100644
--- a/libs/litehtml/src/el_comment.cpp
+++ b/libs/litehtml/src/el_comment.cpp
@@ -1,4 +1,3 @@
-#include "html.h"
#include "el_comment.h"
litehtml::el_comment::el_comment(const std::shared_ptr<document>& doc) : element(doc)
diff --git a/libs/litehtml/src/el_div.cpp b/libs/litehtml/src/el_div.cpp
index 983d45ab2a..a23681cd1d 100644
--- a/libs/litehtml/src/el_div.cpp
+++ b/libs/litehtml/src/el_div.cpp
@@ -1,5 +1,5 @@
-#include "html.h"
#include "el_div.h"
+#include "document.h"
litehtml::el_div::el_div(const document::ptr& doc) : html_tag(doc)
diff --git a/libs/litehtml/src/el_font.cpp b/libs/litehtml/src/el_font.cpp
index 3d5f6d9f73..e8e1f7e231 100644
--- a/libs/litehtml/src/el_font.cpp
+++ b/libs/litehtml/src/el_font.cpp
@@ -1,5 +1,5 @@
-#include "html.h"
#include "el_font.h"
+#include "document.h"
litehtml::el_font::el_font(const std::shared_ptr<document>& doc) : html_tag(doc)
diff --git a/libs/litehtml/src/el_image.cpp b/libs/litehtml/src/el_image.cpp
index 0dee84e011..7ac81193bb 100644
--- a/libs/litehtml/src/el_image.cpp
+++ b/libs/litehtml/src/el_image.cpp
@@ -1,6 +1,6 @@
-#include "html.h"
#include "el_image.h"
#include "render_image.h"
+#include "document_container.h"
litehtml::el_image::el_image(const document::ptr& doc) : html_tag(doc)
{
@@ -82,4 +82,4 @@ std::shared_ptr<litehtml::render_item> litehtml::el_image::create_render_item(co
auto ret = std::make_shared<render_item_image>(shared_from_this());
ret->parent(parent_ri);
return ret;
-}
+} \ No newline at end of file
diff --git a/libs/litehtml/src/el_link.cpp b/libs/litehtml/src/el_link.cpp
index aa3bc76597..2783feafca 100644
--- a/libs/litehtml/src/el_link.cpp
+++ b/libs/litehtml/src/el_link.cpp
@@ -1,7 +1,7 @@
-#include "html.h"
#include "el_link.h"
#include "document.h"
-
+#include "document_container.h"
+#include <cstring>
litehtml::el_link::el_link(const std::shared_ptr<document>& doc) : litehtml::html_tag(doc)
{
diff --git a/libs/litehtml/src/el_para.cpp b/libs/litehtml/src/el_para.cpp
index 5d79151351..0362be9dfd 100644
--- a/libs/litehtml/src/el_para.cpp
+++ b/libs/litehtml/src/el_para.cpp
@@ -1,4 +1,3 @@
-#include "html.h"
#include "el_para.h"
#include "document.h"
diff --git a/libs/litehtml/src/el_script.cpp b/libs/litehtml/src/el_script.cpp
index 4b598a137e..857e47fc5f 100644
--- a/libs/litehtml/src/el_script.cpp
+++ b/libs/litehtml/src/el_script.cpp
@@ -1,4 +1,3 @@
-#include "html.h"
#include "el_script.h"
#include "document.h"
diff --git a/libs/litehtml/src/el_style.cpp b/libs/litehtml/src/el_style.cpp
index cc2f0bab6d..f0fbc66fa2 100644
--- a/libs/litehtml/src/el_style.cpp
+++ b/libs/litehtml/src/el_style.cpp
@@ -1,4 +1,3 @@
-#include "html.h"
#include "el_style.h"
#include "document.h"
@@ -21,8 +20,17 @@ void litehtml::el_style::parse_attributes()
bool litehtml::el_style::appendChild(const ptr &el)
{
- m_children.push_back(el);
- return true;
+ if(el && el->is_text())
+ {
+ m_children.push_back(el);
+ return true;
+ }
+ return false;
+}
+
+void litehtml::el_style::compute_styles(bool /* recursive */)
+{
+ css_w().set_display(display_none);
}
litehtml::string_id litehtml::el_style::tag() const
diff --git a/libs/litehtml/src/el_table.cpp b/libs/litehtml/src/el_table.cpp
index 82b02c6921..c3ce2a9ffc 100644
--- a/libs/litehtml/src/el_table.cpp
+++ b/libs/litehtml/src/el_table.cpp
@@ -1,58 +1,47 @@
-#include "html.h"
#include "el_table.h"
#include "document.h"
-#include "iterators.h"
namespace litehtml
{
-el_table::el_table(const shared_ptr<document>& doc) : html_tag(doc)
-{
-}
-
-bool el_table::appendChild(const element::ptr& el)
-{
- if(!el) return false;
- if( el->tag() == _tbody_ ||
- el->tag() == _thead_ ||
- el->tag() == _tfoot_ ||
- el->tag() == _caption_)
+ el_table::el_table(const shared_ptr<document>& doc) :
+ html_tag(doc)
{
- return html_tag::appendChild(el);
}
- return false;
-}
-void el_table::parse_attributes()
-{
- // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:attr-table-width
- const char* str = get_attr("width");
- if (str)
- map_to_dimension_property_ignoring_zero(_width_, str);
-
- // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:attr-table-height
- str = get_attr("height");
- if (str)
- map_to_dimension_property(_height_, str);
-
- // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:attr-table-cellspacing
- str = get_attr("cellspacing");
- if (str)
- map_to_pixel_length_property(_border_spacing_, str);
-
- // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:attr-table-border
- str = get_attr("border");
- if (str)
- map_to_pixel_length_property_with_default_value(_border_width_, str, 1);
-
- // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:attr-background
- str = get_attr("bgcolor");
- if (str)
+ bool el_table::appendChild(const element::ptr& el)
{
- m_style.add_property(_background_color_, str, "", false, get_document()->container());
+ if(!el) return false;
+ if(el->tag() == _tbody_ || el->tag() == _thead_ || el->tag() == _tfoot_ || el->tag() == _caption_)
+ {
+ return html_tag::appendChild(el);
+ }
+ return false;
}
- html_tag::parse_attributes();
-}
+ void el_table::parse_attributes()
+ {
+ // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:attr-table-width
+ const char* str = get_attr("width");
+ if(str) map_to_dimension_property_ignoring_zero(_width_, str);
+
+ // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:attr-table-height
+ str = get_attr("height");
+ if(str) map_to_dimension_property(_height_, str);
+
+ // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:attr-table-cellspacing
+ str = get_attr("cellspacing");
+ if(str) map_to_pixel_length_property(_border_spacing_, str);
+
+ // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:attr-table-border
+ str = get_attr("border");
+ if(str) map_to_pixel_length_property_with_default_value(_border_width_, str, 1);
+
+ // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:attr-background
+ str = get_attr("bgcolor");
+ if(str) { m_style.add_property(_background_color_, str, "", false, get_document()->container()); }
+
+ html_tag::parse_attributes();
+ }
-} // namespace litehtml \ No newline at end of file
+} // namespace litehtml
diff --git a/libs/litehtml/src/el_td.cpp b/libs/litehtml/src/el_td.cpp
index 659bfb1bc7..f665c7c095 100644
--- a/libs/litehtml/src/el_td.cpp
+++ b/libs/litehtml/src/el_td.cpp
@@ -1,5 +1,5 @@
-#include "html.h"
#include "el_td.h"
+#include "document.h"
namespace litehtml
{
diff --git a/libs/litehtml/src/el_text.cpp b/libs/litehtml/src/el_text.cpp
index 70ed82e6af..042da32651 100644
--- a/libs/litehtml/src/el_text.cpp
+++ b/libs/litehtml/src/el_text.cpp
@@ -1,6 +1,7 @@
#include "html.h"
#include "el_text.h"
#include "render_item.h"
+#include "document_container.h"
litehtml::el_text::el_text(const char* text, const document::ptr& doc) : element(doc)
{
@@ -28,7 +29,7 @@ void litehtml::el_text::compute_styles(bool /*recursive*/)
element::ptr el_parent = parent();
if (el_parent)
{
- css_w().set_line_height(el_parent->css().get_line_height());
+ css_w().line_height_w() = el_parent->css().line_height();
css_w().set_font(el_parent->css().get_font());
css_w().set_font_metrics(el_parent->css().get_font_metrics());
css_w().set_white_space(el_parent->css().get_white_space());
diff --git a/libs/litehtml/src/el_title.cpp b/libs/litehtml/src/el_title.cpp
index f0e42311b4..7752d49a82 100644
--- a/libs/litehtml/src/el_title.cpp
+++ b/libs/litehtml/src/el_title.cpp
@@ -1,6 +1,6 @@
-#include "html.h"
#include "el_title.h"
#include "document.h"
+#include "document_container.h"
litehtml::el_title::el_title(const std::shared_ptr<document>& doc) : html_tag(doc)
{
diff --git a/libs/litehtml/src/el_tr.cpp b/libs/litehtml/src/el_tr.cpp
index 5b80cc1221..78c53f4e80 100644
--- a/libs/litehtml/src/el_tr.cpp
+++ b/libs/litehtml/src/el_tr.cpp
@@ -1,5 +1,5 @@
-#include "html.h"
#include "el_tr.h"
+#include "document.h"
litehtml::el_tr::el_tr(const std::shared_ptr<document>& doc) : html_tag(doc)
diff --git a/libs/litehtml/src/element.cpp b/libs/litehtml/src/element.cpp
index fb4c2c2948..8672b9de7c 100644
--- a/libs/litehtml/src/element.cpp
+++ b/libs/litehtml/src/element.cpp
@@ -317,7 +317,7 @@ string litehtml::element::get_counters_value(const string_vector& parameters)
litehtml::trim(delims, "\"'");
string_vector values;
-
+
element::ptr current = shared_from_this();
while (current != nullptr)
{
@@ -362,7 +362,7 @@ bool litehtml::element::find_counter(const string_id& counter_name_id, std::map<
}
current = current->parent();
}
-
+
return false;
}
@@ -451,7 +451,7 @@ bool element::is_text() const LITEHTML_RETURN_FUNC(false)
bool element::on_mouse_over() LITEHTML_RETURN_FUNC(false)
bool element::on_mouse_leave() LITEHTML_RETURN_FUNC(false)
bool element::on_lbutton_down() LITEHTML_RETURN_FUNC(false)
-bool element::on_lbutton_up() LITEHTML_RETURN_FUNC(false)
+bool element::on_lbutton_up(const bool /*is_click*/) LITEHTML_RETURN_FUNC(false)
bool element::set_pseudo_class( string_id /*cls*/, bool /*add*/ ) LITEHTML_RETURN_FUNC(false)
bool element::set_class( const char* /*pclass*/, bool /*add*/ ) LITEHTML_RETURN_FUNC(false)
bool element::is_replaced() const LITEHTML_RETURN_FUNC(false)
diff --git a/libs/litehtml/src/encodings.cpp b/libs/litehtml/src/encodings.cpp
index 9cb64d821b..f56c0f10fe 100644
--- a/libs/litehtml/src/encodings.cpp
+++ b/libs/litehtml/src/encodings.cpp
@@ -1,4 +1,6 @@
#include "html.h"
+#include "os_types.h"
+#include "utf8_strings.h"
#include "encodings.h"
#include <cassert>
@@ -1888,7 +1890,7 @@ loop:
// 1.
index = (int)str.find_first_of(" \t\r\n\f>", index);
if (index == -1 || end_condition(index)) throw 0; // abort prescan
-
+
// 2.
string tmp;
while (prescan_get_attribute(str, index, tmp, tmp)) {}
diff --git a/libs/litehtml/src/flex_item.cpp b/libs/litehtml/src/flex_item.cpp
index b117c22415..687c7374e6 100644
--- a/libs/litehtml/src/flex_item.cpp
+++ b/libs/litehtml/src/flex_item.cpp
@@ -1,8 +1,6 @@
-#include "html.h"
+#include <cmath>
#include "flex_item.h"
-#include "render_item.h"
#include "flex_line.h"
-#include <cmath>
void litehtml::flex_item::init(const litehtml::containing_block_context &self_size,
litehtml::formatting_context *fmt_ctx, flex_align_items align_items)
diff --git a/libs/litehtml/src/flex_line.cpp b/libs/litehtml/src/flex_line.cpp
index ce45a06335..4e22d0aca8 100644
--- a/libs/litehtml/src/flex_line.cpp
+++ b/libs/litehtml/src/flex_line.cpp
@@ -1,7 +1,5 @@
-#include "html.h"
#include "flex_line.h"
#include "flex_item.h"
-#include "render_item.h"
void litehtml::flex_line::distribute_free_space(int container_main_size)
{
diff --git a/libs/litehtml/src/formatting_context.cpp b/libs/litehtml/src/formatting_context.cpp
index e85e990c9c..ab5e65a006 100644
--- a/libs/litehtml/src/formatting_context.cpp
+++ b/libs/litehtml/src/formatting_context.cpp
@@ -1,4 +1,3 @@
-#include "html.h"
#include "render_item.h"
#include "formatting_context.h"
diff --git a/libs/litehtml/src/gumbo/CMakeLists.txt b/libs/litehtml/src/gumbo/CMakeLists.txt
index 7282604893..9c0dc5b072 100644
--- a/libs/litehtml/src/gumbo/CMakeLists.txt
+++ b/libs/litehtml/src/gumbo/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.5)
+cmake_minimum_required(VERSION 3.11)
project(gumbo C)
diff --git a/libs/litehtml/src/gumbo/char_ref.c b/libs/litehtml/src/gumbo/char_ref.c
index a1d74fd5df..406afad032 100644
--- a/libs/litehtml/src/gumbo/char_ref.c
+++ b/libs/litehtml/src/gumbo/char_ref.c
@@ -136,7 +136,7 @@ static bool consume_numeric_ref(
return false;
}
- int codepoint = 0;
+ unsigned int codepoint = 0;
bool status = true;
do {
codepoint = (codepoint * (is_hex ? 16 : 10)) + digit;
diff --git a/libs/litehtml/src/gumbo/char_ref.rl b/libs/litehtml/src/gumbo/char_ref.rl
index 139a4bbd33..464e1690ba 100644
--- a/libs/litehtml/src/gumbo/char_ref.rl
+++ b/libs/litehtml/src/gumbo/char_ref.rl
@@ -162,7 +162,7 @@ static bool consume_numeric_ref(
return false;
}
- int codepoint = 0;
+ unsigned int codepoint = 0;
bool status = true;
do {
codepoint = (codepoint * (is_hex ? 16 : 10)) + digit;
diff --git a/libs/litehtml/src/gumbo/include/gumbo.h b/libs/litehtml/src/gumbo/include/gumbo.h
index f8137cf061..83cd22d5df 100644
--- a/libs/litehtml/src/gumbo/include/gumbo.h
+++ b/libs/litehtml/src/gumbo/include/gumbo.h
@@ -389,7 +389,10 @@ typedef enum {
*/
GUMBO_INSERTION_CONVERTED_FROM_END_TAG = 1 << 4,
- /** A flag for nodes that are converted from the parse of an <isindex> tag. */
+ /**
+ * Deprecated! Do not use!
+ * It's not used anymore since special handling for <isindex> is obsolete.
+ */
GUMBO_INSERTION_FROM_ISINDEX = 1 << 5,
/** A flag for <image> tags that are rewritten as <img>. */
diff --git a/libs/litehtml/src/gumbo/include/gumbo/tag_enum.h b/libs/litehtml/src/gumbo/include/gumbo/tag_enum.h
index 7a33d1e114..4237b1dec4 100644
--- a/libs/litehtml/src/gumbo/include/gumbo/tag_enum.h
+++ b/libs/litehtml/src/gumbo/include/gumbo/tag_enum.h
@@ -151,5 +151,6 @@ GUMBO_TAG_MULTICOL,
GUMBO_TAG_NOBR,
GUMBO_TAG_SPACER,
GUMBO_TAG_DIALOG,
+GUMBO_TAG_SEARCH,
GUMBO_TAG_TT,
GUMBO_TAG_RTC,
diff --git a/libs/litehtml/src/gumbo/include/gumbo/tag_gperf.h b/libs/litehtml/src/gumbo/include/gumbo/tag_gperf.h
index 525453946f..10691e473d 100644
--- a/libs/litehtml/src/gumbo/include/gumbo/tag_gperf.h
+++ b/libs/litehtml/src/gumbo/include/gumbo/tag_gperf.h
@@ -2,32 +2,32 @@ static unsigned int tag_hash(register const char *str, register size_t len)
{
static unsigned short asso_values[] =
{
- 274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
- 274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
- 274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
- 274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
- 274, 274, 274, 274, 274, 274, 274, 274, 274, 30,
- 27, 27, 9, 6, 3, 6, 6, 3, 274, 274,
- 274, 274, 274, 274, 274, 78, 3, 171, 12, 30,
- 39, 129, 12, 105, 24, 156, 9, 51, 60, 87,
- 12, 96, 3, 6, 18, 75, 99, 96, 36, 123,
- 274, 274, 274, 274, 274, 274, 274, 78, 3, 171,
- 12, 30, 39, 129, 12, 105, 24, 156, 9, 51,
- 60, 87, 12, 96, 3, 6, 18, 75, 99, 96,
- 36, 123, 274, 274, 274, 274, 274, 274, 274, 274,
- 274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
- 274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
- 274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
- 274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
- 274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
- 274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
- 274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
- 274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
- 274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
- 274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
- 274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
- 274, 274, 274, 274, 274, 274, 274, 274, 274, 274,
- 274, 274, 274, 274, 274, 274, 274, 274, 274
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 9,
+ 5, 4, 2, 2, 1, 2, 1, 1, 284, 284,
+ 284, 284, 284, 284, 284, 56, 62, 156, 5, 14,
+ 47, 102, 3, 78, 32, 136, 10, 28, 36, 61,
+ 22, 108, 1, 2, 7, 55, 80, 123, 115, 76,
+ 284, 284, 284, 284, 284, 284, 284, 56, 62, 156,
+ 5, 14, 47, 102, 3, 78, 32, 136, 10, 28,
+ 36, 61, 22, 108, 1, 2, 7, 55, 80, 123,
+ 115, 76, 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284
};
register unsigned int hval = len;
@@ -49,239 +49,244 @@ static const unsigned char kGumboTagMap[] = {
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
- GUMBO_TAG_LAST,
- GUMBO_TAG_LAST,
- GUMBO_TAG_B,
- GUMBO_TAG_LAST,
- GUMBO_TAG_LAST,
- GUMBO_TAG_LAST,
- GUMBO_TAG_LAST,
- GUMBO_TAG_LAST,
GUMBO_TAG_S,
GUMBO_TAG_LAST,
- GUMBO_TAG_LAST,
- GUMBO_TAG_LAST,
- GUMBO_TAG_LAST,
- GUMBO_TAG_LAST,
- GUMBO_TAG_LAST,
GUMBO_TAG_H6,
- GUMBO_TAG_SPACER,
- GUMBO_TAG_LAST,
- GUMBO_TAG_RP,
- GUMBO_TAG_LAST,
- GUMBO_TAG_P,
GUMBO_TAG_H5,
- GUMBO_TAG_DIR,
- GUMBO_TAG_LAST,
GUMBO_TAG_H4,
- GUMBO_TAG_LAST,
- GUMBO_TAG_LAST,
- GUMBO_TAG_SMALL,
+ GUMBO_TAG_H3,
+ GUMBO_TAG_SPACER,
+ GUMBO_TAG_H2,
GUMBO_TAG_HEADER,
- GUMBO_TAG_SAMP,
- GUMBO_TAG_LABEL,
- GUMBO_TAG_DEL,
- GUMBO_TAG_DETAILS,
- GUMBO_TAG_RB,
- GUMBO_TAG_LEGEND,
+ GUMBO_TAG_SEARCH,
GUMBO_TAG_HEAD,
- GUMBO_TAG_BASEFONT,
+ GUMBO_TAG_H1,
+ GUMBO_TAG_DETAILS,
GUMBO_TAG_SELECT,
+ GUMBO_TAG_DIR,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_DEL,
GUMBO_TAG_LAST,
- GUMBO_TAG_H3,
GUMBO_TAG_SOURCE,
- GUMBO_TAG_BGSOUND,
- GUMBO_TAG_H2,
- GUMBO_TAG_SUB,
- GUMBO_TAG_BASE,
+ GUMBO_TAG_LEGEND,
GUMBO_TAG_DATALIST,
- GUMBO_TAG_FOOTER,
GUMBO_TAG_LAST,
- GUMBO_TAG_H1,
- GUMBO_TAG_HGROUP,
+ GUMBO_TAG_RP,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
- GUMBO_TAG_SUP,
- GUMBO_TAG_PICTURE,
- GUMBO_TAG_EMBED,
+ GUMBO_TAG_LABEL,
+ GUMBO_TAG_TABLE,
+ GUMBO_TAG_TEMPLATE,
+ GUMBO_TAG_SAMP,
GUMBO_TAG_LAST,
GUMBO_TAG_TIME,
GUMBO_TAG_TITLE,
- GUMBO_TAG_XMP,
- GUMBO_TAG_FONT,
- GUMBO_TAG_TABLE,
+ GUMBO_TAG_METER,
GUMBO_TAG_LAST,
+ GUMBO_TAG_SMALL,
+ GUMBO_TAG_MATH,
GUMBO_TAG_LAST,
- GUMBO_TAG_TEMPLATE,
- GUMBO_TAG_SCRIPT,
GUMBO_TAG_NOBR,
- GUMBO_TAG_METER,
- GUMBO_TAG_LAST,
- GUMBO_TAG_FOREIGNOBJECT,
- GUMBO_TAG_FIELDSET,
GUMBO_TAG_LAST,
GUMBO_TAG_SPAN,
+ GUMBO_TAG_P,
+ GUMBO_TAG_EMBED,
GUMBO_TAG_NOFRAMES,
- GUMBO_TAG_MAP,
- GUMBO_TAG_MATH,
- GUMBO_TAG_PARAM,
- GUMBO_TAG_LAST,
- GUMBO_TAG_NOEMBED,
- GUMBO_TAG_BR,
- GUMBO_TAG_FIGURE,
GUMBO_TAG_SECTION,
- GUMBO_TAG_LAST,
- GUMBO_TAG_LAST,
+ GUMBO_TAG_NOEMBED,
+ GUMBO_TAG_NEXTID,
GUMBO_TAG_LAST,
GUMBO_TAG_NOSCRIPT,
- GUMBO_TAG_NEXTID,
+ GUMBO_TAG_PICTURE,
+ GUMBO_TAG_MARQUEE,
+ GUMBO_TAG_FOOTER,
+ GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
+ GUMBO_TAG_MAP,
+ GUMBO_TAG_FONT,
+ GUMBO_TAG_PARAM,
GUMBO_TAG_HR,
- GUMBO_TAG_MGLYPH,
+ GUMBO_TAG_SCRIPT,
+ GUMBO_TAG_HGROUP,
GUMBO_TAG_LAST,
+ GUMBO_TAG_TR,
GUMBO_TAG_EM,
+ GUMBO_TAG_MENUITEM,
+ GUMBO_TAG_FOREIGNOBJECT,
+ GUMBO_TAG_MGLYPH,
+ GUMBO_TAG_DATA,
+ GUMBO_TAG_APPLET,
+ GUMBO_TAG_FIELDSET,
+ GUMBO_TAG_MAIN,
+ GUMBO_TAG_TEXTAREA,
+ GUMBO_TAG_ABBR,
GUMBO_TAG_LAST,
+ GUMBO_TAG_FIGURE,
+ GUMBO_TAG_DL,
+ GUMBO_TAG_RB,
GUMBO_TAG_FORM,
- GUMBO_TAG_TR,
GUMBO_TAG_LAST,
- GUMBO_TAG_MARQUEE,
+ GUMBO_TAG_BASEFONT,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_BASE,
+ GUMBO_TAG_LAST,
GUMBO_TAG_PROGRESS,
+ GUMBO_TAG_OBJECT,
+ GUMBO_TAG_VAR,
+ GUMBO_TAG_MENU,
+ GUMBO_TAG_META,
+ GUMBO_TAG_MO,
+ GUMBO_TAG_OPTGROUP,
+ GUMBO_TAG_PRE,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
- GUMBO_TAG_MULTICOL,
- GUMBO_TAG_BUTTON,
- GUMBO_TAG_DATA,
+ GUMBO_TAG_TFOOT,
+ GUMBO_TAG_DIV,
+ GUMBO_TAG_PLAINTEXT,
+ GUMBO_TAG_LI,
GUMBO_TAG_LAST,
- GUMBO_TAG_APPLET,
+ GUMBO_TAG_TBODY,
+ GUMBO_TAG_FIGCAPTION,
GUMBO_TAG_LAST,
- GUMBO_TAG_DL,
+ GUMBO_TAG_OPTION,
+ GUMBO_TAG_BGSOUND,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
- GUMBO_TAG_OPTGROUP,
GUMBO_TAG_LAST,
- GUMBO_TAG_ABBR,
- GUMBO_TAG_TEXTAREA,
- GUMBO_TAG_VAR,
- GUMBO_TAG_FIGCAPTION,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_U,
+ GUMBO_TAG_MS,
+ GUMBO_TAG_A,
+ GUMBO_TAG_DD,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_TD,
+ GUMBO_TAG_FRAMESET,
+ GUMBO_TAG_MI,
+ GUMBO_TAG_IMAGE,
+ GUMBO_TAG_BR,
+ GUMBO_TAG_FRAME,
+ GUMBO_TAG_DFN,
+ GUMBO_TAG_DIALOG,
+ GUMBO_TAG_NAV,
+ GUMBO_TAG_B,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_UL,
+ GUMBO_TAG_LISTING,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_ARTICLE,
GUMBO_TAG_RT,
- GUMBO_TAG_PRE,
- GUMBO_TAG_HTML,
- GUMBO_TAG_MENUITEM,
- GUMBO_TAG_DIV,
+ GUMBO_TAG_OL,
+ GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
- GUMBO_TAG_LI,
- GUMBO_TAG_PLAINTEXT,
- GUMBO_TAG_MAIN,
GUMBO_TAG_DT,
+ GUMBO_TAG_ACRONYM,
+ GUMBO_TAG_TT,
+ GUMBO_TAG_HTML,
+ GUMBO_TAG_WBR,
+ GUMBO_TAG_SUP,
+ GUMBO_TAG_BODY,
+ GUMBO_TAG_STYLE,
+ GUMBO_TAG_STRIKE,
GUMBO_TAG_LAST,
GUMBO_TAG_BLOCKQUOTE,
+ GUMBO_TAG_TH,
GUMBO_TAG_LAST,
- GUMBO_TAG_WBR,
- GUMBO_TAG_BODY,
- GUMBO_TAG_TT,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
- GUMBO_TAG_STYLE,
- GUMBO_TAG_STRIKE,
GUMBO_TAG_LAST,
- GUMBO_TAG_FRAMESET,
- GUMBO_TAG_OBJECT,
- GUMBO_TAG_MENU,
- GUMBO_TAG_MO,
+ GUMBO_TAG_THEAD,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_ASIDE,
+ GUMBO_TAG_VIDEO,
+ GUMBO_TAG_I,
+ GUMBO_TAG_KBD,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_LINK,
+ GUMBO_TAG_MULTICOL,
+ GUMBO_TAG_XMP,
+ GUMBO_TAG_MTEXT,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_CENTER,
+ GUMBO_TAG_ADDRESS,
+ GUMBO_TAG_DESC,
+ GUMBO_TAG_CANVAS,
+ GUMBO_TAG_COL,
+ GUMBO_TAG_AREA,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_MARK,
+ GUMBO_TAG_MN,
+ GUMBO_TAG_CODE,
+ GUMBO_TAG_IFRAME,
GUMBO_TAG_BIG,
- GUMBO_TAG_META,
- GUMBO_TAG_TFOOT,
- GUMBO_TAG_OUTPUT,
GUMBO_TAG_LAST,
- GUMBO_TAG_FRAME,
+ GUMBO_TAG_MALIGNMARK,
GUMBO_TAG_LAST,
- GUMBO_TAG_U,
- GUMBO_TAG_IMAGE,
+ GUMBO_TAG_KEYGEN,
+ GUMBO_TAG_SUB,
+ GUMBO_TAG_SVG,
+ GUMBO_TAG_CITE,
GUMBO_TAG_LAST,
- GUMBO_TAG_LISTING,
- GUMBO_TAG_DD,
- GUMBO_TAG_DIALOG,
- GUMBO_TAG_A,
- GUMBO_TAG_MS,
- GUMBO_TAG_OPTION,
GUMBO_TAG_LAST,
- GUMBO_TAG_TD,
+ GUMBO_TAG_COLGROUP,
+ GUMBO_TAG_ANNOTATION_XML,
+ GUMBO_TAG_OUTPUT,
GUMBO_TAG_LAST,
+ GUMBO_TAG_INS,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
- GUMBO_TAG_RUBY,
- GUMBO_TAG_MI,
GUMBO_TAG_LAST,
+ GUMBO_TAG_RUBY,
GUMBO_TAG_LAST,
- GUMBO_TAG_MTEXT,
+ GUMBO_TAG_INPUT,
GUMBO_TAG_LAST,
GUMBO_TAG_SUMMARY,
- GUMBO_TAG_UL,
- GUMBO_TAG_NAV,
- GUMBO_TAG_ACRONYM,
- GUMBO_TAG_TBODY,
GUMBO_TAG_LAST,
- GUMBO_TAG_LINK,
GUMBO_TAG_LAST,
- GUMBO_TAG_DFN,
+ GUMBO_TAG_TRACK,
+ GUMBO_TAG_CAPTION,
+ GUMBO_TAG_IMG,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
- GUMBO_TAG_OL,
- GUMBO_TAG_COL,
GUMBO_TAG_LAST,
- GUMBO_TAG_TH,
GUMBO_TAG_LAST,
- GUMBO_TAG_ARTICLE,
- GUMBO_TAG_THEAD,
- GUMBO_TAG_CENTER,
- GUMBO_TAG_Q,
- GUMBO_TAG_COLGROUP,
- GUMBO_TAG_CANVAS,
GUMBO_TAG_LAST,
- GUMBO_TAG_ANNOTATION_XML,
GUMBO_TAG_LAST,
- GUMBO_TAG_DESC,
- GUMBO_TAG_VIDEO,
- GUMBO_TAG_KBD,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
+ GUMBO_TAG_Q,
GUMBO_TAG_LAST,
- GUMBO_TAG_AUDIO,
+ GUMBO_TAG_BUTTON,
GUMBO_TAG_LAST,
- GUMBO_TAG_CODE,
- GUMBO_TAG_MN,
- GUMBO_TAG_INS,
- GUMBO_TAG_I,
- GUMBO_TAG_ASIDE,
GUMBO_TAG_LAST,
- GUMBO_TAG_CITE,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
- GUMBO_TAG_ADDRESS,
GUMBO_TAG_LAST,
GUMBO_TAG_BDO,
- GUMBO_TAG_MARK,
- GUMBO_TAG_INPUT,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
- GUMBO_TAG_MALIGNMARK,
+ GUMBO_TAG_STRONG,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_AUDIO,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
- GUMBO_TAG_KEYGEN,
- GUMBO_TAG_AREA,
GUMBO_TAG_LAST,
- GUMBO_TAG_STRONG,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_BDI,
@@ -290,22 +295,23 @@ static const unsigned char kGumboTagMap[] = {
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
- GUMBO_TAG_IFRAME,
- GUMBO_TAG_ISINDEX,
GUMBO_TAG_LAST,
- GUMBO_TAG_IMG,
- GUMBO_TAG_CAPTION,
- GUMBO_TAG_BLINK,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
- GUMBO_TAG_TRACK,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
- GUMBO_TAG_SVG,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_BLINK,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
@@ -317,5 +323,9 @@ static const unsigned char kGumboTagMap[] = {
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
GUMBO_TAG_LAST,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_ISINDEX,
+ GUMBO_TAG_LAST,
+ GUMBO_TAG_LAST,
GUMBO_TAG_RTC
};
diff --git a/libs/litehtml/src/gumbo/include/gumbo/tag_sizes.h b/libs/litehtml/src/gumbo/include/gumbo/tag_sizes.h
index 5b93c22fa2..9dc9529995 100644
--- a/libs/litehtml/src/gumbo/include/gumbo/tag_sizes.h
+++ b/libs/litehtml/src/gumbo/include/gumbo/tag_sizes.h
@@ -1,4 +1,4 @@
// Generated via `gentags.py src/tag.in`.
// Do not edit; edit src/tag.in instead.
// clang-format off
-4, 4, 5, 4, 4, 4, 5, 6, 8, 8, 4, 7, 7, 3, 5, 2, 2, 2, 2, 2, 2, 6, 6, 6, 7, 1, 2, 3, 10, 2, 2, 2, 2, 2, 2, 6, 10, 4, 3, 1, 2, 6, 5, 1, 4, 1, 3, 4, 4, 4, 4, 3, 4, 3, 3, 3, 1, 1, 1, 4, 4, 2, 2, 3, 3, 4, 2, 3, 3, 3, 5, 3, 7, 6, 5, 6, 5, 5, 5, 6, 5, 6, 3, 4, 4, 2, 2, 2, 2, 5, 6, 10, 14, 3, 13, 4, 5, 7, 8, 3, 5, 5, 5, 2, 2, 2, 4, 8, 6, 5, 5, 6, 6, 8, 8, 6, 8, 6, 6, 8, 5, 7, 7, 4, 8, 6, 7, 7, 3, 5, 8, 8, 7, 7, 3, 6, 7, 9, 2, 6, 8, 3, 5, 6, 4, 7, 8, 4, 6, 6, 2, 3, \ No newline at end of file
+4, 4, 5, 4, 4, 4, 5, 6, 8, 8, 4, 7, 7, 3, 5, 2, 2, 2, 2, 2, 2, 6, 6, 6, 7, 1, 2, 3, 10, 2, 2, 2, 2, 2, 2, 6, 10, 4, 3, 1, 2, 6, 5, 1, 4, 1, 3, 4, 4, 4, 4, 3, 4, 3, 3, 3, 1, 1, 1, 4, 4, 2, 2, 3, 3, 4, 2, 3, 3, 3, 5, 3, 7, 6, 5, 6, 5, 5, 5, 6, 5, 6, 3, 4, 4, 2, 2, 2, 2, 5, 6, 10, 14, 3, 13, 4, 5, 7, 8, 3, 5, 5, 5, 2, 2, 2, 4, 8, 6, 5, 5, 6, 6, 8, 8, 6, 8, 6, 6, 8, 5, 7, 7, 4, 8, 6, 7, 7, 3, 5, 8, 8, 7, 7, 3, 6, 7, 9, 2, 6, 8, 3, 5, 6, 4, 7, 8, 4, 6, 6, 6, 2, 3, \ No newline at end of file
diff --git a/libs/litehtml/src/gumbo/include/gumbo/tag_strings.h b/libs/litehtml/src/gumbo/include/gumbo/tag_strings.h
index 03d793c05d..188bcda00b 100644
--- a/libs/litehtml/src/gumbo/include/gumbo/tag_strings.h
+++ b/libs/litehtml/src/gumbo/include/gumbo/tag_strings.h
@@ -151,5 +151,6 @@
"nobr",
"spacer",
"dialog",
+"search",
"tt",
"rtc",
diff --git a/libs/litehtml/src/gumbo/parser.c b/libs/litehtml/src/gumbo/parser.c
index 968fcc0f41..0ab3f92084 100644
--- a/libs/litehtml/src/gumbo/parser.c
+++ b/libs/litehtml/src/gumbo/parser.c
@@ -291,17 +291,16 @@ typedef struct _NamespacedAttributeReplacement {
static const NamespacedAttributeReplacement kForeignAttributeReplacements[] = {
{"xlink:actuate", "actuate", GUMBO_ATTR_NAMESPACE_XLINK},
- {"xlink:actuate", "actuate", GUMBO_ATTR_NAMESPACE_XLINK},
- {"xlink:href", "href", GUMBO_ATTR_NAMESPACE_XLINK},
- {"xlink:role", "role", GUMBO_ATTR_NAMESPACE_XLINK},
- {"xlink:show", "show", GUMBO_ATTR_NAMESPACE_XLINK},
- {"xlink:title", "title", GUMBO_ATTR_NAMESPACE_XLINK},
- {"xlink:type", "type", GUMBO_ATTR_NAMESPACE_XLINK},
- {"xml:base", "base", GUMBO_ATTR_NAMESPACE_XML},
- {"xml:lang", "lang", GUMBO_ATTR_NAMESPACE_XML},
- {"xml:space", "space", GUMBO_ATTR_NAMESPACE_XML},
- {"xmlns", "xmlns", GUMBO_ATTR_NAMESPACE_XMLNS},
- {"xmlns:xlink", "xlink", GUMBO_ATTR_NAMESPACE_XMLNS},
+ {"xlink:arcrole", "arcrole", GUMBO_ATTR_NAMESPACE_XLINK},
+ {"xlink:href", "href", GUMBO_ATTR_NAMESPACE_XLINK},
+ {"xlink:role", "role", GUMBO_ATTR_NAMESPACE_XLINK},
+ {"xlink:show", "show", GUMBO_ATTR_NAMESPACE_XLINK},
+ {"xlink:title", "title", GUMBO_ATTR_NAMESPACE_XLINK},
+ {"xlink:type", "type", GUMBO_ATTR_NAMESPACE_XLINK},
+ {"xml:lang", "lang", GUMBO_ATTR_NAMESPACE_XML},
+ {"xml:space", "space", GUMBO_ATTR_NAMESPACE_XML},
+ {"xmlns", "xmlns", GUMBO_ATTR_NAMESPACE_XMLNS},
+ {"xmlns:xlink", "xlink", GUMBO_ATTR_NAMESPACE_XMLNS},
};
// The "scope marker" for the list of active formatting elements. We use a
@@ -1564,12 +1563,12 @@ static bool is_special_node(const GumboNode* node) {
(gumbo_tagset){TAG(ADDRESS), TAG(APPLET), TAG(AREA), TAG(ARTICLE),
TAG(ASIDE), TAG(BASE), TAG(BASEFONT), TAG(BGSOUND), TAG(BLOCKQUOTE),
TAG(BODY), TAG(BR), TAG(BUTTON), TAG(CAPTION), TAG(CENTER), TAG(COL),
- TAG(COLGROUP), TAG(MENUITEM), TAG(DD), TAG(DETAILS), TAG(DIR),
+ TAG(COLGROUP), TAG(DD), TAG(DETAILS), TAG(DIR),
TAG(DIV), TAG(DL), TAG(DT), TAG(EMBED), TAG(FIELDSET),
TAG(FIGCAPTION), TAG(FIGURE), TAG(FOOTER), TAG(FORM), TAG(FRAME),
TAG(FRAMESET), TAG(H1), TAG(H2), TAG(H3), TAG(H4), TAG(H5), TAG(H6),
TAG(HEAD), TAG(HEADER), TAG(HGROUP), TAG(HR), TAG(HTML), TAG(IFRAME),
- TAG(IMG), TAG(INPUT), TAG(ISINDEX), TAG(LI), TAG(LINK), TAG(LISTING),
+ TAG(IMG), TAG(INPUT), TAG(LI), TAG(LINK), TAG(LISTING),
TAG(MARQUEE), TAG(MENU), TAG(META), TAG(NAV), TAG(NOEMBED),
TAG(NOFRAMES), TAG(NOSCRIPT), TAG(OBJECT), TAG(OL), TAG(P),
TAG(PARAM), TAG(PLAINTEXT), TAG(PRE), TAG(SCRIPT), TAG(SECTION),
@@ -2179,7 +2178,7 @@ static bool handle_in_head(GumboParser* parser, GumboToken* token) {
return handle_in_body(parser, token);
} else if (tag_in(token, kStartTag,
(gumbo_tagset){TAG(BASE), TAG(BASEFONT), TAG(BGSOUND),
- TAG(MENUITEM), TAG(LINK)})) {
+ TAG(LINK)})) {
insert_element_from_token(parser, token);
pop_current_node(parser);
acknowledge_self_closing_tag(parser);
@@ -2419,7 +2418,7 @@ static bool handle_in_body(GumboParser* parser, GumboToken* token) {
return false;
} else if (tag_in(token, kStartTag,
(gumbo_tagset){TAG(BASE), TAG(BASEFONT), TAG(BGSOUND),
- TAG(MENUITEM), TAG(LINK), TAG(META), TAG(NOFRAMES),
+ TAG(LINK), TAG(META), TAG(NOFRAMES),
TAG(SCRIPT), TAG(STYLE), TAG(TEMPLATE), TAG(TITLE)}) ||
tag_is(token, kEndTag, GUMBO_TAG_TEMPLATE)) {
return handle_in_head(parser, token);
@@ -2514,13 +2513,13 @@ static bool handle_in_body(GumboParser* parser, GumboToken* token) {
record_end_of_element(state->_current_token, &body->v.element);
}
return success;
- } else if (tag_in(token, kStartTag,
- (gumbo_tagset){TAG(ADDRESS), TAG(ARTICLE), TAG(ASIDE),
- TAG(BLOCKQUOTE), TAG(CENTER), TAG(DETAILS), TAG(DIALOG),
- TAG(DIR), TAG(DIV), TAG(DL), TAG(FIELDSET), TAG(FIGCAPTION),
- TAG(FIGURE), TAG(FOOTER), TAG(HEADER), TAG(HGROUP),
- TAG(MENU), TAG(MAIN), TAG(NAV), TAG(OL), TAG(P),
- TAG(SECTION), TAG(SUMMARY), TAG(UL)})) {
+ } else if (tag_in(token, kStartTag, (gumbo_tagset){
+ TAG(ADDRESS), TAG(ARTICLE), TAG(ASIDE), TAG(BLOCKQUOTE), TAG(CENTER),
+ TAG(DETAILS), TAG(DIALOG), TAG(DIR), TAG(DIV), TAG(DL), TAG(FIELDSET),
+ TAG(FIGCAPTION), TAG(FIGURE), TAG(FOOTER), TAG(HEADER), TAG(HGROUP),
+ TAG(MENU), TAG(MAIN), TAG(NAV), TAG(OL), TAG(P), TAG(SECTION),
+ TAG(SUMMARY), TAG(UL), TAG(SEARCH)}))
+ {
bool result = maybe_implicitly_close_p_tag(parser, token);
insert_element_from_token(parser, token);
return result;
@@ -2583,13 +2582,13 @@ static bool handle_in_body(GumboParser* parser, GumboToken* token) {
insert_element_from_token(parser, token);
state->_frameset_ok = false;
return true;
- } else if (tag_in(token, kEndTag,
- (gumbo_tagset){TAG(ADDRESS), TAG(ARTICLE), TAG(ASIDE),
- TAG(BLOCKQUOTE), TAG(BUTTON), TAG(CENTER), TAG(DETAILS),
- TAG(DIALOG), TAG(DIR), TAG(DIV), TAG(DL), TAG(FIELDSET),
- TAG(FIGCAPTION), TAG(FIGURE), TAG(FOOTER), TAG(HEADER),
- TAG(HGROUP), TAG(LISTING), TAG(MAIN), TAG(MENU), TAG(NAV),
- TAG(OL), TAG(PRE), TAG(SECTION), TAG(SUMMARY), TAG(UL)})) {
+ } else if (tag_in(token, kEndTag, (gumbo_tagset){
+ TAG(ADDRESS), TAG(ARTICLE), TAG(ASIDE), TAG(BLOCKQUOTE), TAG(BUTTON),
+ TAG(CENTER), TAG(DETAILS), TAG(DIALOG), TAG(DIR), TAG(DIV), TAG(DL),
+ TAG(FIELDSET), TAG(FIGCAPTION), TAG(FIGURE), TAG(FOOTER), TAG(HEADER),
+ TAG(HGROUP), TAG(LISTING), TAG(MAIN), TAG(MENU), TAG(NAV), TAG(OL),
+ TAG(PRE), TAG(SECTION), TAG(SUMMARY), TAG(UL), TAG(SEARCH)}))
+ {
GumboTag tag = token->v.end_tag;
if (!has_an_element_in_scope(parser, tag)) {
parser_add_parse_error(parser, token);
@@ -2820,100 +2819,13 @@ static bool handle_in_body(GumboParser* parser, GumboToken* token) {
set_frameset_not_ok(parser);
return result;
} else if (tag_is(token, kStartTag, GUMBO_TAG_ISINDEX)) {
- parser_add_parse_error(parser, token);
- if (parser->_parser_state->_form_element != NULL &&
- !has_open_element(parser, GUMBO_TAG_TEMPLATE)) {
- ignore_token(parser);
- return false;
- }
- acknowledge_self_closing_tag(parser);
- maybe_implicitly_close_p_tag(parser, token);
- set_frameset_not_ok(parser);
-
- GumboVector* token_attrs = &token->v.start_tag.attributes;
- GumboAttribute* prompt_attr = gumbo_get_attribute(token_attrs, "prompt");
- GumboAttribute* action_attr = gumbo_get_attribute(token_attrs, "action");
- GumboAttribute* name_attr = gumbo_get_attribute(token_attrs, "name");
-
- GumboNode* form = insert_element_of_tag_type(
- parser, GUMBO_TAG_FORM, GUMBO_INSERTION_FROM_ISINDEX);
- if (!has_open_element(parser, GUMBO_TAG_TEMPLATE)) {
- parser->_parser_state->_form_element = form;
- }
- if (action_attr) {
- gumbo_vector_add(parser, action_attr, &form->v.element.attributes);
- }
- insert_element_of_tag_type(
- parser, GUMBO_TAG_HR, GUMBO_INSERTION_FROM_ISINDEX);
- pop_current_node(parser); // <hr>
-
- insert_element_of_tag_type(
- parser, GUMBO_TAG_LABEL, GUMBO_INSERTION_FROM_ISINDEX);
- TextNodeBufferState* text_state = &parser->_parser_state->_text_node;
- text_state->_start_original_text = token->original_text.data;
- text_state->_start_position = token->position;
- text_state->_type = GUMBO_NODE_TEXT;
- if (prompt_attr) {
- int prompt_attr_length = strlen(prompt_attr->value);
- gumbo_string_buffer_destroy(parser, &text_state->_buffer);
- text_state->_buffer.data = gumbo_copy_stringz(parser, prompt_attr->value);
- text_state->_buffer.length = prompt_attr_length;
- text_state->_buffer.capacity = prompt_attr_length + 1;
- gumbo_destroy_attribute(parser, prompt_attr);
- } else {
- GumboStringPiece prompt_text =
- GUMBO_STRING("This is a searchable index. Enter search keywords: ");
- gumbo_string_buffer_append_string(
- parser, &prompt_text, &text_state->_buffer);
- }
-
- GumboNode* input = insert_element_of_tag_type(
- parser, GUMBO_TAG_INPUT, GUMBO_INSERTION_FROM_ISINDEX);
- for (unsigned int i = 0; i < token_attrs->length; ++i) {
- GumboAttribute* attr = token_attrs->data[i];
- if (attr != prompt_attr && attr != action_attr && attr != name_attr) {
- gumbo_vector_add(parser, attr, &input->v.element.attributes);
- }
- token_attrs->data[i] = NULL;
- }
-
- // All attributes have been successfully transferred and nulled out at this
- // point, so the call to ignore_token will free the memory for it without
- // touching the attributes.
- ignore_token(parser);
-
- // The name attribute, if present, should be destroyed since it's ignored
- // when copying over. The action attribute should be kept since it's moved
- // to the form.
- if (name_attr) {
- gumbo_destroy_attribute(parser, name_attr);
- }
-
- GumboAttribute* name =
- gumbo_parser_allocate(parser, sizeof(GumboAttribute));
- GumboStringPiece name_str = GUMBO_STRING("name");
- GumboStringPiece isindex_str = GUMBO_STRING("isindex");
- name->attr_namespace = GUMBO_ATTR_NAMESPACE_NONE;
- name->name = gumbo_copy_stringz(parser, "name");
- name->value = gumbo_copy_stringz(parser, "isindex");
- name->original_name = name_str;
- name->original_value = isindex_str;
- name->name_start = kGumboEmptySourcePosition;
- name->name_end = kGumboEmptySourcePosition;
- name->value_start = kGumboEmptySourcePosition;
- name->value_end = kGumboEmptySourcePosition;
- gumbo_vector_add(parser, name, &input->v.element.attributes);
-
- pop_current_node(parser); // <input>
- pop_current_node(parser); // <label>
- insert_element_of_tag_type(
- parser, GUMBO_TAG_HR, GUMBO_INSERTION_FROM_ISINDEX);
- pop_current_node(parser); // <hr>
- pop_current_node(parser); // <form>
- if (!has_open_element(parser, GUMBO_TAG_TEMPLATE)) {
- parser->_parser_state->_form_element = NULL;
+ reconstruct_active_formatting_elements(parser);
+ insert_element_from_token(parser, token);
+ if (token->v.start_tag.is_self_closing) {
+ pop_current_node(parser);
+ acknowledge_self_closing_tag(parser);
}
- return false;
+ return true;
} else if (tag_is(token, kStartTag, GUMBO_TAG_TEXTAREA)) {
run_generic_parsing_algorithm(parser, token, GUMBO_LEX_RCDATA);
parser->_parser_state->_ignore_next_linefeed = true;
@@ -3491,6 +3403,17 @@ static bool handle_in_select(GumboParser* parser, GumboToken* token) {
}
insert_element_from_token(parser, token);
return true;
+ } else if (tag_is(token, kStartTag, GUMBO_TAG_HR)) {
+ if (node_html_tag_is(get_current_node(parser), GUMBO_TAG_OPTION)) {
+ pop_current_node(parser);
+ }
+ if (node_html_tag_is(get_current_node(parser), GUMBO_TAG_OPTGROUP)) {
+ pop_current_node(parser);
+ }
+ insert_element_from_token(parser, token);
+ pop_current_node(parser);
+ acknowledge_self_closing_tag(parser);
+ return true;
} else if (tag_is(token, kEndTag, GUMBO_TAG_OPTGROUP)) {
GumboVector* open_elements = &parser->_parser_state->_open_elements;
if (node_html_tag_is(get_current_node(parser), GUMBO_TAG_OPTION) &&
@@ -3854,40 +3777,33 @@ static bool handle_in_foreign_content(GumboParser* parser, GumboToken* token) {
// Fall through to the if-statements below.
break;
}
- // Order matters for these clauses.
- if (tag_in(token, kStartTag,
- (gumbo_tagset){TAG(B), TAG(BIG), TAG(BLOCKQUOTE), TAG(BODY), TAG(BR),
- TAG(CENTER), TAG(CODE), TAG(DD), TAG(DIV), TAG(DL), TAG(DT),
- TAG(EM), TAG(EMBED), TAG(H1), TAG(H2), TAG(H3), TAG(H4), TAG(H5),
- TAG(H6), TAG(HEAD), TAG(HR), TAG(I), TAG(IMG), TAG(LI),
- TAG(LISTING), TAG(MENU), TAG(META), TAG(NOBR), TAG(OL), TAG(P),
- TAG(PRE), TAG(RUBY), TAG(S), TAG(SMALL), TAG(SPAN), TAG(STRONG),
- TAG(STRIKE), TAG(SUB), TAG(SUP), TAG(TABLE), TAG(TT), TAG(U),
- TAG(UL), TAG(VAR)}) ||
- (tag_is(token, kStartTag, GUMBO_TAG_FONT) &&
- (token_has_attribute(token, "color") ||
- token_has_attribute(token, "face") ||
- token_has_attribute(token, "size")))) {
+
+ if (tag_in(token, kStartTag, (gumbo_tagset){
+ TAG(B), TAG(BIG), TAG(BLOCKQUOTE), TAG(BODY), TAG(BR), TAG(CENTER),
+ TAG(CODE), TAG(DD), TAG(DIV), TAG(DL), TAG(DT), TAG(EM), TAG(EMBED),
+ TAG(H1), TAG(H2), TAG(H3), TAG(H4), TAG(H5), TAG(H6), TAG(HEAD),
+ TAG(HR), TAG(I), TAG(IMG), TAG(LI), TAG(LISTING), TAG(MENU), TAG(META),
+ TAG(NOBR), TAG(OL), TAG(P), TAG(PRE), TAG(RUBY), TAG(S), TAG(SMALL),
+ TAG(SPAN), TAG(STRONG), TAG(STRIKE), TAG(SUB), TAG(SUP), TAG(TABLE),
+ TAG(TT), TAG(U), TAG(UL), TAG(VAR)})
+ || tag_in(token, kEndTag, (gumbo_tagset){TAG(BR), TAG(P)})
+ || (tag_is(token, kStartTag, GUMBO_TAG_FONT)
+ && (token_has_attribute(token, "color")
+ || token_has_attribute(token, "face")
+ || token_has_attribute(token, "size"))))
+ {
/* Parse error */
parser_add_parse_error(parser, token);
- /*
- * Fragment case: If the parser was originally created for the HTML
- * fragment parsing algorithm, then act as described in the "any other
- * start tag" entry below.
- */
- if (!is_fragment_parser(parser)) {
- do {
- pop_current_node(parser);
- } while (!(is_mathml_integration_point(get_current_node(parser)) ||
- is_html_integration_point(get_current_node(parser)) ||
- get_current_node(parser)->v.element.tag_namespace ==
- GUMBO_NAMESPACE_HTML));
- parser->_parser_state->_reprocess_current_token = true;
- return false;
+ while (!is_mathml_integration_point(get_current_node(parser))
+ && !is_html_integration_point(get_current_node(parser))
+ && get_current_node(parser)->v.element.tag_namespace != GUMBO_NAMESPACE_HTML)
+ {
+ pop_current_node(parser);
}
- assert(token->type == GUMBO_TOKEN_START_TAG);
+ handle_html_content(parser, token);
+ return false;
}
if (token->type == GUMBO_TOKEN_START_TAG) {
diff --git a/libs/litehtml/src/html_microsyntaxes.cpp b/libs/litehtml/src/html_microsyntaxes.cpp
index f16bd622e0..d8ce01471f 100644
--- a/libs/litehtml/src/html_microsyntaxes.cpp
+++ b/libs/litehtml/src/html_microsyntaxes.cpp
@@ -1,3 +1,4 @@
+#include "html_microsyntaxes.h"
#include "html.h"
namespace litehtml
diff --git a/libs/litehtml/src/html_tag.cpp b/libs/litehtml/src/html_tag.cpp
index 54a8dd404a..08f289df9d 100644
--- a/libs/litehtml/src/html_tag.cpp
+++ b/libs/litehtml/src/html_tag.cpp
@@ -3,6 +3,7 @@
#include "html.h"
#include "html_tag.h"
#include "document.h"
+#include "html_microsyntaxes.h"
#include "iterators.h"
#include "stylesheet.h"
#include "table.h"
@@ -10,6 +11,7 @@
#include "line_box.h"
#include "render_item.h"
#include "internal.h"
+#include "document_container.h"
namespace litehtml
{
@@ -126,7 +128,7 @@ litehtml::elements_list litehtml::html_tag::select_all(const string& selector )
{
css_selector sel;
sel.parse(selector, get_document()->mode());
-
+
return select_all(sel);
}
@@ -143,7 +145,7 @@ void litehtml::html_tag::select_all(const css_selector& selector, elements_list&
{
res.push_back(shared_from_this());
}
-
+
for(auto& el : m_children)
{
el->select_all(selector, res);
@@ -295,7 +297,7 @@ void litehtml::html_tag::draw(uint_ptr hdc, int x, int y, const position *clip,
draw_background(hdc, x, y, clip, ri);
- if(m_css.get_display() == display_list_item &&
+ if(m_css.get_display() == display_list_item &&
(m_css.get_list_style_type() != list_style_type_none || m_css.get_list_style_image() != ""))
{
if(m_css.get_overflow() > overflow_visible)
@@ -816,7 +818,7 @@ bool litehtml::html_tag::on_lbutton_down()
return ret;
}
-bool litehtml::html_tag::on_lbutton_up()
+bool litehtml::html_tag::on_lbutton_up(bool is_click)
{
bool ret = false;
@@ -830,7 +832,7 @@ bool litehtml::html_tag::on_lbutton_up()
el = el->parent();
}
- on_click();
+ if (is_click) on_click();
return ret;
}
@@ -839,10 +841,13 @@ void litehtml::html_tag::on_click()
{
if (!is_root())
{
- element::ptr el_parent = parent();
- if (el_parent)
+ if(!get_document()->container()->on_element_click(shared_from_this()))
{
- el_parent->on_click();
+ element::ptr el_parent = parent();
+ if (el_parent)
+ {
+ el_parent->on_click();
+ }
}
}
}
@@ -935,7 +940,7 @@ void litehtml::html_tag::draw_background(uint_ptr hdc, int x, int y, const posit
bdr.radius.top_right_y = m_css.get_borders().radius.top_right_y;
}
-
+
bdr.top = m_css.get_borders().top;
bdr.bottom = m_css.get_borders().bottom;
if(box == boxes.begin())
@@ -954,7 +959,7 @@ void litehtml::html_tag::draw_background(uint_ptr hdc, int x, int y, const posit
{
background_layer layer;
if(!bg->get_layer(i, content_box, this, ri, layer)) continue;
- layer.border_radius = bdr.radius.calc_percents(layer.border_box.width, layer.border_box.width);
+ layer.border_radius = bdr.radius.calc_percents(box->width, box->height);
bg->draw_layer(hdc, i, layer, get_document()->container());
}
}
@@ -1057,7 +1062,7 @@ void litehtml::html_tag::draw_list_marker( uint_ptr hdc, const position& pos )
lm.baseurl = nullptr;
}
- int ln_height = css().get_line_height();
+ int ln_height = css().line_height().computed_value;
int sz_font = css().get_font_size();
lm.pos.x = pos.x;
lm.pos.width = sz_font - sz_font * 2 / 3;
@@ -1192,7 +1197,7 @@ bool html_tag::is_nth_child(const element::ptr& el, int num, int off, bool of_ty
{
if(child->css().get_display() != display_inline_text)
{
- if( (!of_type && selector_list.empty()) ||
+ if( (!of_type && selector_list.empty()) ||
(of_type && child->tag() == el->tag()) || child->select(selector_list) )
{
if(el == child)
@@ -1502,7 +1507,7 @@ const litehtml::background* litehtml::html_tag::get_background(bool own_only)
}
return nullptr;
}
-
+
if(is_body())
{
element::ptr el_parent = parent();
@@ -1578,7 +1583,7 @@ void html_tag::map_to_dimension_property_ignoring_zero(string_id prop_name, stri
tok = {DIMENSION, x, css_number_number, "px"};
else
tok = {PERCENTAGE, x, css_number_number};
-
+
m_style.add_property(prop_name, {tok});
}
diff --git a/libs/litehtml/src/iterators.cpp b/libs/litehtml/src/iterators.cpp
index f0a87555c2..3d48e463dd 100644
--- a/libs/litehtml/src/iterators.cpp
+++ b/libs/litehtml/src/iterators.cpp
@@ -1,8 +1,5 @@
-#include "html.h"
#include "iterators.h"
-#include "html_tag.h"
#include "render_item.h"
-#include <iterator>
litehtml::elements_iterator::elements_iterator(bool return_parents, iterator_selector* go_inside, iterator_selector* select) :
m_go_inside(go_inside),
diff --git a/libs/litehtml/src/line_box.cpp b/libs/litehtml/src/line_box.cpp
index fed0aa404d..20aed39fb3 100644
--- a/libs/litehtml/src/line_box.cpp
+++ b/libs/litehtml/src/line_box.cpp
@@ -45,6 +45,11 @@ int litehtml::line_box_item::left() const
return m_element->left();
}
+int litehtml::line_box_item::height() const
+{
+ return m_element->height();
+}
+
//////////////////////////////////////////////////////////////////////////////////////////
litehtml::lbi_start::lbi_start(const std::shared_ptr<render_item>& element) : line_box_item(element)
@@ -86,6 +91,11 @@ int litehtml::lbi_start::left() const
return m_pos.x - m_element->content_offset_left();
}
+int litehtml::lbi_start::height() const
+{
+ return m_pos.height;
+}
+
//////////////////////////////////////////////////////////////////////////////////////////
litehtml::lbi_end::lbi_end(const std::shared_ptr<render_item>& element) : lbi_start(element)
@@ -180,9 +190,9 @@ int litehtml::line_box::calc_va_baseline(const va_context& current, vertical_ali
switch(va)
{
case va_super:
- return current.baseline - current.fm.height / 3;
+ return current.baseline - current.fm.super_shift;
case va_sub:
- return current.baseline + current.fm.height / 3;
+ return current.baseline + current.fm.sub_shift;
case va_middle:
return current.baseline - current.fm.x_height / 2;
case va_text_top:
@@ -190,10 +200,10 @@ int litehtml::line_box::calc_va_baseline(const va_context& current, vertical_ali
new_font.height - new_font.base_line();
case va_text_bottom:
return current.baseline + current.fm.base_line() - new_font.base_line();
+ case va_bottom:
+ return bottom - new_font.base_line();
case va_top:
return top + new_font.height - new_font.base_line();
- case va_bottom:
- return bottom - new_font.height + new_font.base_line();
default:
return current.baseline;
}
@@ -275,130 +285,236 @@ std::list< std::unique_ptr<litehtml::line_box_item> > litehtml::line_box::finish
if( is_empty() || (!is_empty() && last_box && is_break_only()) )
{
- m_height = m_default_line_height;
+ m_height = m_default_line_height.computed_value;
m_baseline = m_font_metrics.base_line();
return ret_items;
}
- int spc_x = 0;
+ int spacing_x = 0; // Number of pixels to distribute between elements
+ int shift_x = 0; // Shift elements by X to apply the text-align
- int add_x = 0;
switch(m_text_align)
{
case text_align_right:
if(m_width < (m_right - m_left))
{
- add_x = (m_right - m_left) - m_width;
+ shift_x = (m_right - m_left) - m_width;
}
break;
case text_align_center:
if(m_width < (m_right - m_left))
{
- add_x = ((m_right - m_left) - m_width) / 2;
+ shift_x = ((m_right - m_left) - m_width) / 2;
}
break;
case text_align_justify:
if (m_width < (m_right - m_left))
{
- add_x = 0;
- spc_x = (m_right - m_left) - m_width;
- if (spc_x > m_width/4)
- spc_x = 0;
+ shift_x = 0;
+ spacing_x = (m_right - m_left) - m_width;
+ // don't justify for small lines
+ if (spacing_x > m_width / 4)
+ spacing_x = 0;
}
break;
default:
- add_x = 0;
+ shift_x = 0;
}
int counter = 0;
- float offj = float(spc_x) / std::max(1.f, float(m_items.size())-1.f);
+ float offj = float(spacing_x) / std::max(1.f, float(m_items.size()) - 1.f);
float cixx = 0.0f;
- int line_top = 0;
- int line_bottom = 0;
+ std::optional<int> line_height;
+
+ if(!m_default_line_height.css_value.is_predefined())
+ {
+ line_height = m_default_line_height.computed_value;
+ }
va_context current_context;
std::list<va_context> contexts;
current_context.baseline = 0;
current_context.fm = m_font_metrics;
+ current_context.start_lbi = nullptr;
+ current_context.line_height = m_default_line_height.computed_value;
m_min_width = 0;
+ struct items_dimensions
+ {
+ int top = 0;
+ int bottom = 0;
+ int count = 0;
+ int max_height = 0;
+
+ void add_item(const line_box_item* item)
+ {
+ top = std::min(top, item->top());
+ bottom = std::max(bottom, item->bottom());
+ max_height = std::max(max_height, item->height());
+ count++;
+ }
+ int height() const { return bottom - top; }
+ };
+
+ items_dimensions line_max_height;
+ items_dimensions top_aligned_max_height;
+ items_dimensions bottom_aligned_max_height;
+ items_dimensions inline_boxes_dims;
+
+ // First pass
+ // 1. Apply text-align-justify
+ // 1. Align all items by baseline
+ // 2. top/button aligned items are aligned by baseline
+ // 3. Calculate top and button of the linebox separately for items in baseline
+ // and for top and bottom aligned items
for (const auto& lbi : m_items)
- {
+ {
+ // Apply text-align-justify
m_min_width += lbi->get_rendered_min_width();
- { // start text_align_justify
- if (spc_x && counter)
+ if (spacing_x && counter)
+ {
+ cixx += offj;
+ if ((counter + 1) == int(m_items.size()))
+ cixx += 0.99f;
+ lbi->pos().x += int(cixx);
+ }
+ counter++;
+ if ((m_text_align == text_align_right || spacing_x) && counter == int(m_items.size()))
+ {
+ // Forcible justify the last element to the right side for text align right and justify;
+ lbi->pos().x = m_right - lbi->pos().width;
+ } else if (shift_x)
+ {
+ lbi->pos().x += shift_x;
+ }
+
+ // Calculate new baseline for inline start/continue
+ // Inline start/continue elements are inline containers like <span>
+ if (lbi->get_type() == line_box_item::type_inline_start || lbi->get_type() == line_box_item::type_inline_continue)
+ {
+ contexts.push_back(current_context);
+ if(is_one_of(lbi->get_el()->css().get_vertical_align(), va_top, va_bottom))
{
- cixx += offj;
- if ((counter + 1) == int(m_items.size()))
- cixx += 0.99f;
- lbi->pos().x += int(cixx);
- }
- counter++;
- if ((m_text_align == text_align_right || spc_x) && counter == int(m_items.size()))
+ // top/bottom aligned inline boxes are aligned by baseline == 0
+ current_context.baseline = 0;
+ current_context.start_lbi = lbi.get();
+ current_context.start_lbi->reset_items_height();
+ } else if(current_context.start_lbi)
{
- // Forcible justify the last element to the right side for text align right and justify;
- lbi->pos().x = m_right - lbi->pos().width;
- } else if (add_x)
+ current_context.baseline = calc_va_baseline(current_context,
+ lbi->get_el()->css().get_vertical_align(),
+ lbi->get_el()->css().get_font_metrics(),
+ current_context.start_lbi->top(), current_context.start_lbi->bottom());
+ } else
{
- lbi->pos().x += add_x;
+ current_context.start_lbi = nullptr;
+ current_context.baseline = calc_va_baseline(current_context,
+ lbi->get_el()->css().get_vertical_align(),
+ lbi->get_el()->css().get_font_metrics(),
+ line_max_height.top, line_max_height.bottom);
}
- } // end text_align_justify
+ current_context.fm = lbi->get_el()->css().get_font_metrics();
+ current_context.line_height = lbi->get_el()->css().line_height().computed_value;
+ }
- if (lbi->get_type() == line_box_item::type_inline_start || lbi->get_type() == line_box_item::type_inline_continue)
+ int bl = current_context.baseline;
+ int content_offset = 0;
+ bool is_top_bottom_box = false;
+ bool ignore = false;
+
+ // Align element by baseline
+ if(!is_one_of(lbi->get_el()->src_el()->css().get_display(), display_inline_text, display_inline))
{
- contexts.push_back(current_context);
- current_context.baseline = calc_va_baseline(current_context,
- lbi->get_el()->css().get_vertical_align(),
- lbi->get_el()->css().get_font_metrics(),
- line_top, line_bottom);
- current_context.fm = lbi->get_el()->css().get_font_metrics();
+ // Apply margins, paddings and border for inline boxes
+ content_offset = lbi->get_el()->content_offset_top();
+ switch (lbi->get_el()->css().get_vertical_align())
+ {
+ case va_bottom:
+ case va_top:
+ // Align by base line 0 all inline boxes with top and bottom vertical aling
+ bl = 0;
+ is_top_bottom_box = true;
+ break;
+
+ case va_text_bottom:
+ lbi->pos().y = bl + current_context.fm.base_line() - lbi->get_el()->height() + content_offset;
+ ignore = true;
+ break;
+
+ case va_text_top:
+ lbi->pos().y = bl - current_context.fm.ascent + content_offset;
+ ignore = true;
+ break;
+
+ case va_middle:
+ lbi->pos().y = bl - current_context.fm.x_height / 2 - lbi->get_el()->height() / 2 + content_offset;
+ ignore = true;
+ break;
+
+ default:
+ bl = calc_va_baseline(current_context,
+ lbi->get_el()->css().get_vertical_align(),
+ lbi->get_el()->css().get_font_metrics(),
+ line_max_height.top, line_max_height.bottom);
+ break;
+ }
+ }
+ if(!ignore)
+ {
+ lbi->pos().y = bl - lbi->get_el()->get_last_baseline() + content_offset;
}
- // Align elements vertically by baseline.
- if(lbi->get_el()->src_el()->css().get_display() == display_inline_text || lbi->get_el()->src_el()->css().get_display() == display_inline)
- {
- // inline elements and text are aligned by baseline only
- // at this point the baseline for text is properly aligned already
- lbi->pos().y = current_context.baseline - lbi->get_el()->css().get_font_metrics().height + lbi->get_el()->css().get_font_metrics().base_line();
- } else
- {
- switch(lbi->get_el()->css().get_vertical_align())
- {
- case va_sub:
- case va_super:
- {
- int bl = calc_va_baseline(current_context, lbi->get_el()->css().get_vertical_align(), current_context.fm, line_top, line_bottom);
- lbi->pos().y = bl - lbi->get_el()->get_last_baseline() +
- lbi->get_el()->content_offset_top();
- }
+ if(is_top_bottom_box)
+ {
+ switch (lbi->get_el()->css().get_vertical_align())
+ {
+ case va_top:
+ top_aligned_max_height.add_item(lbi.get());
break;
case va_bottom:
- lbi->pos().y = line_bottom - lbi->get_el()->height() + lbi->get_el()->content_offset_top();
+ bottom_aligned_max_height.add_item(lbi.get());
break;
+ default:
+ break;
+ }
+ } else if(current_context.start_lbi)
+ {
+ current_context.start_lbi->add_item_height(lbi->top(), lbi->bottom());
+ switch (current_context.start_lbi->get_el()->css().get_vertical_align())
+ {
case va_top:
- lbi->pos().y = line_top + lbi->get_el()->content_offset_top();
+ top_aligned_max_height.add_item(lbi.get());
break;
- case va_baseline:
- lbi->pos().y = current_context.baseline - lbi->get_el()->get_last_baseline() +
- lbi->get_el()->content_offset_top();
- break;
- case va_text_top:
- lbi->pos().y = current_context.baseline - current_context.fm.height + current_context.fm.base_line() +
- lbi->get_el()->content_offset_top();
- break;
- case va_text_bottom:
- lbi->pos().y = current_context.baseline + current_context.fm.base_line() - lbi->get_el()->height() +
- lbi->get_el()->content_offset_top();
+ case va_bottom:
+ bottom_aligned_max_height.add_item(lbi.get());
break;
- case va_middle:
- lbi->pos().y = current_context.baseline - current_context.fm.x_height / 2 - lbi->get_el()->height() / 2 +
- lbi->get_el()->content_offset_top();
- break;
- }
- }
+ default:
+ break;
+ }
+ } else
+ {
+ if(!lbi->get_el()->src_el()->is_inline_box())
+ {
+ line_max_height.add_item(lbi.get());
+ } else
+ {
+ inline_boxes_dims.add_item(lbi.get());
+ }
+ }
+
+ if(!lbi->get_el()->src_el()->is_inline_box() && !lbi->get_el()->css().line_height().css_value.is_predefined())
+ {
+ if(line_height.has_value())
+ {
+ line_height = std::max(line_height.value(), lbi->get_el()->css().line_height().computed_value);
+ } else
+ {
+ line_height = lbi->get_el()->css().line_height().computed_value;
+ }
+ }
if (lbi->get_type() == line_box_item::type_inline_end)
{
@@ -408,25 +524,68 @@ std::list< std::unique_ptr<litehtml::line_box_item> > litehtml::line_box::finish
contexts.pop_back();
}
}
+ }
- // calculate line height
- line_top = std::min(line_top, lbi->top());
- line_bottom = std::max(line_bottom, lbi->bottom());
-
- if(lbi->get_el()->src_el()->css().get_display() == display_inline_text)
+ int top_shift = 0;
+ if(line_height.has_value())
+ {
+ m_height = line_height.value();
+ if(line_max_height.count != 0)
+ {
+ // We have inline items
+ top_shift = std::abs(line_max_height.top);
+ const int top_shift_correction = (line_height.value() - line_max_height.height()) / 2;
+ m_baseline = line_max_height.bottom + top_shift_correction;
+ top_shift += top_shift_correction;
+ if(inline_boxes_dims.count)
+ {
+ const int diff2 = std::abs(inline_boxes_dims.top) - std::abs(top_shift);
+ if(diff2 > 0)
+ {
+ m_height += diff2;
+ top_shift += diff2;
+ m_baseline += diff2;
+ }
+ const int diff1 = inline_boxes_dims.bottom - (line_max_height.bottom + top_shift_correction);
+ if(diff1 > 0)
+ {
+ m_height += diff1;
+ }
+ }
+ } else if(inline_boxes_dims.count != 0)
+ {
+ // We have inline boxes only
+ m_height = inline_boxes_dims.height();
+ top_shift = std::abs(inline_boxes_dims.top);
+ m_baseline = inline_boxes_dims.bottom;
+ } else
{
- m_line_height = std::max(m_line_height, lbi->get_el()->css().get_line_height());
+ // We don't have inline items and inline boxes
+ top_shift = 0;
}
- }
- m_height = line_bottom - line_top;
- int top_shift = line_top;
- if(m_height < m_line_height)
+
+ const int top_down_height = std::max(top_aligned_max_height.max_height, bottom_aligned_max_height.max_height);
+ if(top_down_height > m_height)
+ {
+ if(bottom_aligned_max_height.count)
+ {
+ top_shift += bottom_aligned_max_height.height() - m_height;
+ }
+ m_height = top_down_height;
+ }
+ } else
{
- top_shift -= (m_line_height - m_height) / 2;
- m_height = m_line_height;
+ // Add inline boxes dimentions
+ line_max_height.top = std::min(line_max_height.top, inline_boxes_dims.top);
+ line_max_height.bottom = std::max(line_max_height.bottom, inline_boxes_dims.bottom);
+
+ // Height is maximum from inline elements height and top/bottom aligned elements height
+ m_height = std::max({line_max_height.height(), top_aligned_max_height.height(), bottom_aligned_max_height.height()});
+
+ top_shift = -std::min(line_max_height.top, line_max_height.bottom - bottom_aligned_max_height.height());
+ m_baseline = line_max_height.bottom;
}
- m_baseline = line_bottom;
struct inline_item_box
{
@@ -443,37 +602,30 @@ std::list< std::unique_ptr<litehtml::line_box_item> > litehtml::line_box::finish
current_context.baseline = 0;
current_context.fm = m_font_metrics;
- bool va_top_bottom = false;
+ current_context.start_lbi = nullptr;
+ //int va_top_bottom = 0;
+ // Second pass:
+ // 1. Vertical align top/bottom
+ // 2. Apply relative shift
+ // 3. Calculate inline boxes
for (const auto& lbi : m_items)
{
- // Calculate baseline. Now we calculate baseline for vertical alignment top and bottom
- if (lbi->get_type() == line_box_item::type_inline_start || lbi->get_type() == line_box_item::type_inline_continue)
+ if(is_one_of(lbi->get_type(), line_box_item::type_inline_start, line_box_item::type_inline_continue))
{
contexts.push_back(current_context);
- va_top_bottom = lbi->get_el()->css().get_vertical_align() == va_bottom || lbi->get_el()->css().get_vertical_align() == va_top;
- current_context.baseline = calc_va_baseline(current_context,
- lbi->get_el()->css().get_vertical_align(),
- lbi->get_el()->css().get_font_metrics(),
- top_shift, top_shift + m_height);
current_context.fm = lbi->get_el()->css().get_font_metrics();
- }
- // Align inlines and text by baseline if current vertical alignment is top or bottom
- if(va_top_bottom)
- {
- if (lbi->get_el()->src_el()->css().get_display() == display_inline_text ||
- lbi->get_el()->src_el()->css().get_display() == display_inline)
+ if(lbi->get_el()->css().get_vertical_align() == va_top)
{
- // inline elements and text are aligned by baseline only
- // at this point the baseline for text is properly aligned already
- lbi->pos().y = current_context.baseline - lbi->get_el()->css().get_font_metrics().height +
- lbi->get_el()->css().get_font_metrics().base_line();
+ current_context.baseline = m_top - lbi->get_items_top();
+ current_context.start_lbi = lbi.get();
+ } else if(lbi->get_el()->css().get_vertical_align() == va_bottom)
+ {
+ current_context.baseline = m_top + m_height - lbi->get_items_bottom();
+ current_context.start_lbi = lbi.get();
}
- }
-
- // Pop the prev context
- if (lbi->get_type() == line_box_item::type_inline_end)
+ } else if(lbi->get_type() == line_box_item::type_inline_end)
{
if(!contexts.empty())
{
@@ -482,20 +634,25 @@ std::list< std::unique_ptr<litehtml::line_box_item> > litehtml::line_box::finish
}
}
- // move element to the correct position
- lbi->pos().y += m_top - top_shift;
-
- // Perform vertical align top and bottom for inline boxes
- if(lbi->get_el()->css().get_display() != display_inline_text && lbi->get_el()->css().get_display() != display_inline)
- {
- if(lbi->get_el()->css().get_vertical_align() == va_top)
+ if(current_context.start_lbi)
+ {
+ lbi->pos().y = current_context.baseline - lbi->get_el()->get_last_baseline() +
+ lbi->get_el()->content_offset_top();
+ } else if(is_one_of(lbi->get_el()->css().get_vertical_align(), va_top, va_bottom) && lbi->get_type() == line_box_item::type_text_part)
+ {
+ if(lbi->get_el()->css().get_vertical_align() == va_top)
{
lbi->pos().y = m_top + lbi->get_el()->content_offset_top();
- } else if(lbi->get_el()->css().get_vertical_align() == va_bottom)
+ } else
{
- lbi->pos().y = m_top + m_height - lbi->get_el()->height() + lbi->get_el()->content_offset_top();
+ lbi->pos().y = m_top + m_height - (lbi->bottom() - lbi->top()) + lbi->get_el()->content_offset_bottom();
}
- }
+ } else
+ {
+ // move element to the correct position
+ lbi->pos().y += m_top + top_shift;
+ }
+
lbi->get_el()->apply_relative_shift(containing_block_size);
// Calculate and push inline box into the render item element
@@ -703,11 +860,9 @@ std::list< std::unique_ptr<litehtml::line_box_item> > litehtml::line_box::new_wi
{
remove_begin = i;
break;
- } else
- {
- (*i)->pos().x += add;
- m_width += (*i)->get_el()->width();
}
+ (*i)->pos().x += add;
+ m_width += (*i)->get_el()->width();
}
i++;
}
@@ -722,4 +877,3 @@ std::list< std::unique_ptr<litehtml::line_box_item> > litehtml::line_box::new_wi
}
return ret_items;
}
-
diff --git a/libs/litehtml/src/media_query.cpp b/libs/litehtml/src/media_query.cpp
index 8593f89f11..e2e17eb8a4 100644
--- a/libs/litehtml/src/media_query.cpp
+++ b/libs/litehtml/src/media_query.cpp
@@ -2,6 +2,8 @@
#include "media_query.h"
#include "css_parser.h"
#include <cassert>
+#include "document.h"
+#include "document_container.h"
#define UNE 8800 // u'≠'
#define ULE 10877 // u'⩽'
@@ -53,7 +55,7 @@ bool media_feature::check(const media_features& feat) const
return compare(feat.height >= feat.width ? _portrait_ : _landscape_);
case _aspect_ratio_:
// The standard calls 1/0 "a degenerate ratio" https://drafts.csswg.org/css-values-4/#ratio-value,
- // but it doesn't specify exactly how it behaves in this context: https://drafts.csswg.org/mediaqueries-5/#aspect-ratio.
+ // but it doesn't specify exactly how it behaves in this context: https://drafts.csswg.org/mediaqueries-5/#aspect-ratio.
// Chrome/Firefox work as expected with 1/0, for example when both width and height are nonzero
// (aspect-ratio < 1/0) evaluates to true. But they behave the same for 0/0, which is unexpected
// (0/0 is NaN, so any comparisons should evaluate to false).
@@ -79,12 +81,12 @@ trilean media_condition::check(const media_features& features) const
{
if (op == _not_)
return !m_conditions[0].check(features);
-
+
if (op == _and_)
{
// https://drafts.csswg.org/mediaqueries/#evaluating
- // The result is true if the <media-in-parens> child term and all of the <media-in-parens>
- // children of the <media-and> child terms are true, false if at least one of these
+ // The result is true if the <media-in-parens> child term and all of the <media-in-parens>
+ // children of the <media-and> child terms are true, false if at least one of these
// <media-in-parens> terms are false, and unknown otherwise.
trilean result = True;
for (const auto& condition : m_conditions)
@@ -96,8 +98,8 @@ trilean media_condition::check(const media_features& features) const
}
if (op == _or_)
{
- // The result is false if the <media-in-parens> child term and all of the <media-in-parens>
- // children of the <media-or> child terms are false, true if at least one of these
+ // The result is false if the <media-in-parens> child term and all of the <media-in-parens>
+ // children of the <media-or> child terms are false, true if at least one of these
// <media-in-parens> terms are true, and unknown otherwise.
trilean result = False;
for (const auto& condition : m_conditions)
@@ -129,7 +131,7 @@ trilean media_query::check(const media_features& features) const
result = False;
else if (m_media_type == media_type_all)
result = True;
- else
+ else
result = (trilean)(m_media_type == features.type);
if (result == True)
@@ -237,7 +239,7 @@ bool parse_media_query(const css_token_vector& tokens, media_query& mquery, docu
bool _not = false;
if (ident == "not") index++, _not = true;
else if (ident == "only") index++; // ignored https://drafts.csswg.org/mediaqueries-5/#mq-only
-
+
// <media-type> = <ident> except only, not, and, or, and layer
ident = at(tokens, index).ident();
if (is_one_of(ident, "", "only", "not", "and", "or", "layer"))
@@ -310,7 +312,7 @@ bool parse_media_in_parens(const css_token& token, media_in_parens& media_in_par
media_in_parens = unknown();
return true;
}
-
+
if (token.type != ROUND_BLOCK) return false;
const css_token_vector& tokens = token.value;
@@ -344,7 +346,7 @@ struct mf_info
string_id type = empty_id; // range, discrete
string_id value_type = empty_id; // length, ratio, resolution, integer, keyword
vector<string_id> keywords = {}; // default value is specified here to get rid of gcc warning "missing initializer for member"
-
+
operator bool() { return type != empty_id; }
};
@@ -407,7 +409,7 @@ bool convert_units(mf_info mfi, css_token val[2], document::ptr doc)
case _integer_:
// nothing to convert, just verify
return val[0].type == NUMBER && val[0].n.number_type == css_number_integer && val[1].type == 0;
-
+
case _length_:
{
if (val[1].type != 0) return false;
@@ -419,7 +421,7 @@ bool convert_units(mf_info mfi, css_token val[2], document::ptr doc)
val[0].n.number = length.val();
return true;
}
-
+
case _resolution_: // https://drafts.csswg.org/css-values-4/#resolution
if (val[1].type != 0) return false;
if (val[0].type == DIMENSION)
@@ -444,7 +446,7 @@ bool convert_units(mf_info mfi, css_token val[2], document::ptr doc)
}
// Note: <resolution> doesn't allow unitless zero
return false;
-
+
case _ratio_: // https://drafts.csswg.org/css-values-4/#ratio <ratio> = <number [0,∞]> [ / <number [0,∞]> ]?
if (val[0].type == NUMBER && val[0].n.number >= 0 &&
((val[1].type == NUMBER && val[1].n.number >= 0) || val[1].type == 0))
@@ -463,7 +465,7 @@ bool convert_units(mf_info mfi, css_token val[2], document::ptr doc)
val[0] = css_token(NUMBER, (float)ident);
return true;
}
-
+
default:
return false;
}
@@ -549,7 +551,7 @@ bool parse_media_feature(const css_token& token, media_feature& result, document
int index = 2;
if (!parse_mf_value(tokens, index, val) || index != (int)tokens.size())
return false;
-
+
media_feature mf = {tokens[0].ident()};
if (!mf.verify_and_convert_units(_plain_, val, nullptr, doc)) return false;
result = mf;
@@ -566,9 +568,9 @@ bool parse_mf_value(const css_token_vector& tokens, int& index, css_token val[2]
const css_token& a = at(tokens, index);
const css_token& b = at(tokens, index + 1);
const css_token& c = at(tokens, index + 2);
-
+
if (!is_one_of(a.type, NUMBER, DIMENSION, IDENT)) return false;
-
+
if (a.type == NUMBER && a.n.number >= 0 && b.ch == '/' &&
c.type == NUMBER && c.n.number >= 0)
{
diff --git a/libs/litehtml/src/render_block.cpp b/libs/litehtml/src/render_block.cpp
index 7e2867f35e..6fba641b03 100644
--- a/libs/litehtml/src/render_block.cpp
+++ b/libs/litehtml/src/render_block.cpp
@@ -1,8 +1,9 @@
-#include "html.h"
#include "render_block.h"
#include "render_inline_context.h"
#include "render_block_context.h"
#include "document.h"
+#include "document_container.h"
+#include "html_tag.h"
int litehtml::render_item_block::place_float(const std::shared_ptr<render_item> &el, int top, const containing_block_context &self_size, formatting_context* fmt_ctx)
{
@@ -199,7 +200,7 @@ int litehtml::render_item_block::_render(int x, int y, const containing_block_co
{
if(m_pos.height == 0)
{
- m_pos.height = css().get_line_height();
+ m_pos.height = css().line_height().computed_value;
}
}
diff --git a/libs/litehtml/src/render_block_context.cpp b/libs/litehtml/src/render_block_context.cpp
index 205485d478..d039985003 100644
--- a/libs/litehtml/src/render_block_context.cpp
+++ b/libs/litehtml/src/render_block_context.cpp
@@ -1,4 +1,3 @@
-#include "html.h"
#include "render_block_context.h"
#include "document.h"
diff --git a/libs/litehtml/src/render_flex.cpp b/libs/litehtml/src/render_flex.cpp
index 7b497cf312..ad8ff3a2fc 100644
--- a/libs/litehtml/src/render_flex.cpp
+++ b/libs/litehtml/src/render_flex.cpp
@@ -1,6 +1,6 @@
-#include "html.h"
#include "types.h"
#include "render_flex.h"
+#include "html_tag.h"
int litehtml::render_item_flex::_render_content(int x, int y, bool /*second_pass*/, const containing_block_context &self_size, formatting_context* fmt_ctx)
{
diff --git a/libs/litehtml/src/render_image.cpp b/libs/litehtml/src/render_image.cpp
index 23b059bd90..0f13216079 100644
--- a/libs/litehtml/src/render_image.cpp
+++ b/libs/litehtml/src/render_image.cpp
@@ -1,4 +1,3 @@
-#include "html.h"
#include "render_image.h"
#include "document.h"
@@ -19,7 +18,7 @@ int litehtml::render_item_image::_render(int x, int y, const containing_block_co
m_pos.width = sz.width;
m_pos.height = sz.height;
- src_el()->css_w().set_line_height(height());
+ src_el()->css_w().line_height_w().computed_value = height();
if(src_el()->css().get_height().is_predefined() && src_el()->css().get_width().is_predefined())
{
diff --git a/libs/litehtml/src/render_inline_context.cpp b/libs/litehtml/src/render_inline_context.cpp
index fcf23bf733..4c4d974800 100644
--- a/libs/litehtml/src/render_inline_context.cpp
+++ b/libs/litehtml/src/render_inline_context.cpp
@@ -1,4 +1,3 @@
-#include "html.h"
#include "render_inline_context.h"
#include "document.h"
#include "iterators.h"
@@ -150,7 +149,7 @@ void litehtml::render_item_inline_context::fix_line_width(element_float flt,
{
line_left += src_el()->css().get_text_indent().calc_percent(self_size.width);
}
-
+
}
auto items = m_line_boxes.back()->new_width(line_left, line_right);
@@ -227,7 +226,7 @@ int litehtml::render_item_inline_context::new_box(const std::unique_ptr<line_box
m_line_boxes.emplace_back(std::make_unique<line_box>(
line_ctx.top,
line_ctx.left + first_line_margin + text_indent, line_ctx.right,
- css().get_line_height(),
+ css().line_height(),
css().get_font_metrics(),
css().get_text_align()));
@@ -403,7 +402,7 @@ int litehtml::render_item_inline_context::get_last_baseline()
bl = line->bottom() - line->baseline() + content_offset_top();
} else
{
- bl = height() - margin_bottom();
+ bl = height();
}
return bl;
}
diff --git a/libs/litehtml/src/render_item.cpp b/libs/litehtml/src/render_item.cpp
index 5ec65ab049..3794807a4f 100644
--- a/libs/litehtml/src/render_item.cpp
+++ b/libs/litehtml/src/render_item.cpp
@@ -1,8 +1,8 @@
-#include "html.h"
#include "render_item.h"
#include "document.h"
#include <typeinfo>
-#include <utf8_strings.h>
+#include "document_container.h"
+#include "types.h"
litehtml::render_item::render_item(std::shared_ptr<element> _src_el) :
m_element(std::move(_src_el)),
@@ -46,7 +46,6 @@ int litehtml::render_item::render(int x, int y, const containing_block_context&
if(src_el()->is_block_formatting_context() || ! fmt_ctx)
{
formatting_context fmt;
- fmt.push_position(content_left, content_top);
ret = _render(x, y, containing_block_size, &fmt, second_pass);
fmt.apply_relative_shift(containing_block_size);
} else
@@ -243,8 +242,8 @@ bool litehtml::render_item::fetch_positioned()
void litehtml::render_item::render_positioned(render_type rt)
{
- position wnd_position;
- src_el()->get_document()->container()->get_client_rect(wnd_position);
+ position view_port;
+ src_el()->get_document()->container()->get_viewport(view_port);
element_position el_position;
bool process;
@@ -275,8 +274,8 @@ void litehtml::render_item::render_positioned(render_type rt)
containing_block_context containing_block_size;
if(el_position == element_position_fixed || (is_root() && !src_el()->is_positioned()))
{
- containing_block_size.height = wnd_position.height;
- containing_block_size.width = wnd_position.width;
+ containing_block_size.height = view_port.height;
+ containing_block_size.width = view_port.width;
} else
{
containing_block_size.height = m_pos.height + m_padding.height();
@@ -648,8 +647,8 @@ void litehtml::render_item::render_positioned(render_type rt)
if(el_position == element_position_fixed)
{
- position fixed_pos;
- el->get_redraw_box(fixed_pos);
+ position fixed_pos = el->pos();
+ el->get_redraw_box(fixed_pos);
src_el()->get_document()->add_fixed_box(fixed_pos);
}
}
@@ -832,12 +831,10 @@ void litehtml::render_item::draw_children(uint_ptr hdc, int x, int y, const posi
if (el->src_el()->is_positioned() && el->src_el()->css().get_z_index() == zindex)
{
if (el->src_el()->css().get_position() == element_position_fixed)
- {
- position browser_wnd;
- doc->container()->get_client_rect(browser_wnd);
-
- el->src_el()->draw(hdc, browser_wnd.x, browser_wnd.y, clip, el);
- el->draw_stacking_context(hdc, browser_wnd.x, browser_wnd.y, clip, true);
+ {
+ // Fixed elements position is always relative to the (0,0)
+ el->src_el()->draw(hdc, 0, 0, clip, el);
+ el->draw_stacking_context(hdc, 0, 0, clip, true);
}
else
{
@@ -1129,17 +1126,39 @@ void litehtml::render_item::get_rendering_boxes( position::vector& redraw_boxes)
if(src_el()->css().get_position() != element_position_fixed)
{
- auto cur_el = parent();
+ auto cur_el = parent();
+ int add_x = 0;
+ int add_y = 0;
+
while(cur_el)
- {
- for(auto& box : redraw_boxes)
- {
- box.x += cur_el->m_pos.x;
- box.y += cur_el->m_pos.y;
- }
+ {
+ if(cur_el->css().get_position() == element_position_fixed)
+ {
+ position view_port;
+ src_el()->get_document()->container()->get_viewport(view_port);
+ add_x += cur_el->m_pos.x + view_port.left();
+ add_y += cur_el->m_pos.y + view_port.top();
+ break;
+ }
+ add_x += cur_el->m_pos.x;
+ add_y += cur_el->m_pos.y;
cur_el = cur_el->parent();
}
- }
+ for(auto& box : redraw_boxes)
+ {
+ box.x += add_x;
+ box.y += add_y;
+ }
+ } else
+ {
+ position view_port;
+ src_el()->get_document()->container()->get_viewport(view_port);
+ for(auto& box : redraw_boxes)
+ {
+ box.x += view_port.left();
+ box.y += view_port.top();
+ }
+ }
}
void litehtml::render_item::dump(litehtml::dumper& cout)
diff --git a/libs/litehtml/src/render_table.cpp b/libs/litehtml/src/render_table.cpp
index 16a143eb43..4792f14972 100644
--- a/libs/litehtml/src/render_table.cpp
+++ b/libs/litehtml/src/render_table.cpp
@@ -1,4 +1,3 @@
-#include "html.h"
#include "render_table.h"
#include "document.h"
#include "iterators.h"
diff --git a/libs/litehtml/src/string_id.cpp b/libs/litehtml/src/string_id.cpp
index d197d24469..ac131962b7 100644
--- a/libs/litehtml/src/string_id.cpp
+++ b/libs/litehtml/src/string_id.cpp
@@ -2,10 +2,12 @@
#include "string_id.h"
#include <cassert>
+#include <Windows.h>
+#include <m_system.h>
+
#ifndef LITEHTML_NO_THREADS
- #include <mutex>
- static std::mutex mutex;
- #define lock_guard std::lock_guard<std::mutex> lock(mutex)
+ static mir_cs mutex;
+ #define lock_guard mir_cslock lock(mutex)
#else
#define lock_guard
#endif
diff --git a/libs/litehtml/src/style.cpp b/libs/litehtml/src/style.cpp
index 10768700a6..2707dd8bed 100644
--- a/libs/litehtml/src/style.cpp
+++ b/libs/litehtml/src/style.cpp
@@ -2,6 +2,9 @@
#include "style.h"
#include "css_parser.h"
#include "internal.h"
+#include <set>
+#include "html_tag.h"
+#include "document.h"
// All functions here assume that whitespace have been removed.
@@ -28,6 +31,7 @@ std::map<string_id, string> style::m_valid_values =
{ _float_, element_float_strings },
{ _clear_, element_clear_strings },
{ _overflow_, overflow_strings },
+ { _appearance_, appearance_strings },
{ _box_sizing_, box_sizing_strings },
{ _text_align_, text_align_strings },
@@ -62,6 +66,9 @@ std::map<string_id, string> style::m_valid_values =
{ _align_self_, flex_align_items_strings },
{ _caption_side_, caption_side_strings },
+
+ { _text_decoration_style_, style_text_decoration_style_strings },
+ { _text_emphasis_position_, style_text_emphasis_position_strings },
};
std::map<string_id, vector<string_id>> shorthands =
@@ -101,6 +108,9 @@ std::map<string_id, vector<string_id>> shorthands =
{ _flex_, {_flex_grow_, _flex_shrink_, _flex_basis_}},
{ _flex_flow_, {_flex_direction_, _flex_wrap_}},
+
+ { _text_decoration_, {_text_decoration_color_, _text_decoration_line_, _text_decoration_style_, _text_decoration_thickness_}},
+ { _text_emphasis_, {_text_emphasis_style_, _text_emphasis_color_}},
};
void style::add(const string& txt, const string& baseurl, document_container* container)
@@ -167,10 +177,10 @@ void style::add_property(string_id name, const css_token_vector& value, const st
// Note: empty value is a valid value for a custom property.
if (value.empty() && _s(name).substr(0, 2) != "--")
return;
-
+
if (has_var(value))
return add_parsed_property(name, property_value(value, important, true));
-
+
// valid only if value contains a single token
css_token val = value.size() == 1 ? value[0] : css_token();
// nonempty if value is a single identifier
@@ -193,6 +203,7 @@ void style::add_property(string_id name, const css_token_vector& value, const st
case _position_:
case _float_:
case _clear_:
+ case _appearance_:
case _box_sizing_:
case _overflow_:
@@ -203,6 +214,7 @@ void style::add_property(string_id name, const css_token_vector& value, const st
case _font_style_:
case _font_variant_:
+ case _text_decoration_style_:
case _list_style_type_:
case _list_style_position_:
@@ -233,7 +245,7 @@ void style::add_property(string_id name, const css_token_vector& value, const st
// <length-percentage> https://developer.mozilla.org/en-US/docs/Web/CSS/text-indent#formal_syntax
case _text_indent_:
return add_length_property(name, val, "", f_length_percentage, important);
-
+
// <length-percentage [0,∞]> https://developer.mozilla.org/en-US/docs/Web/CSS/padding-left
case _padding_left_:
case _padding_right_:
@@ -251,7 +263,7 @@ void style::add_property(string_id name, const css_token_vector& value, const st
case _margin_top_:
case _margin_bottom_:
return add_length_property(name, val, "auto", f_length_percentage, important);
-
+
// auto | min-content | max-content | fit-content | <length-percentage [0,∞]> https://developer.mozilla.org/en-US/docs/Web/CSS/width#formal_syntax
case _width_:
case _height_:
@@ -281,7 +293,7 @@ void style::add_property(string_id name, const css_token_vector& value, const st
if (int n = parse_1234_lengths(value, len, f_length_percentage | f_positive))
add_four_properties(_padding_top_, len, n, important);
break;
-
+
// ============================= COLOR =============================
case _color_:
@@ -370,8 +382,8 @@ void style::add_property(string_id name, const css_token_vector& value, const st
case _border_radius_x_:
case _border_radius_y_:
{
- string_id top_left = name == _border_radius_x_ ?
- _border_top_left_radius_x_ :
+ string_id top_left = name == _border_radius_x_ ?
+ _border_top_left_radius_x_ :
_border_top_left_radius_y_;
if (int n = parse_1234_lengths(value, len, f_length_percentage | f_positive))
@@ -424,10 +436,38 @@ void style::add_property(string_id name, const css_token_vector& value, const st
break;
case _text_decoration_:
+ parse_text_decoration(value, important, container);
+ break;
+
+ case _text_decoration_thickness_:
+ add_length_property(name, val, style_text_decoration_thickness_strings, f_length_percentage|f_positive, important);
+ break;
+
+ case _text_decoration_color_:
+ parse_text_decoration_color(val, important, container);
+ break;
+
+ case _text_decoration_line_:
+ parse_text_decoration_line(value, important);
+ break;
+
+ case _text_emphasis_:
+ parse_text_emphasis(value, important, container);
+ break;
+
+ case _text_emphasis_style_:
str = get_repr(value, 0, -1, true);
add_parsed_property(name, property_value(str, important));
break;
+ case _text_emphasis_color_:
+ parse_text_emphasis_color(val, important, container);
+ break;
+
+ case _text_emphasis_position_:
+ parse_text_emphasis_position(value, important);
+ break;
+
// ============================= FLEX =============================
case _flex_:
@@ -484,10 +524,10 @@ void style::add_property(string_id name, const css_token_vector& value, const st
break;
// ============================= CUSTOM PROPERTY =============================
-
+
// https://drafts.csswg.org/css-variables-2/#defining-variables
default:
- if (_s(name).substr(0, 2) == "--" && _s(name).size() >= 3 &&
+ if (_s(name).substr(0, 2) == "--" && _s(name).size() >= 3 &&
(value.empty() || is_declaration_value(value)))
add_parsed_property(name, property_value(value, important));
}
@@ -527,7 +567,7 @@ void style::parse_list_style(const css_token_vector& tokens, string baseurl, boo
for (const auto& token : tokens)
{
- // "...none is a valid value for both list-style-image and list-style-type. To resolve this ambiguity,
+ // "...none is a valid value for both list-style-image and list-style-type. To resolve this ambiguity,
// a value of none ... must be applied to whichever of the two properties aren’t otherwise set by the shorthand."
if (token.ident() == "none") {
none_count++;
@@ -566,12 +606,12 @@ void style::parse_list_style(const css_token_vector& tokens, string baseurl, boo
}
// https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius
-// border-radius = <length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?
+// border-radius = <length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?
void style::parse_border_radius(const css_token_vector& tokens, bool important)
{
int i;
for (i = 0; i < (int)tokens.size() && tokens[i].ch != '/'; i++) {}
-
+
if (i == (int)tokens.size()) // no '/'
{
css_length len[4];
@@ -585,11 +625,11 @@ void style::parse_border_radius(const css_token_vector& tokens, bool important)
{
auto raduis_x = slice(tokens, 0, i);
auto raduis_y = slice(tokens, i + 1);
-
+
css_length rx[4], ry[4];
int n = parse_1234_lengths(raduis_x, rx, f_length_percentage | f_positive);
int m = parse_1234_lengths(raduis_y, ry, f_length_percentage | f_positive);
-
+
if (n && m)
{
add_four_properties(_border_top_left_radius_x_, rx, n, important);
@@ -603,10 +643,10 @@ bool parse_border_width(const css_token& token, css_length& w)
css_length width;
if (!width.from_token(token, f_length | f_positive, border_width_strings))
return false;
-
+
if (width.is_predefined())
width.set_value(border_width_values[width.predef()], css_units_px);
-
+
w = width;
return true;
}
@@ -650,7 +690,7 @@ void style::parse_border(const css_token_vector& tokens, bool important, documen
css_length width;
border_style style;
web_color color;
-
+
if (!parse_border_helper(tokens, container, width, style, color))
return;
@@ -724,7 +764,7 @@ int parse_1234_lengths(const css_token_vector& tokens, css_length len[4], int op
// This function implements the logic of the kind "if two values are specified, the first one applies to
// top and bottom, the second one to left and right". Works in conjunction with parse_1234_values.
-template<class T>
+template<class T>
void style::add_four_properties(string_id top_name, T val[4], int n, bool important)
{
// These always go in trbl order, see comment for "CSS property names" in string_id.
@@ -751,7 +791,7 @@ void style::parse_background(const css_token_vector& tokens, const string& baseu
if (layers.empty()) return;
web_color color;
- std::vector<image> images;
+ std::vector<image> images;
length_vector x_positions, y_positions;
size_vector sizes;
int_vector repeats, attachments, origins, clips;
@@ -761,7 +801,7 @@ void style::parse_background(const css_token_vector& tokens, const string& baseu
background bg;
if (!parse_bg_layer(layers[i], container, bg, i == layers.size() - 1))
return;
-
+
color = bg.m_color;
images.push_back(bg.m_image[0]);
x_positions.push_back(bg.m_position_x[0]);
@@ -821,7 +861,7 @@ bool style::parse_bg_layer(const css_token_vector& tokens, document_container* c
repeat_found = true;
else if (!attachment_found && parse_keyword(tokens[i], bg.m_attachment[0], background_attachment_strings))
attachment_found = true;
- // If one <visual-box> value is present then it sets both background-origin and background-clip to that value.
+ // If one <visual-box> value is present then it sets both background-origin and background-clip to that value.
// If two values are present, then the first sets background-origin and the second background-clip.
else if (!origin_found && parse_keyword(tokens[i], bg.m_origin[0], background_box_strings))
origin_found = true, bg.m_clip[0] = bg.m_origin[0];
@@ -841,7 +881,7 @@ bool parse_bg_position_size(const css_token_vector& tokens, int& index, css_leng
if (at(tokens, index).ch != '/')
return true; // no [ / <bg-size> ]
-
+
if (!parse_bg_size(tokens, ++index, size))
{
index--; // restore index to point to '/'
@@ -859,7 +899,7 @@ bool parse_bg_size(const css_token_vector& tokens, int& index, css_size& size)
if (!a.from_token(at(tokens, index), f_length_percentage | f_positive, background_size_strings))
return false;
-
+
// cover | contain
if (a.is_predefined() && a.predef() != background_size_auto)
{
@@ -900,7 +940,7 @@ bool parse_bg_position(const css_token_vector& tokens, int& index, css_length& x
bottom = background_position_bottom,
center = background_position_center
};
-
+
css_length a, b;
if (!a.from_token(at(tokens, index), f_length_percentage, background_position_strings))
@@ -924,7 +964,7 @@ bool parse_bg_position(const css_token_vector& tokens, int& index, css_length& x
if ((is_one_of_predef(a, top, bottom) && b.is_predefined()) ||
(a.is_predefined() && is_one_of_predef(b, left, right)))
swap(a, b);
-
+
// check for wrong order
if (is_one_of_predef(a, top, bottom) || is_one_of_predef(b, left, right))
return false;
@@ -939,7 +979,7 @@ bool parse_bg_position(const css_token_vector& tokens, int& index, css_length& x
if (b.is_predefined())
b.set_value(background_position_percentages[b.predef()], css_units_percentage);
}
-
+
x = a;
y = b;
return true;
@@ -949,7 +989,7 @@ void style::parse_background_image(const css_token_vector& tokens, const string&
{
auto layers = parse_comma_separated_list(tokens);
if (layers.empty()) return;
-
+
std::vector<image> images;
for (const auto& layer : layers)
@@ -1009,7 +1049,7 @@ bool parse_url(const css_token& tok, string& url)
url = trim(tok.value[0].str);
return true;
}
-
+
return false;
}
@@ -1231,6 +1271,121 @@ void style::parse_font(css_token_vector tokens, bool important)
add_parsed_property(_font_family_, property_value(font_family, important));
}
+void style::parse_text_decoration(const css_token_vector& tokens, bool important, document_container* container)
+{
+ css_length len;
+ css_token_vector line_tokens;
+ for(const auto& token : tokens)
+ {
+ if(parse_text_decoration_color(token, important, container)) continue;
+
+ if(parse_length(token, len, f_length_percentage|f_positive, style_text_decoration_thickness_strings))
+ {
+ add_parsed_property(_text_decoration_thickness_, property_value(len, important));
+ } else
+ {
+ if(token.type == IDENT)
+ {
+ int style = value_index(token.ident(), style_text_decoration_style_strings);
+ if(style >= 0)
+ {
+ add_parsed_property(_text_decoration_style_, property_value(style, important));
+ } else
+ {
+ line_tokens.push_back(token);
+ }
+ } else
+ {
+ line_tokens.push_back(token);
+ }
+ }
+ }
+ if(!line_tokens.empty())
+ {
+ parse_text_decoration_line(line_tokens, important);
+ }
+}
+
+bool style::parse_text_decoration_color(const css_token& token, bool important, document_container* container)
+{
+ web_color _color;
+ if(parse_color(token, _color, container))
+ {
+ add_parsed_property(_text_decoration_color_, property_value(_color, important));
+ return true;
+ }
+ if(token.type == IDENT && value_in_list(token.ident(), "auto;currentcolor"))
+ {
+ add_parsed_property(_text_decoration_color_, property_value(web_color::current_color, important));
+ return true;
+ }
+ return false;
+}
+
+void style::parse_text_decoration_line(const css_token_vector& tokens, bool important)
+{
+ int val = 0;
+ for(const auto& token : tokens)
+ {
+ if(token.type == IDENT)
+ {
+ int idx = value_index(token.ident(), style_text_decoration_line_strings);
+ if(idx >= 0)
+ {
+ val |= 1 << (idx - 1);
+ }
+ }
+ }
+ add_parsed_property(_text_decoration_line_, property_value(val, important));
+}
+
+void style::parse_text_emphasis(const css_token_vector& tokens, bool important, document_container *container) {
+ string style;
+ for(const auto& token : std::vector(tokens.rbegin(), tokens.rend()))
+ {
+ if(parse_text_emphasis_color(token, important, container)) continue;
+ style.insert(0, token.str + " ");
+ }
+ style = trim(style);
+ if (!style.empty())
+ {
+ add_parsed_property(_text_emphasis_style_, property_value(style, important));
+ }
+}
+
+bool style::parse_text_emphasis_color(const css_token &token, bool important, document_container *container)
+{
+ web_color _color;
+ if(parse_color(token, _color, container))
+ {
+ add_parsed_property(_text_emphasis_color_, property_value(_color, important));
+ return true;
+ }
+ if(token.type == IDENT && value_in_list(token.ident(), "auto;currentcolor"))
+ {
+ add_parsed_property(_text_emphasis_color_, property_value(web_color::current_color, important));
+ return true;
+ }
+ return false;
+}
+
+void style::parse_text_emphasis_position(const css_token_vector &tokens, bool important)
+{
+ int val = 0;
+ for(const auto& token : tokens)
+ {
+ if(token.type == IDENT)
+ {
+ int idx = value_index(token.ident(), style_text_emphasis_position_strings);
+ if(idx >= 0)
+ {
+ val |= 1 << (idx - 1);
+ }
+ }
+ }
+ add_parsed_property(_text_emphasis_position_, property_value(val, important));
+}
+
// https://developer.mozilla.org/en-US/docs/Web/CSS/flex
// https://drafts.csswg.org/css-flexbox/#flex-property
// flex = none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
@@ -1355,9 +1510,9 @@ void style::parse_align_self(string_id name, const css_token_vector& tokens, boo
return;
if (tokens[0].type != IDENT || (n == 2 && tokens[1].type != IDENT))
return;
-
+
string a = tokens[0].ident();
-
+
if (name == _align_items_ && a == "auto")
return;
@@ -1441,11 +1596,11 @@ const property_value& style::get_property(string_id name) const
bool check_var_syntax(const css_token_vector& args)
{
if (args.empty()) return false;
-
+
string name = args[0].ident();
if (name.substr(0, 2) != "--" || name.size() <= 2)
return false;
-
+
if (args.size() > 1 && args[1].ch != ',')
return false;
if (args.size() > 2 && !is_declaration_value(args, 2))
@@ -1467,11 +1622,11 @@ bool subst_var(css_token_vector& tokens, const html_tag* el, std::set<string_id>
{
auto args = tok.value; // copy is intentional
if (!check_var_syntax(args)) return false;
-
+
auto name = _id(args[0].name);
if (name in used_vars) return false; // dependency cycle https://drafts.csswg.org/css-variables/#cycles
used_vars.insert(name);
-
+
css_token_vector value;
if (el->get_custom_property(name, value))
{
diff --git a/libs/litehtml/src/stylesheet.cpp b/libs/litehtml/src/stylesheet.cpp
index bb428b1328..d6ddca5e8f 100644
--- a/libs/litehtml/src/stylesheet.cpp
+++ b/libs/litehtml/src/stylesheet.cpp
@@ -1,6 +1,8 @@
#include "html.h"
#include "stylesheet.h"
#include "css_parser.h"
+#include "document.h"
+#include "document_container.h"
namespace litehtml
{
@@ -12,12 +14,12 @@ void css::parse_css_stylesheet(const Input& input, string baseurl, document::ptr
if (doc && media)
doc->add_media_list(media);
- // To parse a CSS stylesheet, first parse a stylesheet.
+ // To parse a CSS stylesheet, first parse a stylesheet.
auto rules = css_parser::parse_stylesheet(input, top_level);
bool import_allowed = top_level;
// Interpret all of the resulting top-level qualified rules as style rules, defined below.
- // If any style rule is invalid, or any at-rule is not recognized or is invalid according
+ // If any style rule is invalid, or any at-rule is not recognized or is invalid according
// to its grammar or context, it's a parse error. Discard that rule.
for (auto rule : rules)
{
@@ -40,7 +42,7 @@ void css::parse_css_stylesheet(const Input& input, string baseurl, document::ptr
else
css_parse_error("incorrect placement of @import rule");
break;
-
+
// https://www.w3.org/TR/css-conditional-3/#at-media
// @media <media-query-list> { <stylesheet> }
case _media_:
@@ -58,7 +60,7 @@ void css::parse_css_stylesheet(const Input& input, string baseurl, document::ptr
import_allowed = false;
break;
}
-
+
default:
css_parse_error("unrecognized rule @" + rule->name);
}
@@ -115,7 +117,7 @@ bool css::parse_style_rule(raw_rule::ptr rule, string baseurl, document::ptr doc
}
style::ptr style = make_shared<litehtml::style>(); // style block
- // The content of the qualified rule's block is parsed as a style block's contents.
+ // The content of the qualified rule's block is parsed as a style block's contents.
style->add(rule->block.value, baseurl, doc->container());
for (auto sel : list)
diff --git a/libs/litehtml/src/url.cpp b/libs/litehtml/src/url.cpp
index caa8fbb9d3..dbae382ace 100644
--- a/libs/litehtml/src/url.cpp
+++ b/libs/litehtml/src/url.cpp
@@ -29,7 +29,6 @@
#include "url.h"
-#include <iostream>
#include <sstream>
#include <algorithm>
diff --git a/libs/litehtml/src/utf8_strings.cpp b/libs/litehtml/src/utf8_strings.cpp
index f720f6d26c..6a578e1b9e 100644
--- a/libs/litehtml/src/utf8_strings.cpp
+++ b/libs/litehtml/src/utf8_strings.cpp
@@ -1,4 +1,3 @@
-#include "html.h"
#include "utf8_strings.h"
namespace litehtml
@@ -13,7 +12,7 @@ char32_t read_utf8_char(const string& str, int& index)
if (!str[index]) return 0;
return str[index++];
};
-
+
byte b1 = getb();
// Determine whether we are dealing
diff --git a/libs/litehtml/src/web_color.cpp b/libs/litehtml/src/web_color.cpp
index 51c6e762f1..c9472432d7 100644
--- a/libs/litehtml/src/web_color.cpp
+++ b/libs/litehtml/src/web_color.cpp
@@ -1,6 +1,8 @@
#include "html.h"
#include "web_color.h"
#include "css_parser.h"
+#include "os_types.h"
+#include "document_container.h"
namespace litehtml
{
@@ -18,7 +20,7 @@ struct def_color
const char* rgb;
};
-def_color g_def_colors[] =
+def_color g_def_colors[] =
{
{"transparent","rgba(0, 0, 0, 0)"},
{"AliceBlue","#F0F8FF"},
@@ -268,7 +270,7 @@ bool parse_rgb_func(const css_token& tok, web_color& color)
int n = (int)list.size();
if (!is_one_of(n, 1, 3, 4))
return false;
-
+
css_length r, g, b, a(1, css_units_none);
// legacy syntax: <percentage>#{3} , <alpha-value>? | <number>#{3} , <alpha-value>?
if (n != 1)
@@ -354,18 +356,18 @@ bool parse_hsl_func(const css_token& tok, web_color& color)
float lit = l.val();
// For historical reasons, if the saturation is less than 0% it is clamped to 0% at parsed-value time, before being converted to an sRGB color.
if (sat < 0) sat = 0;
-
+
// Note: Chrome and Firefox treat invalid hsl values differently.
- //
- // Note: at this point, sat is not clamped at 100, and lit is not clamped at all. The standard
+ //
+ // Note: at this point, sat is not clamped at 100, and lit is not clamped at all. The standard
// mentions only clamping sat at 0. As a result, returning rgb values may not be inside [0,1].
float r, g, b;
hsl_to_rgb(hue, sat, lit, r, g, b);
-
+
r = clamp(r, 0, 1);
g = clamp(g, 0, 1);
b = clamp(b, 0, 1);
-
+
color = web_color(
(byte)round(r * 255),
(byte)round(g * 255),
@@ -411,9 +413,9 @@ bool parse_name_color(const css_token& tok, web_color& color, document_container
// https://drafts.csswg.org/css-color-5/#typedef-color
bool parse_color(const css_token& tok, web_color& color, document_container* container)
{
- return
- parse_hash_color(tok, color) ||
- parse_func_color(tok, color) ||
+ return
+ parse_hash_color(tok, color) ||
+ parse_func_color(tok, color) ||
parse_name_color(tok, color, container);
}