1 #ifndef LH_ELEMENT_H
2 #define LH_ELEMENT_H
3 
4 #include <memory>
5 #include "stylesheet.h"
6 #include "css_offsets.h"
7 
8 namespace litehtml
9 {
10 	class box;
11 
12 	class element : public std::enable_shared_from_this<element>
13 	{
14 		friend class block_box;
15 		friend class line_box;
16 		friend class html_tag;
17 		friend class el_table;
18 		friend class document;
19 	public:
20 		typedef std::shared_ptr<litehtml::element>		ptr;
21 		typedef std::weak_ptr<litehtml::element>		weak_ptr;
22 	protected:
23 		std::weak_ptr<element>		m_parent;
24 		std::weak_ptr<litehtml::document>	m_doc;
25 		litehtml::box*				m_box;
26 		elements_vector				m_children;
27 		position					m_pos;
28 		margins						m_margins;
29 		margins						m_padding;
30 		margins						m_borders;
31 		bool						m_skip;
32 
33 		virtual void select_all(const css_selector& selector, elements_vector& res);
34 	public:
35 		element(const std::shared_ptr<litehtml::document>& doc);
36 		virtual ~element();
37 
38 		// returns refer to m_pos member;
39 		position&					get_position();
40 
41 		int							left()						const;
42 		int							right()						const;
43 		int							top()						const;
44 		int							bottom()					const;
45 		int							height()					const;
46 		int							width()						const;
47 
48 		int							content_margins_top()		const;
49 		int							content_margins_bottom()	const;
50 		int							content_margins_left()		const;
51 		int							content_margins_right()		const;
52 		int							content_margins_width()		const;
53 		int							content_margins_height()	const;
54 
55 		int							margin_top()				const;
56 		int							margin_bottom()				const;
57 		int							margin_left()				const;
58 		int							margin_right()				const;
59 		margins						get_margins()				const;
60 
61 		int							padding_top()				const;
62 		int							padding_bottom()			const;
63 		int							padding_left()				const;
64 		int							padding_right()				const;
65 		margins						get_paddings()				const;
66 
67 		int							border_top()				const;
68 		int							border_bottom()				const;
69 		int							border_left()				const;
70 		int							border_right()				const;
71 		margins						get_borders()				const;
72 
73 		bool						in_normal_flow()			const;
74 		litehtml::web_color			get_color(const tchar_t* prop_name, bool inherited, const litehtml::web_color& def_color = litehtml::web_color());
75 		bool						is_inline_box()				const;
76 		position					get_placement()				const;
77 		bool						collapse_top_margin()		const;
78 		bool						collapse_bottom_margin()	const;
79 		bool						is_positioned()				const;
80 
81 		bool						skip();
82 		void						skip(bool val);
83 		bool						have_parent() const;
84 		element::ptr				parent() const;
85 		void						parent(element::ptr par);
86 		bool						is_visible() const;
87 		int							calc_width(int defVal) const;
88 		int							get_inline_shift_left();
89 		int							get_inline_shift_right();
90 		void						apply_relative_shift(int parent_width);
91 
92 		std::shared_ptr<document>	get_document() const;
93 
94 		virtual elements_vector		select_all(const tstring& selector);
95 		virtual elements_vector		select_all(const css_selector& selector);
96 
97 		virtual element::ptr		select_one(const tstring& selector);
98 		virtual element::ptr		select_one(const css_selector& selector);
99 
100 		virtual int					render(int x, int y, int max_width, bool second_pass = false);
101 		virtual int					render_inline(const ptr &container, int max_width);
102 		virtual int					place_element(const ptr &el, int max_width);
103 		virtual void				calc_outlines( int parent_width );
104 		virtual void				calc_auto_margins(int parent_width);
105 		virtual void				apply_vertical_align();
106 		virtual bool				fetch_positioned();
107 		virtual void				render_positioned(render_type rt = render_all);
108 
109 		virtual bool				appendChild(const ptr &el);
110 		virtual bool				removeChild(const ptr &el);
111 		virtual void				clearRecursive();
112 
113 		virtual const tchar_t*		get_tagName() const;
114 		virtual void				set_tagName(const tchar_t* tag);
115 		virtual void				set_data(const tchar_t* data);
116 		virtual element_float		get_float() const;
117 		virtual vertical_align		get_vertical_align() const;
118 		virtual element_clear		get_clear() const;
119 		virtual size_t				get_children_count() const;
120 		virtual element::ptr		get_child(int idx) const;
121 		virtual overflow			get_overflow() const;
122 
123 		virtual css_length			get_css_left() const;
124 		virtual css_length			get_css_right() const;
125 		virtual css_length			get_css_top() const;
126 		virtual css_length			get_css_bottom() const;
127 		virtual css_offsets			get_css_offsets() const;
128 		virtual css_length			get_css_width() const;
129 		virtual void				set_css_width(css_length& w);
130 		virtual css_length			get_css_height() const;
131 
132 		virtual void				set_attr(const tchar_t* name, const tchar_t* val);
133 		virtual const tchar_t*		get_attr(const tchar_t* name, const tchar_t* def = 0);
134 		virtual void				apply_stylesheet(const litehtml::css& stylesheet);
135 		virtual void				refresh_styles();
136 		virtual bool				is_white_space() const;
137 		virtual bool				is_body() const;
138 		virtual bool				is_break() const;
139 		virtual int					get_base_line();
140 		virtual bool				on_mouse_over();
141 		virtual bool				on_mouse_leave();
142 		virtual bool				on_lbutton_down();
143 		virtual bool				on_lbutton_up();
144 		virtual void				on_click();
145 		virtual bool				find_styles_changes(position::vector& redraw_boxes, int x, int y);
146 		virtual const tchar_t*		get_cursor();
147 		virtual void				init_font();
148 		virtual bool				is_point_inside(int x, int y);
149 		virtual bool				set_pseudo_class(const tchar_t* pclass, bool add);
150 		virtual bool				set_class(const tchar_t* pclass, bool add);
151 		virtual bool				is_replaced() const;
152 		virtual int					line_height() const;
153 		virtual white_space			get_white_space() const;
154 		virtual style_display		get_display() const;
155 		virtual visibility			get_visibility() const;
156 		virtual element_position	get_element_position(css_offsets* offsets = 0) const;
157 		virtual void				get_inline_boxes(position::vector& boxes);
158 		virtual void				parse_styles(bool is_reparse = false);
159 		virtual void				draw(uint_ptr hdc, int x, int y, const position* clip);
160 		virtual void				draw_background( uint_ptr hdc, int x, int y, const position* clip );
161 		virtual const tchar_t*		get_style_property(const tchar_t* name, bool inherited, const tchar_t* def = 0);
162 		virtual uint_ptr			get_font(font_metrics* fm = 0);
163 		virtual int					get_font_size() const;
164 		virtual void				get_text(tstring& text);
165 		virtual void				parse_attributes();
166 		virtual int					select(const css_selector& selector, bool apply_pseudo = true);
167 		virtual int					select(const css_element_selector& selector, bool apply_pseudo = true);
168 		virtual element::ptr		find_ancestor(const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = 0);
169 		virtual bool				is_ancestor(const ptr &el) const;
170 		virtual element::ptr		find_adjacent_sibling(const element::ptr& el, const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = 0);
171 		virtual element::ptr		find_sibling(const element::ptr& el, const css_selector& selector, bool apply_pseudo = true, bool* is_pseudo = 0);
172 		virtual bool				is_first_child_inline(const element::ptr& el) const;
173 		virtual bool				is_last_child_inline(const element::ptr& el);
174 		virtual bool				have_inline_child() const;
175 		virtual void				get_content_size(size& sz, int max_width);
176 		virtual void				init();
177 		virtual bool				is_floats_holder() const;
178 		virtual int					get_floats_height(element_float el_float = float_none) const;
179 		virtual int					get_left_floats_height() const;
180 		virtual int					get_right_floats_height() const;
181 		virtual int					get_line_left(int y);
182 		virtual int					get_line_right(int y, int def_right);
183 		virtual void				get_line_left_right(int y, int def_right, int& ln_left, int& ln_right);
184 		virtual void				add_float(const ptr &el, int x, int y);
185 		virtual void				update_floats(int dy, const ptr &parent);
186 		virtual void				add_positioned(const ptr &el);
187 		virtual int					find_next_line_top(int top, int width, int def_right);
188 		virtual int					get_zindex() const;
189 		virtual void				draw_stacking_context(uint_ptr hdc, int x, int y, const position* clip, bool with_positioned);
190 		virtual void				draw_children( uint_ptr hdc, int x, int y, const position* clip, draw_flag flag, int zindex );
191 		virtual bool				is_nth_child(const element::ptr& el, int num, int off, bool of_type) const;
192 		virtual bool				is_nth_last_child(const element::ptr& el, int num, int off, bool of_type) const;
193 		virtual bool				is_only_child(const element::ptr& el, bool of_type) const;
194 		virtual bool				get_predefined_height(int& p_height) const;
195 		virtual void				calc_document_size(litehtml::size& sz, int x = 0, int y = 0);
196 		virtual void				get_redraw_box(litehtml::position& pos, int x = 0, int y = 0);
197 		virtual void				add_style(const litehtml::style& st);
198 		virtual element::ptr		get_element_by_point(int x, int y, int client_x, int client_y);
199 		virtual element::ptr		get_child_by_point(int x, int y, int client_x, int client_y, draw_flag flag, int zindex);
200 		virtual const background*	get_background(bool own_only = false);
201 	};
202 
203 	//////////////////////////////////////////////////////////////////////////
204 	//							INLINE FUNCTIONS							//
205 	//////////////////////////////////////////////////////////////////////////
206 
right()207 	inline int litehtml::element::right() const
208 	{
209 		return left() + width();
210 	}
211 
left()212 	inline int litehtml::element::left() const
213 	{
214 		return m_pos.left() - margin_left() - m_padding.left - m_borders.left;
215 	}
216 
top()217 	inline int litehtml::element::top() const
218 	{
219 		return m_pos.top() - margin_top() - m_padding.top - m_borders.top;
220 	}
221 
bottom()222 	inline int litehtml::element::bottom() const
223 	{
224 		return top() + height();
225 	}
226 
height()227 	inline int litehtml::element::height() const
228 	{
229 		return m_pos.height + margin_top() + margin_bottom() + m_padding.height() + m_borders.height();
230 	}
231 
width()232 	inline int litehtml::element::width() const
233 	{
234 		return m_pos.width + margin_left() + margin_right() + m_padding.width() + m_borders.width();
235 	}
236 
content_margins_top()237 	inline int litehtml::element::content_margins_top() const
238 	{
239 		return margin_top() + m_padding.top + m_borders.top;
240 	}
241 
content_margins_bottom()242 	inline int litehtml::element::content_margins_bottom() const
243 	{
244 		return margin_bottom() + m_padding.bottom + m_borders.bottom;
245 	}
246 
content_margins_left()247 	inline int litehtml::element::content_margins_left() const
248 	{
249 		return margin_left() + m_padding.left + m_borders.left;
250 	}
251 
content_margins_right()252 	inline int litehtml::element::content_margins_right() const
253 	{
254 		return margin_right() + m_padding.right + m_borders.right;
255 	}
256 
content_margins_width()257 	inline int litehtml::element::content_margins_width() const
258 	{
259 		return content_margins_left() + content_margins_right();
260 	}
261 
content_margins_height()262 	inline int litehtml::element::content_margins_height() const
263 	{
264 		return content_margins_top() + content_margins_bottom();
265 	}
266 
get_paddings()267 	inline litehtml::margins litehtml::element::get_paddings()	const
268 	{
269 		return m_padding;
270 	}
271 
get_borders()272 	inline litehtml::margins litehtml::element::get_borders()	const
273 	{
274 		return m_borders;
275 	}
276 
padding_top()277 	inline int litehtml::element::padding_top() const
278 	{
279 		return m_padding.top;
280 	}
281 
padding_bottom()282 	inline int litehtml::element::padding_bottom() const
283 	{
284 		return m_padding.bottom;
285 	}
286 
padding_left()287 	inline int litehtml::element::padding_left() const
288 	{
289 		return m_padding.left;
290 	}
291 
padding_right()292 	inline int litehtml::element::padding_right() const
293 	{
294 		return m_padding.right;
295 	}
296 
in_normal_flow()297 	inline bool litehtml::element::in_normal_flow() const
298 	{
299 		if(get_element_position() != element_position_absolute && get_display() != display_none)
300 		{
301 			return true;
302 		}
303 		return false;
304 	}
305 
border_top()306 	inline int litehtml::element::border_top() const
307 	{
308 		return m_borders.top;
309 	}
310 
border_bottom()311 	inline int litehtml::element::border_bottom() const
312 	{
313 		return m_borders.bottom;
314 	}
315 
border_left()316 	inline int litehtml::element::border_left() const
317 	{
318 		return m_borders.left;
319 	}
320 
border_right()321 	inline int litehtml::element::border_right() const
322 	{
323 		return m_borders.right;
324 	}
325 
skip()326 	inline bool litehtml::element::skip()
327 	{
328 		return m_skip;
329 	}
330 
skip(bool val)331 	inline void litehtml::element::skip(bool val)
332 	{
333 		m_skip = val;
334 	}
335 
have_parent()336 	inline bool litehtml::element::have_parent() const
337 	{
338 		return !m_parent.expired();
339 	}
340 
parent()341 	inline element::ptr litehtml::element::parent() const
342 	{
343 		return m_parent.lock();
344 	}
345 
parent(element::ptr par)346 	inline void litehtml::element::parent(element::ptr par)
347 	{
348 		m_parent = par;
349 	}
350 
margin_top()351 	inline int litehtml::element::margin_top() const
352 	{
353 		return m_margins.top;
354 	}
355 
margin_bottom()356 	inline int litehtml::element::margin_bottom() const
357 	{
358 		return m_margins.bottom;
359 	}
360 
margin_left()361 	inline int litehtml::element::margin_left() const
362 	{
363 		return m_margins.left;
364 	}
365 
margin_right()366 	inline int litehtml::element::margin_right() const
367 	{
368 		return m_margins.right;
369 	}
370 
get_margins()371 	inline litehtml::margins litehtml::element::get_margins() const
372 	{
373 		margins ret;
374 		ret.left	= margin_left();
375 		ret.right	= margin_right();
376 		ret.top		= margin_top();
377 		ret.bottom	= margin_bottom();
378 
379 		return ret;
380 	}
381 
is_positioned()382 	inline bool litehtml::element::is_positioned()	const
383 	{
384 		return (get_element_position() > element_position_static);
385 	}
386 
is_visible()387 	inline bool litehtml::element::is_visible() const
388 	{
389 		return !(m_skip || get_display() == display_none || get_visibility() != visibility_visible);
390 	}
391 
get_position()392 	inline position& litehtml::element::get_position()
393 	{
394 		return m_pos;
395 	}
396 
get_document()397 	inline std::shared_ptr<document> element::get_document() const
398 	{
399 		return m_doc.lock();
400 	}
401 }
402 
403 #endif  // LH_ELEMENT_H
404