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