aboutsummaryrefslogtreecommitdiffstats
path: root/include/litehtml/document.h
blob: 0898b44497cd1942165120be62ae4dbd92675aaa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#ifndef LH_DOCUMENT_H
#define LH_DOCUMENT_H

#include "stylesheet.h"
#include "types.h"
#include "master_css.h"
#include "encodings.h"
#include "font_description.h"

typedef struct GumboInternalOutput GumboOutput;

namespace litehtml
{
	struct css_text
	{
		typedef std::vector<css_text>	vector;

		string	text;
		string	baseurl;
		string	media;

		css_text() = default;

		css_text(const char* txt, const char* url, const char* media_str)
		{
			text	= txt ? txt : "";
			baseurl	= url ? url : "";
			media	= media_str ? media_str : "";
		}
	};

	class dumper
	{
	public:
		virtual ~dumper() {}
		virtual void begin_node(const string& descr) = 0;
		virtual void end_node() = 0;
		virtual void begin_attrs_group(const string& descr) = 0;
		virtual void end_attrs_group() = 0;
		virtual void add_attr(const string& name, const string& value) = 0;
	};

	class html_tag;
	class render_item;

	class document : public std::enable_shared_from_this<document>
	{
	public:
		typedef std::shared_ptr<document>	ptr;
		typedef std::weak_ptr<document>		weak_ptr;
	private:
		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;
		litehtml::css						m_master_css;
		litehtml::css						m_user_css;
		litehtml::size						m_size;
		position::vector					m_fixed_boxes;
		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;
		string								m_lang;
		string								m_culture;
		string								m_text;
		document_mode						m_mode = no_quirks_mode;
	public:
		document(document_container* objContainer);
		virtual ~document();

		document_container*				container()	{ return m_container; }
		document_mode					mode() const { return m_mode; }
		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; }
		void 							cvt_units(css_length& val, const font_metrics& metrics, int size) const;
		int								to_pixels(const css_length& val, const font_metrics& metrics, int size) const;
		int								width() const;
		int								height() const;
		void							add_stylesheet(const char* str, const char* baseurl, const char* media);
		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);
		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);
		void							add_media_list(media_query_list_list::ptr list);
		bool							media_changed();
		bool							lang_changed();
		bool							match_lang(const string& lang);
		void							add_tabular(const std::shared_ptr<render_item>& el);
		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);

		// see doc/document_createFromString.txt
		static document::ptr  createFromString(
			const estring&       str,
			document_container*  container,
			const string&        master_styles = litehtml::master_css,
			const string&        user_styles = "");

	private:
		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);
		bool update_media_lists(const media_features& features);
		void fix_tables_layout();
		void fix_table_children(const std::shared_ptr<render_item>& el_ptr, style_display disp, const char* disp_str);
		void fix_table_parent(const std::shared_ptr<render_item> & el_ptr, style_display disp, const char* disp_str);
	};

	inline std::shared_ptr<element> document::root()
	{
		return m_root;
	}

	inline std::shared_ptr<render_item> document::root_render()
	{
		return m_root_render;
	}

	inline void document::add_tabular(const std::shared_ptr<render_item>& el)
	{
		m_tabular_elements.push_back(el);
	}
	inline bool document::match_lang(const string& lang)
	{
		return lang == m_lang || lang == m_culture;
	}
}

#endif  // LH_DOCUMENT_H