1 /*
2 Copyright (c) 2022 Andrea Fontana
3 Permission is hereby granted, free of charge, to any person
4 obtaining a copy of this software and associated documentation
5 files (the "Software"), to deal in the Software without
6 restriction, including without limitation the rights to use,
7 copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the
9 Software is furnished to do so, subject to the following
10 conditions:
11 The above copyright notice and this permission notice shall be
12 included in all copies or substantial portions of the Software.
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
17 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 OTHER DEALINGS IN THE SOFTWARE.
21 */
22 
23 module parserino.c.lexbor;
24 import core.stdc.stdint;
25 
26 extern (C):
27 
28 alias lxb_html_serialize_cb_f = uint function (const(lxb_char_t)* data, size_t len, void* ctx);
29 alias lxb_selectors_cb_f = uint function (lxb_dom_node_t*, void*, void*);
30 
31 version(Windows)
32 {
33     enum ToImport;
34 
35     __gshared {
36         @ToImport:
37         lxb_dom_element_t* function (lxb_dom_element_t* element) lxb_dom_element_destroy;
38         lxb_dom_element_t* function (lxb_dom_document_t* document, const(lxb_dom_element_t)* element) lxb_dom_element_interface_clone;
39         lxb_dom_element_t* function (lxb_dom_element_t* element) lxb_dom_element_interface_destroy;
40         lxb_status_t function (lxb_dom_element_t* dst, const(lxb_dom_element_t)* src) lxb_dom_element_interface_copy;
41 
42         lxb_dom_attr_t* function (lxb_dom_element_t* element, const(lxb_char_t)* qualified_name, size_t qn_len, const(lxb_char_t)* value, size_t value_len) lxb_dom_element_set_attribute;
43         const(lxb_char_t)* function (lxb_dom_element_t* element, const(lxb_char_t)* qualified_name, size_t qn_len, size_t* value_len) lxb_dom_element_get_attribute;
44         lxb_status_t function (lxb_dom_element_t* element, const(lxb_char_t)* qualified_name, size_t qn_len) lxb_dom_element_remove_attribute;
45         bool function (lxb_dom_element_t* element, const(lxb_char_t)* qualified_name, size_t qn_len) lxb_dom_element_has_attribute;
46 
47         const(lxb_char_t)* function (lxb_dom_element_t* element, size_t* len) lxb_dom_element_tag_name;
48         const(lxb_char_t)* function (lxb_dom_element_t* element, size_t* len) lxb_dom_element_local_name;
49         lxb_dom_attr_t* function (lxb_dom_element_t* element) lxb_dom_element_first_attribute_noi;
50         lxb_dom_attr_t* function (lxb_dom_attr_t* attr) lxb_dom_element_next_attribute_noi;
51 
52         void function (lxb_dom_node_t* to, lxb_dom_node_t* node) lxb_dom_node_insert_child;
53         void function (lxb_dom_node_t* to, lxb_dom_node_t* node) lxb_dom_node_insert_before;
54         void function (lxb_dom_node_t* to, lxb_dom_node_t* node) lxb_dom_node_insert_after;
55         void function (lxb_dom_node_t* node) lxb_dom_node_remove;
56 
57         lxb_char_t* function (lxb_dom_node_t* node, size_t* len) lxb_dom_node_text_content;
58         lxb_status_t function (lxb_dom_node_t* node, const(lxb_char_t)* content, size_t len) lxb_dom_node_text_content_set;
59         bool function (lxb_dom_node_t* root) lxb_dom_node_is_empty;
60 
61         lxb_dom_node_t* function (lxb_dom_node_t* node) lxb_dom_node_next_noi;
62         lxb_dom_node_t* function (lxb_dom_node_t* node) lxb_dom_node_prev_noi;
63         lxb_dom_node_t* function (lxb_dom_node_t* node) lxb_dom_node_parent_noi;
64         lxb_dom_node_t* function (lxb_dom_node_t* node) lxb_dom_node_first_child_noi;
65         lxb_dom_node_t* function (lxb_dom_node_t* node) lxb_dom_node_last_child_noi;
66 
67         const(lxb_char_t)* function (lxb_dom_attr_t* attr, size_t* len) lxb_dom_attr_local_name_noi;
68         const(lxb_char_t)* function (lxb_dom_attr_t* attr, size_t* len) lxb_dom_attr_value_noi;
69 
70         lxb_status_t function (lxb_dom_node_t* node, lxb_html_serialize_cb_f cb, void* ctx) lxb_html_serialize_cb;
71         lxb_status_t function (lxb_dom_node_t* node, lexbor_str_t* str) lxb_html_serialize_str;
72         lxb_status_t function (lxb_dom_node_t* node, lxb_html_serialize_cb_f cb, void* ctx) lxb_html_serialize_tree_cb;
73         lxb_status_t function (lxb_dom_node_t* node, lexbor_str_t* str) lxb_html_serialize_tree_str;
74         lxb_status_t function (lxb_dom_node_t* node, lxb_html_serialize_cb_f cb, void* ctx) lxb_html_serialize_deep_cb;
75         lxb_status_t function (lxb_dom_node_t* node, lexbor_str_t* str) lxb_html_serialize_deep_str;
76         lxb_status_t function (lxb_dom_node_t* node, lxb_html_serialize_opt_t opt, size_t indent, lxb_html_serialize_cb_f cb, void* ctx) lxb_html_serialize_pretty_cb;
77         lxb_status_t function (lxb_dom_node_t* node, lxb_html_serialize_opt_t opt, size_t indent, lexbor_str_t* str) lxb_html_serialize_pretty_str;
78         lxb_status_t function (lxb_dom_node_t* node, lxb_html_serialize_opt_t opt, size_t indent, lxb_html_serialize_cb_f cb, void* ctx) lxb_html_serialize_pretty_tree_cb;
79         lxb_status_t function (lxb_dom_node_t* node, lxb_html_serialize_opt_t opt, size_t indent, lexbor_str_t* str) lxb_html_serialize_pretty_tree_str;
80         lxb_status_t function (lxb_dom_node_t* node, lxb_html_serialize_opt_t opt, size_t indent, lxb_html_serialize_cb_f cb, void* ctx) lxb_html_serialize_pretty_deep_cb;
81         lxb_status_t function (lxb_dom_node_t* node, lxb_html_serialize_opt_t opt, size_t indent, lexbor_str_t* str) lxb_html_serialize_pretty_deep_str;
82 
83         lxb_html_element_t* function (lxb_html_element_t* element, const(lxb_char_t)* html, size_t size) lxb_html_element_inner_html_set;
84 
85         lxb_selectors_t* function () lxb_selectors_create;
86         lxb_status_t function (lxb_selectors_t* selectors) lxb_selectors_init;
87         lxb_selectors_t* function (lxb_selectors_t* selectors, bool self_destroy) lxb_selectors_destroy;
88 
89         lxb_status_t function (lxb_selectors_t* selectors, lxb_dom_node_t* root, lxb_css_selector_list_t* list, lxb_selectors_cb_f cb, void* ctx) lxb_selectors_find;
90 
91         lxb_css_parser_t* function() lxb_css_parser_create;
92         lxb_status_t function (lxb_css_parser_t *, lxb_css_syntax_tokenizer_t *, lexbor_mraw_t *) lxb_css_parser_init;
93         lxb_css_parser_t* function(lxb_css_parser_t *, bool) lxb_css_parser_destroy;
94 
95         lxb_html_document_t* function () lxb_html_document_create;
96         void function (lxb_html_document_t* document) lxb_html_document_clean;
97         lxb_html_document_t* function (lxb_html_document_t* document) lxb_html_document_destroy;
98         lxb_status_t function (lxb_html_document_t*, const(lxb_char_t)*, size_t) lxb_html_document_parse;
99         lxb_dom_node_t* function (lxb_html_document_t*, lxb_dom_element_t*, const(lxb_char_t)*, size_t) lxb_html_document_parse_fragment;
100         const(lxb_char_t)* function (lxb_html_document_t*, size_t*) lxb_html_document_title;
101         lxb_status_t function (lxb_html_document_t*, const(lxb_char_t)*, size_t) lxb_html_document_title_set;
102         const(lxb_char_t)* function (lxb_html_document_t*, size_t*) lxb_html_document_title_raw;
103         lxb_html_head_element_t* function (lxb_html_document_t*) lxb_html_document_head_element_noi;
104         lxb_html_body_element_t* function (lxb_html_document_t*) lxb_html_document_body_element_noi;
105 
106         lxb_dom_element_t* function (lxb_dom_document_t*, const(lxb_char_t)*, size_t, void*) lxb_dom_document_create_element;
107         void function(lxb_css_selector_list_t *) lxb_css_selector_list_destroy_memory;
108         lxb_css_selector_list_t * function(lxb_css_parser_t *, const lxb_char_t *, size_t) lxb_css_selectors_parse;
109     }
110 
111     extern(D) shared static this()
112     {
113         import core.sys.windows.windows;
114         import std.traits;
115         import std.stdio;
116         import std.file : thisExePath, getcwd;
117         import std.path : buildPath,dirName;
118         import std.string : toStringz;
119 
120         HINSTANCE handle = LoadLibraryA(buildPath(thisExePath.dirName, "lexbor.dll").toStringz);
121 
122         if (handle == null)
123             handle = LoadLibraryA(buildPath(getcwd(), "lexbor.dll").toStringz);
124 
125         if (handle == null)
126             throw new Exception("Can't find lexbor.dll.");
127 
128         static foreach(s; getSymbolsByUDA!(parserino.c.lexbor, ToImport))
129             static if (isFunctionPointer!s)
130                 mixin(`*(cast(void**)&` ~ s.stringof ~ `) = cast(void*)GetProcAddress(handle, "` ~ s.stringof ~ `");`);
131     }
132 }
133 else
134 {
135     lxb_dom_element_t* lxb_dom_element_destroy (lxb_dom_element_t* element);
136     lxb_dom_element_t* lxb_dom_element_interface_clone (lxb_dom_document_t* document, const(lxb_dom_element_t)* element);
137     lxb_dom_element_t* lxb_dom_element_interface_destroy (lxb_dom_element_t* element);
138     lxb_status_t lxb_dom_element_interface_copy (lxb_dom_element_t* dst, const(lxb_dom_element_t)* src);
139 
140     lxb_dom_attr_t* lxb_dom_element_set_attribute (lxb_dom_element_t* element, const(lxb_char_t)* qualified_name, size_t qn_len, const(lxb_char_t)* value, size_t value_len);
141     const(lxb_char_t)* lxb_dom_element_get_attribute (lxb_dom_element_t* element, const(lxb_char_t)* qualified_name, size_t qn_len, size_t* value_len);
142     lxb_status_t lxb_dom_element_remove_attribute (lxb_dom_element_t* element, const(lxb_char_t)* qualified_name, size_t qn_len);
143     bool lxb_dom_element_has_attribute (lxb_dom_element_t* element, const(lxb_char_t)* qualified_name, size_t qn_len);
144 
145     const(lxb_char_t)* lxb_dom_element_tag_name (lxb_dom_element_t* element, size_t* len);
146     const(lxb_char_t)* lxb_dom_element_local_name (lxb_dom_element_t* element, size_t* len);
147     lxb_dom_attr_t* lxb_dom_element_first_attribute_noi (lxb_dom_element_t* element);
148     lxb_dom_attr_t* lxb_dom_element_next_attribute_noi (lxb_dom_attr_t* attr);
149 
150     void lxb_dom_node_insert_child (lxb_dom_node_t* to, lxb_dom_node_t* node);
151     void lxb_dom_node_insert_before (lxb_dom_node_t* to, lxb_dom_node_t* node);
152     void lxb_dom_node_insert_after (lxb_dom_node_t* to, lxb_dom_node_t* node);
153     void lxb_dom_node_remove (lxb_dom_node_t* node);
154 
155     lxb_char_t* lxb_dom_node_text_content (lxb_dom_node_t* node, size_t* len);
156     lxb_status_t lxb_dom_node_text_content_set (lxb_dom_node_t* node, const(lxb_char_t)* content, size_t len);
157     bool lxb_dom_node_is_empty (lxb_dom_node_t* root);
158 
159     lxb_dom_node_t* lxb_dom_node_next_noi (lxb_dom_node_t* node);
160     lxb_dom_node_t* lxb_dom_node_prev_noi (lxb_dom_node_t* node);
161     lxb_dom_node_t* lxb_dom_node_parent_noi (lxb_dom_node_t* node);
162     lxb_dom_node_t* lxb_dom_node_first_child_noi (lxb_dom_node_t* node);
163     lxb_dom_node_t* lxb_dom_node_last_child_noi (lxb_dom_node_t* node);
164 
165     const(lxb_char_t)* lxb_dom_attr_local_name_noi (lxb_dom_attr_t* attr, size_t* len);
166     const(lxb_char_t)* lxb_dom_attr_value_noi (lxb_dom_attr_t* attr, size_t* len);
167 
168     lxb_status_t lxb_html_serialize_cb (lxb_dom_node_t* node, lxb_html_serialize_cb_f cb, void* ctx);
169     lxb_status_t lxb_html_serialize_str (lxb_dom_node_t* node, lexbor_str_t* str);
170     lxb_status_t lxb_html_serialize_tree_cb (lxb_dom_node_t* node, lxb_html_serialize_cb_f cb, void* ctx);
171     lxb_status_t lxb_html_serialize_tree_str (lxb_dom_node_t* node, lexbor_str_t* str);
172     lxb_status_t lxb_html_serialize_deep_cb (lxb_dom_node_t* node, lxb_html_serialize_cb_f cb, void* ctx);
173     lxb_status_t lxb_html_serialize_deep_str (lxb_dom_node_t* node, lexbor_str_t* str);
174     lxb_status_t lxb_html_serialize_pretty_cb (lxb_dom_node_t* node, lxb_html_serialize_opt_t opt, size_t indent, lxb_html_serialize_cb_f cb, void* ctx);
175     lxb_status_t lxb_html_serialize_pretty_str (lxb_dom_node_t* node, lxb_html_serialize_opt_t opt, size_t indent, lexbor_str_t* str);
176     lxb_status_t lxb_html_serialize_pretty_tree_cb (lxb_dom_node_t* node, lxb_html_serialize_opt_t opt, size_t indent, lxb_html_serialize_cb_f cb, void* ctx);
177     lxb_status_t lxb_html_serialize_pretty_tree_str (lxb_dom_node_t* node, lxb_html_serialize_opt_t opt, size_t indent, lexbor_str_t* str);
178     lxb_status_t lxb_html_serialize_pretty_deep_cb (lxb_dom_node_t* node, lxb_html_serialize_opt_t opt, size_t indent, lxb_html_serialize_cb_f cb, void* ctx);
179     lxb_status_t lxb_html_serialize_pretty_deep_str (lxb_dom_node_t* node, lxb_html_serialize_opt_t opt, size_t indent, lexbor_str_t* str);
180 
181     lxb_html_element_t* lxb_html_element_inner_html_set (lxb_html_element_t* element, const(lxb_char_t)* html, size_t size);
182 
183     lxb_selectors_t* lxb_selectors_create ();
184     lxb_status_t lxb_selectors_init (lxb_selectors_t* selectors);
185     lxb_selectors_t* lxb_selectors_destroy (lxb_selectors_t* selectors, bool self_destroy);
186 
187     lxb_status_t lxb_selectors_find (lxb_selectors_t* selectors, lxb_dom_node_t* root, lxb_css_selector_list_t* list, lxb_selectors_cb_f cb, void* ctx);
188 
189     lxb_css_parser_t* lxb_css_parser_create();
190     lxb_status_t lxb_css_parser_init(lxb_css_parser_t *, lxb_css_syntax_tokenizer_t *, lexbor_mraw_t *);
191     lxb_css_parser_t *lxb_css_parser_destroy(lxb_css_parser_t *, bool);
192 
193     lxb_html_document_t* lxb_html_document_create ();
194     void lxb_html_document_clean (lxb_html_document_t* document);
195     lxb_html_document_t* lxb_html_document_destroy (lxb_html_document_t* document);
196     lxb_status_t lxb_html_document_parse (lxb_html_document_t*, const(lxb_char_t)*, size_t);
197     lxb_dom_node_t* lxb_html_document_parse_fragment (lxb_html_document_t*, lxb_dom_element_t*, const(lxb_char_t)*, size_t);
198     const(lxb_char_t)* lxb_html_document_title (lxb_html_document_t*, size_t*);
199     lxb_status_t lxb_html_document_title_set (lxb_html_document_t*, const(lxb_char_t)*, size_t);
200     const(lxb_char_t)* lxb_html_document_title_raw (lxb_html_document_t*, size_t*);
201     lxb_html_head_element_t* lxb_html_document_head_element_noi (lxb_html_document_t*);
202     lxb_html_body_element_t* lxb_html_document_body_element_noi (lxb_html_document_t*);
203 
204     lxb_dom_element_t* lxb_dom_document_create_element (lxb_dom_document_t*, const(lxb_char_t)*, size_t, void*);
205     void lxb_css_selector_list_destroy_memory(lxb_css_selector_list_t *);
206     lxb_css_selector_list_t * lxb_css_selectors_parse(lxb_css_parser_t *, const lxb_char_t *, size_t);
207 }
208 
209 // STRUCTS
210 alias lxb_dom_attr_id_t = uintptr_t;
211 alias lxb_char_t = ubyte;
212 alias lxb_status_t = uint;
213 alias lxb_html_document_opt_t = uint;
214 alias lxb_html_serialize_opt_t = int;
215 
216 struct lxb_selectors_t;
217 struct lxb_css_selector_list_t;
218 struct lxb_css_parser_t;
219 struct lxb_css_syntax_tokenizer_t;
220 struct lexbor_mraw_t;
221 
222 alias lxb_html_body_element_t = lxb_html_body_element;
223 struct lxb_html_body_element;
224 
225 alias lxb_html_head_element_t = lxb_html_head_element;
226 struct lxb_html_head_element;
227 
228 alias lxb_dom_event_target_t = lxb_dom_event_target;
229 struct lxb_dom_event_target
230 {
231     void* events;
232 }
233 
234 alias lxb_html_element_t = lxb_html_element;
235 struct lxb_html_element
236 {
237     lxb_dom_element_t element;
238 }
239 
240 alias lexbor_str_t = lexbor_str;
241 struct lexbor_str
242 {
243     lxb_char_t *data;
244     size_t     length;
245 }
246 
247 alias lxb_dom_element_t = lxb_dom_element;
248 struct lxb_dom_element
249 {
250     lxb_dom_node_t node;
251     lxb_dom_attr_id_t upper_name;
252     lxb_dom_attr_id_t qualified_name;
253     lexbor_str_t* _value;
254     lxb_dom_attr_t* first_attr;
255     lxb_dom_attr_t* last_attr;
256     lxb_dom_attr_t* attr_id;
257     lxb_dom_attr_t* attr_class;
258 }
259 
260 alias lxb_dom_document_type_t = lxb_dom_document_type;
261 struct lxb_dom_document_type {
262     lxb_dom_node_t    node;
263 
264     lxb_dom_attr_id_t name;
265     lexbor_str_t      public_id;
266     lexbor_str_t      system_id;
267 }
268 
269 alias lexbor_hash_t = lexbor_hash;
270 struct lexbor_hash {
271     void    *entries;
272     void    *mraw;
273 
274     void    **table;
275     size_t  table_size;
276 
277     size_t  struct_size;
278 }
279 
280 alias lxb_dom_document_t = lxb_dom_document;
281 struct lxb_dom_document {
282     lxb_dom_node_t              node;
283 
284     lxb_dom_document_cmode_t    compat_mode;
285     lxb_dom_document_dtype_t    type;
286 
287     lxb_dom_document_type_t     *doctype;
288     lxb_dom_element_t           *element;
289 
290     void*  create_interface;
291     void*  clone_interface;
292     void*  destroy_interface;
293 
294     lexbor_mraw_t               *mraw;
295     lexbor_mraw_t               *text;
296     lexbor_hash_t               *tags;
297     lexbor_hash_t               *attrs;
298     lexbor_hash_t               *prefix;
299     lexbor_hash_t               *ns;
300     void                        *parser;
301     void                        *user;
302 
303     bool                        tags_inherited;
304     bool                        ns_inherited;
305 
306     bool                        scripting;
307 }
308 
309 alias lxb_html_document_t = lxb_html_document;
310 struct lxb_html_document {
311     lxb_dom_document_t              dom_document;
312     void                            *iframe_srcdoc;
313     lxb_html_head_element_t         *head;
314     lxb_html_body_element_t         *body;
315     lxb_html_document_ready_state_t ready_state;
316     lxb_html_document_opt_t         opt;
317 }
318 
319 alias lxb_dom_node_t = lxb_dom_node;
320 struct lxb_dom_node
321 {
322     lxb_dom_event_target_t event_target;
323     uintptr_t local_name;
324     uintptr_t prefix;
325     uintptr_t ns;
326     lxb_dom_document_t* owner_document;
327     lxb_dom_node_t* next;
328     lxb_dom_node_t* prev;
329     lxb_dom_node_t* parent;
330     lxb_dom_node_t* first_child;
331     lxb_dom_node_t* last_child;
332     void* user;
333     lxb_dom_node_type_t type;
334 }
335 
336 alias lxb_dom_attr_t = lxb_dom_attr;
337 struct lxb_dom_attr
338 {
339     lxb_dom_node_t node;
340     lxb_dom_attr_id_t upper_name; /* uppercase, with prefix: FIX:ME */
341     lxb_dom_attr_id_t qualified_name; /* original, with prefix: Fix:Me */
342     lexbor_str_t* value;
343     lxb_dom_element_t* owner;
344     lxb_dom_attr_t* next;
345     lxb_dom_attr_t* prev;
346 }
347 
348 // ENUMS
349 
350 enum lxb_html_document_ready_state_t {
351     LXB_HTML_DOCUMENT_READY_STATE_UNDEF       = 0x00,
352     LXB_HTML_DOCUMENT_READY_STATE_LOADING     = 0x01,
353     LXB_HTML_DOCUMENT_READY_STATE_INTERACTIVE = 0x02,
354     LXB_HTML_DOCUMENT_READY_STATE_COMPLETE    = 0x03,
355 }
356 
357 enum lexbor_status_t {
358     LXB_STATUS_OK                       = 0x0000,
359     LXB_STATUS_ERROR                    = 0x0001,
360     LXB_STATUS_ERROR_MEMORY_ALLOCATION,
361     LXB_STATUS_ERROR_OBJECT_IS_NULL,
362     LXB_STATUS_ERROR_SMALL_BUFFER,
363     LXB_STATUS_ERROR_INCOMPLETE_OBJECT,
364     LXB_STATUS_ERROR_NO_FREE_SLOT,
365     LXB_STATUS_ERROR_TOO_SMALL_SIZE,
366     LXB_STATUS_ERROR_NOT_EXISTS,
367     LXB_STATUS_ERROR_WRONG_ARGS,
368     LXB_STATUS_ERROR_WRONG_STAGE,
369     LXB_STATUS_ERROR_UNEXPECTED_RESULT,
370     LXB_STATUS_ERROR_UNEXPECTED_DATA,
371     LXB_STATUS_ERROR_OVERFLOW,
372     LXB_STATUS_CONTINUE,
373     LXB_STATUS_SMALL_BUFFER,
374     LXB_STATUS_ABORTED,
375     LXB_STATUS_STOPPED,
376     LXB_STATUS_NEXT,
377     LXB_STATUS_STOP,
378 }
379 
380 enum lxb_html_serialize_opt
381 {
382     LXB_HTML_SERIALIZE_OPT_UNDEF = 0x00,
383     LXB_HTML_SERIALIZE_OPT_SKIP_WS_NODES = 0x01,
384     LXB_HTML_SERIALIZE_OPT_SKIP_COMMENT = 0x02,
385     LXB_HTML_SERIALIZE_OPT_RAW = 0x04,
386     LXB_HTML_SERIALIZE_OPT_WITHOUT_CLOSING = 0x08,
387     LXB_HTML_SERIALIZE_OPT_TAG_WITH_NS = 0x10,
388     LXB_HTML_SERIALIZE_OPT_WITHOUT_TEXT_INDENT = 0x20,
389     LXB_HTML_SERIALIZE_OPT_FULL_DOCTYPE = 0x40
390 }
391 
392 
393 enum lxb_dom_node_type_t
394 {
395     LXB_DOM_NODE_TYPE_UNDEF = 0x00,
396     LXB_DOM_NODE_TYPE_ELEMENT = 0x01,
397     LXB_DOM_NODE_TYPE_ATTRIBUTE = 0x02,
398     LXB_DOM_NODE_TYPE_TEXT = 0x03,
399     LXB_DOM_NODE_TYPE_CDATA_SECTION = 0x04,
400     LXB_DOM_NODE_TYPE_ENTITY_REFERENCE = 0x05, // historical
401     LXB_DOM_NODE_TYPE_ENTITY = 0x06, // historical
402     LXB_DOM_NODE_TYPE_PROCESSING_INSTRUCTION = 0x07,
403     LXB_DOM_NODE_TYPE_COMMENT = 0x08,
404     LXB_DOM_NODE_TYPE_DOCUMENT = 0x09,
405     LXB_DOM_NODE_TYPE_DOCUMENT_TYPE = 0x0A,
406     LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT = 0x0B,
407     LXB_DOM_NODE_TYPE_NOTATION = 0x0C, // historical
408     LXB_DOM_NODE_TYPE_LAST_ENTRY = 0x0D
409 }
410 
411 enum lxb_dom_document_cmode_t
412 {
413     LXB_DOM_DOCUMENT_CMODE_NO_QUIRKS       = 0x00,
414     LXB_DOM_DOCUMENT_CMODE_QUIRKS          = 0x01,
415     LXB_DOM_DOCUMENT_CMODE_LIMITED_QUIRKS  = 0x02
416 }
417 
418 enum lxb_dom_document_dtype_t
419 {
420     LXB_DOM_DOCUMENT_DTYPE_UNDEF = 0x00,
421     LXB_DOM_DOCUMENT_DTYPE_HTML  = 0x01,
422     LXB_DOM_DOCUMENT_DTYPE_XML   = 0x02
423 }