1 /*
2 * Copyright (C) 2018-2021 Alexander Borisov
3 *
4 * Author: Alexander Borisov <borisov@lexbor.com>
5 */
6
7 #ifndef LEXBOR_HTML_DOCUMENT_H
8 #define LEXBOR_HTML_DOCUMENT_H
9
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13
14 #include "lexbor/core/mraw.h"
15 #include "lexbor/core/avl.h"
16
17 #include "lexbor/tag/tag.h"
18 #include "lexbor/ns/ns.h"
19 #include "lexbor/html/interface.h"
20 #include "lexbor/dom/interfaces/attr.h"
21 #include "lexbor/dom/interfaces/document.h"
22 #include "lexbor/css/css.h"
23
24
25 typedef lxb_status_t
26 (*lxb_html_document_done_cb_f)(lxb_html_document_t *document);
27
28 typedef unsigned int lxb_html_document_opt_t;
29
30 typedef enum {
31 LXB_HTML_DOCUMENT_READY_STATE_UNDEF = 0x00,
32 LXB_HTML_DOCUMENT_READY_STATE_LOADING = 0x01,
33 LXB_HTML_DOCUMENT_READY_STATE_INTERACTIVE = 0x02,
34 LXB_HTML_DOCUMENT_READY_STATE_COMPLETE = 0x03,
35 }
36 lxb_html_document_ready_state_t;
37
38 enum lxb_html_document_opt {
39 LXB_HTML_DOCUMENT_OPT_UNDEF = 0x00,
40 LXB_HTML_DOCUMENT_PARSE_WO_COPY = 0x01
41 };
42
43 typedef struct {
44 lxb_css_memory_t *memory;
45 lxb_css_selectors_t *css_selectors;
46 lxb_css_parser_t *parser;
47
48 lexbor_avl_t *styles;
49 lexbor_array_t *stylesheets;
50 lexbor_dobject_t *weak;
51
52 lexbor_hash_t *customs;
53 uintptr_t customs_id;
54 }
55 lxb_html_document_css_t;
56
57 struct lxb_html_document {
58 lxb_dom_document_t dom_document;
59
60 void *iframe_srcdoc;
61
62 lxb_html_head_element_t *head;
63 lxb_html_body_element_t *body;
64
65 lxb_html_document_css_t css;
66 bool css_init;
67
68 lxb_html_document_done_cb_f done;
69 lxb_html_document_ready_state_t ready_state;
70
71 lxb_html_document_opt_t opt;
72 };
73
74
75 LXB_API lxb_html_document_t *
76 lxb_html_document_interface_create(lxb_html_document_t *document);
77
78 LXB_API lxb_html_document_t *
79 lxb_html_document_interface_destroy(lxb_html_document_t *document);
80
81
82 LXB_API lxb_html_document_t *
83 lxb_html_document_create(void);
84
85 LXB_API void
86 lxb_html_document_clean(lxb_html_document_t *document);
87
88 LXB_API lxb_html_document_t *
89 lxb_html_document_destroy(lxb_html_document_t *document);
90
91 LXB_API lxb_status_t
92 lxb_html_document_css_init(lxb_html_document_t *document);
93
94 LXB_API void
95 lxb_html_document_css_destroy(lxb_html_document_t *document);
96
97 LXB_API void
98 lxb_html_document_css_clean(lxb_html_document_t *document);
99
100 LXB_API void
101 lxb_html_document_css_parser_attach(lxb_html_document_t *document,
102 lxb_css_parser_t *parser);
103
104 LXB_API void
105 lxb_html_document_css_memory_attach(lxb_html_document_t *document,
106 lxb_css_memory_t *memory);
107
108 LXB_API uintptr_t
109 lxb_html_document_css_customs_find_id(lxb_html_document_t *document,
110 const lxb_char_t *key, size_t length);
111
112 LXB_API uintptr_t
113 lxb_html_document_css_customs_id(lxb_html_document_t *document,
114 const lxb_char_t *key, size_t length);
115
116 LXB_API lxb_status_t
117 lxb_html_document_stylesheet_attach(lxb_html_document_t *document,
118 lxb_css_stylesheet_t *sst);
119
120 LXB_API lxb_status_t
121 lxb_html_document_stylesheet_apply(lxb_html_document_t *document,
122 lxb_css_stylesheet_t *sst);
123
124 LXB_API lxb_status_t
125 lxb_html_document_stylesheet_add(lxb_html_document_t *document,
126 lxb_css_stylesheet_t *sst);
127
128 LXB_API lxb_status_t
129 lxb_html_document_stylesheet_remove(lxb_html_document_t *document,
130 lxb_css_stylesheet_t *sst);
131
132 LXB_API lxb_status_t
133 lxb_html_document_element_styles_attach(lxb_html_element_t *element);
134
135 LXB_API void
136 lxb_html_document_stylesheet_destroy_all(lxb_html_document_t *document,
137 bool destroy_memory);
138
139 LXB_API lxb_status_t
140 lxb_html_document_style_attach(lxb_html_document_t *document,
141 lxb_css_rule_style_t *style);
142
143 LXB_API lxb_status_t
144 lxb_html_document_style_remove(lxb_html_document_t *document,
145 lxb_css_rule_style_t *style);
146
147 LXB_API lxb_status_t
148 lxb_html_document_style_attach_by_element(lxb_html_document_t *document,
149 lxb_html_element_t *element,
150 lxb_css_rule_style_t *style);
151
152 LXB_API lxb_status_t
153 lxb_html_document_css_customs_init(lxb_html_document_t *document);
154
155 LXB_API void
156 lxb_html_document_css_customs_destroy(lxb_html_document_t *document);
157
158 LXB_API lxb_status_t
159 lxb_html_document_parse(lxb_html_document_t *document,
160 const lxb_char_t *html, size_t size);
161
162 LXB_API lxb_status_t
163 lxb_html_document_parse_chunk_begin(lxb_html_document_t *document);
164
165 LXB_API lxb_status_t
166 lxb_html_document_parse_chunk(lxb_html_document_t *document,
167 const lxb_char_t *html, size_t size);
168
169 LXB_API lxb_status_t
170 lxb_html_document_parse_chunk_end(lxb_html_document_t *document);
171
172 LXB_API lxb_dom_node_t *
173 lxb_html_document_parse_fragment(lxb_html_document_t *document,
174 lxb_dom_element_t *element,
175 const lxb_char_t *html, size_t size);
176
177 LXB_API lxb_status_t
178 lxb_html_document_parse_fragment_chunk_begin(lxb_html_document_t *document,
179 lxb_dom_element_t *element);
180
181 LXB_API lxb_status_t
182 lxb_html_document_parse_fragment_chunk(lxb_html_document_t *document,
183 const lxb_char_t *html, size_t size);
184
185 LXB_API lxb_dom_node_t *
186 lxb_html_document_parse_fragment_chunk_end(lxb_html_document_t *document);
187
188 LXB_API const lxb_char_t *
189 lxb_html_document_title(lxb_html_document_t *document, size_t *len);
190
191 LXB_API lxb_status_t
192 lxb_html_document_title_set(lxb_html_document_t *document,
193 const lxb_char_t *title, size_t len);
194
195 LXB_API const lxb_char_t *
196 lxb_html_document_title_raw(lxb_html_document_t *document, size_t *len);
197
198 LXB_API lxb_dom_node_t *
199 lxb_html_document_import_node(lxb_html_document_t *doc, lxb_dom_node_t *node,
200 bool deep);
201
202 /*
203 * Inline functions
204 */
205 lxb_inline lxb_html_head_element_t *
lxb_html_document_head_element(lxb_html_document_t * document)206 lxb_html_document_head_element(lxb_html_document_t *document)
207 {
208 return document->head;
209 }
210
211 lxb_inline lxb_html_body_element_t *
lxb_html_document_body_element(lxb_html_document_t * document)212 lxb_html_document_body_element(lxb_html_document_t *document)
213 {
214 return document->body;
215 }
216
217 lxb_inline lxb_dom_document_t *
lxb_html_document_original_ref(lxb_html_document_t * document)218 lxb_html_document_original_ref(lxb_html_document_t *document)
219 {
220 if (lxb_dom_interface_node(document)->owner_document
221 != &document->dom_document)
222 {
223 return lxb_dom_interface_node(document)->owner_document;
224 }
225
226 return lxb_dom_interface_document(document);
227 }
228
229 lxb_inline bool
lxb_html_document_is_original(lxb_html_document_t * document)230 lxb_html_document_is_original(lxb_html_document_t *document)
231 {
232 return lxb_dom_interface_node(document)->owner_document
233 == &document->dom_document;
234 }
235
236 lxb_inline lexbor_mraw_t *
lxb_html_document_mraw(lxb_html_document_t * document)237 lxb_html_document_mraw(lxb_html_document_t *document)
238 {
239 return (lexbor_mraw_t *) lxb_dom_interface_document(document)->mraw;
240 }
241
242 lxb_inline lexbor_mraw_t *
lxb_html_document_mraw_text(lxb_html_document_t * document)243 lxb_html_document_mraw_text(lxb_html_document_t *document)
244 {
245 return (lexbor_mraw_t *) lxb_dom_interface_document(document)->text;
246 }
247
248 lxb_inline void
lxb_html_document_opt_set(lxb_html_document_t * document,lxb_html_document_opt_t opt)249 lxb_html_document_opt_set(lxb_html_document_t *document,
250 lxb_html_document_opt_t opt)
251 {
252 document->opt = opt;
253 }
254
255 lxb_inline lxb_html_document_opt_t
lxb_html_document_opt(lxb_html_document_t * document)256 lxb_html_document_opt(lxb_html_document_t *document)
257 {
258 return document->opt;
259 }
260
261 lxb_inline lexbor_hash_t *
lxb_html_document_tags(lxb_html_document_t * document)262 lxb_html_document_tags(lxb_html_document_t *document)
263 {
264 return document->dom_document.tags;
265 }
266
267 lxb_inline void *
lxb_html_document_create_struct(lxb_html_document_t * document,size_t struct_size)268 lxb_html_document_create_struct(lxb_html_document_t *document,
269 size_t struct_size)
270 {
271 return lexbor_mraw_calloc(lxb_dom_interface_document(document)->mraw,
272 struct_size);
273 }
274
275 lxb_inline void *
lxb_html_document_destroy_struct(lxb_html_document_t * document,void * data)276 lxb_html_document_destroy_struct(lxb_html_document_t *document, void *data)
277 {
278 return lexbor_mraw_free(lxb_dom_interface_document(document)->mraw, data);
279 }
280
281 lxb_inline lxb_html_element_t *
lxb_html_document_create_element(lxb_html_document_t * document,const lxb_char_t * local_name,size_t lname_len,void * reserved_for_opt)282 lxb_html_document_create_element(lxb_html_document_t *document,
283 const lxb_char_t *local_name, size_t lname_len,
284 void *reserved_for_opt)
285 {
286 return (lxb_html_element_t *) lxb_dom_document_create_element(&document->dom_document,
287 local_name, lname_len,
288 reserved_for_opt);
289 }
290
291 lxb_inline lxb_dom_element_t *
lxb_html_document_destroy_element(lxb_dom_element_t * element)292 lxb_html_document_destroy_element(lxb_dom_element_t *element)
293 {
294 return lxb_dom_document_destroy_element(element);
295 }
296
297 /*
298 * No inline functions for ABI.
299 */
300 LXB_API lxb_html_head_element_t *
301 lxb_html_document_head_element_noi(lxb_html_document_t *document);
302
303 LXB_API lxb_html_body_element_t *
304 lxb_html_document_body_element_noi(lxb_html_document_t *document);
305
306 LXB_API lxb_dom_document_t *
307 lxb_html_document_original_ref_noi(lxb_html_document_t *document);
308
309 LXB_API bool
310 lxb_html_document_is_original_noi(lxb_html_document_t *document);
311
312 LXB_API lexbor_mraw_t *
313 lxb_html_document_mraw_noi(lxb_html_document_t *document);
314
315 LXB_API lexbor_mraw_t *
316 lxb_html_document_mraw_text_noi(lxb_html_document_t *document);
317
318 LXB_API void
319 lxb_html_document_opt_set_noi(lxb_html_document_t *document,
320 lxb_html_document_opt_t opt);
321
322 LXB_API lxb_html_document_opt_t
323 lxb_html_document_opt_noi(lxb_html_document_t *document);
324
325 LXB_API void *
326 lxb_html_document_create_struct_noi(lxb_html_document_t *document,
327 size_t struct_size);
328
329 LXB_API void *
330 lxb_html_document_destroy_struct_noi(lxb_html_document_t *document, void *data);
331
332 LXB_API lxb_html_element_t *
333 lxb_html_document_create_element_noi(lxb_html_document_t *document,
334 const lxb_char_t *local_name,
335 size_t lname_len, void *reserved_for_opt);
336
337 LXB_API lxb_dom_element_t *
338 lxb_html_document_destroy_element_noi(lxb_dom_element_t *element);
339
340
341 #ifdef __cplusplus
342 } /* extern "C" */
343 #endif
344
345 #endif /* LEXBOR_HTML_DOCUMENT_H */
346