1 /*
2 * Copyright (C) 2018-2021 Alexander Borisov
3 *
4 * Author: Alexander Borisov <borisov@lexbor.com>
5 */
6
7 #ifndef LEXBOR_DOM_DOCUMENT_H
8 #define LEXBOR_DOM_DOCUMENT_H
9
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13
14 #include "lexbor/core/mraw.h"
15 #include "lexbor/core/hash.h"
16
17 #include "lexbor/dom/interface.h"
18 #include "lexbor/dom/interfaces/node.h"
19
20
21 typedef enum {
22 LXB_DOM_DOCUMENT_CMODE_NO_QUIRKS = 0x00,
23 LXB_DOM_DOCUMENT_CMODE_QUIRKS = 0x01,
24 LXB_DOM_DOCUMENT_CMODE_LIMITED_QUIRKS = 0x02
25 }
26 lxb_dom_document_cmode_t;
27
28 typedef enum {
29 LXB_DOM_DOCUMENT_DTYPE_UNDEF = 0x00,
30 LXB_DOM_DOCUMENT_DTYPE_HTML = 0x01,
31 LXB_DOM_DOCUMENT_DTYPE_XML = 0x02
32 }
33 lxb_dom_document_dtype_t;
34
35 struct lxb_dom_document {
36 lxb_dom_node_t node;
37
38 lxb_dom_document_cmode_t compat_mode;
39 lxb_dom_document_dtype_t type;
40
41 lxb_dom_document_type_t *doctype;
42 lxb_dom_element_t *element;
43
44 lxb_dom_interface_create_f create_interface;
45 lxb_dom_interface_clone_f clone_interface;
46 lxb_dom_interface_destroy_f destroy_interface;
47
48 lxb_dom_event_insert_f ev_insert;
49 lxb_dom_event_remove_f ev_remove;
50 lxb_dom_event_destroy_f ev_destroy;
51 lxb_dom_event_set_value_f ev_set_value;
52
53 lexbor_mraw_t *mraw;
54 lexbor_mraw_t *text;
55 lexbor_hash_t *tags;
56 lexbor_hash_t *attrs;
57 lexbor_hash_t *prefix;
58 lexbor_hash_t *ns;
59 void *parser;
60 void *user;
61
62 bool tags_inherited;
63 bool ns_inherited;
64
65 bool scripting;
66 };
67
68
69 LXB_API lxb_dom_document_t *
70 lxb_dom_document_interface_create(lxb_dom_document_t *document);
71
72 LXB_API lxb_dom_document_t *
73 lxb_dom_document_interface_clone(lxb_dom_document_t *document,
74 const lxb_dom_document_t *doc);
75
76 LXB_API lxb_dom_document_t *
77 lxb_dom_document_interface_destroy(lxb_dom_document_t *document);
78
79 LXB_API lxb_dom_document_t *
80 lxb_dom_document_create(lxb_dom_document_t *owner);
81
82 LXB_API lxb_status_t
83 lxb_dom_document_init(lxb_dom_document_t *document, lxb_dom_document_t *owner,
84 lxb_dom_interface_create_f create_interface,
85 lxb_dom_interface_clone_f clone_interface,
86 lxb_dom_interface_destroy_f destroy_interface,
87 lxb_dom_document_dtype_t type, unsigned int ns);
88
89 LXB_API lxb_status_t
90 lxb_dom_document_clean(lxb_dom_document_t *document);
91
92 LXB_API lxb_dom_document_t *
93 lxb_dom_document_destroy(lxb_dom_document_t *document);
94
95 LXB_API void
96 lxb_dom_document_attach_doctype(lxb_dom_document_t *document,
97 lxb_dom_document_type_t *doctype);
98
99 LXB_API void
100 lxb_dom_document_attach_element(lxb_dom_document_t *document,
101 lxb_dom_element_t *element);
102
103 LXB_API lxb_dom_element_t *
104 lxb_dom_document_create_element(lxb_dom_document_t *document,
105 const lxb_char_t *local_name, size_t lname_len,
106 void *reserved_for_opt);
107
108 LXB_API lxb_dom_element_t *
109 lxb_dom_document_destroy_element(lxb_dom_element_t *element);
110
111 LXB_API lxb_dom_document_fragment_t *
112 lxb_dom_document_create_document_fragment(lxb_dom_document_t *document);
113
114 LXB_API lxb_dom_text_t *
115 lxb_dom_document_create_text_node(lxb_dom_document_t *document,
116 const lxb_char_t *data, size_t len);
117
118 LXB_API lxb_dom_cdata_section_t *
119 lxb_dom_document_create_cdata_section(lxb_dom_document_t *document,
120 const lxb_char_t *data, size_t len);
121
122 LXB_API lxb_dom_processing_instruction_t *
123 lxb_dom_document_create_processing_instruction(lxb_dom_document_t *document,
124 const lxb_char_t *target, size_t target_len,
125 const lxb_char_t *data, size_t data_len);
126
127 LXB_API lxb_dom_comment_t *
128 lxb_dom_document_create_comment(lxb_dom_document_t *document,
129 const lxb_char_t *data, size_t len);
130
131 LXB_API lxb_dom_node_t *
132 lxb_dom_document_root(lxb_dom_document_t *document);
133
134 LXB_API lxb_dom_node_t *
135 lxb_dom_document_import_node(lxb_dom_document_t *doc, lxb_dom_node_t *node,
136 bool deep);
137
138 /*
139 * Inline functions
140 */
141 lxb_inline lxb_dom_interface_t *
lxb_dom_document_create_interface(lxb_dom_document_t * document,lxb_tag_id_t tag_id,lxb_ns_id_t ns)142 lxb_dom_document_create_interface(lxb_dom_document_t *document,
143 lxb_tag_id_t tag_id, lxb_ns_id_t ns)
144 {
145 return document->create_interface(document, tag_id, ns);
146 }
147
148 lxb_inline lxb_dom_interface_t *
lxb_dom_document_destroy_interface(lxb_dom_interface_t * intrfc)149 lxb_dom_document_destroy_interface(lxb_dom_interface_t *intrfc)
150 {
151 return lxb_dom_interface_node(intrfc)->owner_document->destroy_interface(intrfc);
152 }
153
154 lxb_inline void *
lxb_dom_document_create_struct(lxb_dom_document_t * document,size_t struct_size)155 lxb_dom_document_create_struct(lxb_dom_document_t *document, size_t struct_size)
156 {
157 return lexbor_mraw_calloc(document->mraw, struct_size);
158 }
159
160 lxb_inline void *
lxb_dom_document_destroy_struct(lxb_dom_document_t * document,void * structure)161 lxb_dom_document_destroy_struct(lxb_dom_document_t *document, void *structure)
162 {
163 return lexbor_mraw_free(document->mraw, structure);
164 }
165
166 lxb_inline lxb_char_t *
lxb_dom_document_create_text(lxb_dom_document_t * document,size_t len)167 lxb_dom_document_create_text(lxb_dom_document_t *document, size_t len)
168 {
169 return (lxb_char_t *) lexbor_mraw_alloc(document->text,
170 sizeof(lxb_char_t) * len);
171 }
172
173 lxb_inline void *
lxb_dom_document_destroy_text(lxb_dom_document_t * document,lxb_char_t * text)174 lxb_dom_document_destroy_text(lxb_dom_document_t *document, lxb_char_t *text)
175 {
176 return lexbor_mraw_free(document->text, text);
177 }
178
179 lxb_inline lxb_dom_element_t *
lxb_dom_document_element(lxb_dom_document_t * document)180 lxb_dom_document_element(lxb_dom_document_t *document)
181 {
182 return document->element;
183 }
184
185 lxb_inline bool
lxb_dom_document_scripting(lxb_dom_document_t * document)186 lxb_dom_document_scripting(lxb_dom_document_t *document)
187 {
188 return document->scripting;
189 }
190
191 lxb_inline void
lxb_dom_document_scripting_set(lxb_dom_document_t * document,bool scripting)192 lxb_dom_document_scripting_set(lxb_dom_document_t *document, bool scripting)
193 {
194 document->scripting = scripting;
195 }
196
197 lxb_inline lxb_dom_document_t *
lxb_dom_document_owner(lxb_dom_document_t * document)198 lxb_dom_document_owner(lxb_dom_document_t *document)
199 {
200 return lxb_dom_interface_node(document)->owner_document;
201 }
202
203 lxb_inline bool
lxb_dom_document_is_original(lxb_dom_document_t * document)204 lxb_dom_document_is_original(lxb_dom_document_t *document)
205 {
206 return lxb_dom_interface_node(document)->owner_document == document;
207 }
208
209 /*
210 * No inline functions for ABI.
211 */
212 LXB_API lxb_dom_interface_t *
213 lxb_dom_document_create_interface_noi(lxb_dom_document_t *document,
214 lxb_tag_id_t tag_id, lxb_ns_id_t ns);
215
216 LXB_API lxb_dom_interface_t *
217 lxb_dom_document_destroy_interface_noi(lxb_dom_interface_t *intrfc);
218
219 LXB_API void *
220 lxb_dom_document_create_struct_noi(lxb_dom_document_t *document,
221 size_t struct_size);
222
223 LXB_API void *
224 lxb_dom_document_destroy_struct_noi(lxb_dom_document_t *document,
225 void *structure);
226
227 LXB_API lxb_char_t *
228 lxb_dom_document_create_text_noi(lxb_dom_document_t *document, size_t len);
229
230 LXB_API void *
231 lxb_dom_document_destroy_text_noi(lxb_dom_document_t *document,
232 lxb_char_t *text);
233
234 LXB_API lxb_dom_element_t *
235 lxb_dom_document_element_noi(lxb_dom_document_t *document);
236
237 LXB_API bool
238 lxb_dom_document_scripting_noi(lxb_dom_document_t *document);
239
240 LXB_API void
241 lxb_dom_document_scripting_set_noi(lxb_dom_document_t *document,
242 bool scripting);
243
244 #ifdef __cplusplus
245 } /* extern "C" */
246 #endif
247
248 #endif /* LEXBOR_DOM_DOCUMENT_H */
249