xref: /php-src/ext/dom/lexbor/lexbor/dom/interfaces/node.h (revision bffab33a)
1 /*
2  * Copyright (C) 2018-2021 Alexander Borisov
3  *
4  * Author: Alexander Borisov <borisov@lexbor.com>
5  */
6 
7 #ifndef LEXBOR_DOM_NODE_H
8 #define LEXBOR_DOM_NODE_H
9 
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13 
14 #include "lexbor/dom/interface.h"
15 #include "lexbor/dom/collection.h"
16 #include "lexbor/dom/interfaces/event_target.h"
17 
18 
19 typedef lexbor_action_t
20 (*lxb_dom_node_simple_walker_f)(lxb_dom_node_t *node, void *ctx);
21 
22 
23 typedef enum {
24     LXB_DOM_NODE_TYPE_UNDEF                  = 0x00,
25     LXB_DOM_NODE_TYPE_ELEMENT                = 0x01,
26     LXB_DOM_NODE_TYPE_ATTRIBUTE              = 0x02,
27     LXB_DOM_NODE_TYPE_TEXT                   = 0x03,
28     LXB_DOM_NODE_TYPE_CDATA_SECTION          = 0x04,
29     LXB_DOM_NODE_TYPE_ENTITY_REFERENCE       = 0x05, // historical
30     LXB_DOM_NODE_TYPE_ENTITY                 = 0x06, // historical
31     LXB_DOM_NODE_TYPE_PROCESSING_INSTRUCTION = 0x07,
32     LXB_DOM_NODE_TYPE_COMMENT                = 0x08,
33     LXB_DOM_NODE_TYPE_DOCUMENT               = 0x09,
34     LXB_DOM_NODE_TYPE_DOCUMENT_TYPE          = 0x0A,
35     LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT      = 0x0B,
36     LXB_DOM_NODE_TYPE_NOTATION               = 0x0C, // historical
37     LXB_DOM_NODE_TYPE_LAST_ENTRY             = 0x0D
38 }
39 lxb_dom_node_type_t;
40 
41 struct lxb_dom_node {
42     lxb_dom_event_target_t event_target;
43 
44     /* For example: <LalAla:DiV Fix:Me="value"> */
45 
46     uintptr_t              local_name; /* , lowercase, without prefix: div */
47     uintptr_t              prefix;     /* lowercase: lalala */
48     uintptr_t              ns;         /* namespace */
49 
50     lxb_dom_document_t     *owner_document;
51 
52     lxb_dom_node_t         *next;
53     lxb_dom_node_t         *prev;
54     lxb_dom_node_t         *parent;
55     lxb_dom_node_t         *first_child;
56     lxb_dom_node_t         *last_child;
57     void                   *user;
58 
59     lxb_dom_node_type_t    type;
60 
61     size_t                 line;
62 
63 #ifdef LXB_DOM_NODE_USER_VARIABLES
64     LXB_DOM_NODE_USER_VARIABLES
65 #endif /* LXB_DOM_NODE_USER_VARIABLES */
66 };
67 
68 
69 LXB_API lxb_dom_node_t *
70 lxb_dom_node_interface_create(lxb_dom_document_t *document);
71 
72 LXB_API lxb_dom_node_t *
73 lxb_dom_node_interface_clone(lxb_dom_document_t *document,
74                              const lxb_dom_node_t *node, bool is_attr);
75 
76 LXB_API lxb_dom_node_t *
77 lxb_dom_node_interface_destroy(lxb_dom_node_t *node);
78 
79 LXB_API lxb_status_t
80 lxb_dom_node_interface_copy(lxb_dom_node_t *dst,
81                             const lxb_dom_node_t *src, bool is_attr);
82 
83 LXB_API lxb_dom_node_t *
84 lxb_dom_node_destroy(lxb_dom_node_t *node);
85 
86 LXB_API lxb_dom_node_t *
87 lxb_dom_node_destroy_deep(lxb_dom_node_t *root);
88 
89 LXB_API lxb_dom_node_t *
90 lxb_dom_node_clone(lxb_dom_node_t *node, bool deep);
91 
92 LXB_API const lxb_char_t *
93 lxb_dom_node_name(lxb_dom_node_t *node, size_t *len);
94 
95 LXB_API void
96 lxb_dom_node_insert_child_wo_events(lxb_dom_node_t *to, lxb_dom_node_t *node);
97 
98 LXB_API void
99 lxb_dom_node_insert_child(lxb_dom_node_t *to, lxb_dom_node_t *node);
100 
101 LXB_API void
102 lxb_dom_node_insert_before_wo_events(lxb_dom_node_t *to, lxb_dom_node_t *node);
103 
104 LXB_API void
105 lxb_dom_node_insert_before(lxb_dom_node_t *to, lxb_dom_node_t *node);
106 
107 LXB_API void
108 lxb_dom_node_insert_after_wo_events(lxb_dom_node_t *to, lxb_dom_node_t *node);
109 
110 LXB_API void
111 lxb_dom_node_insert_after(lxb_dom_node_t *to, lxb_dom_node_t *node);
112 
113 LXB_API void
114 lxb_dom_node_remove_wo_events(lxb_dom_node_t *node);
115 
116 LXB_API void
117 lxb_dom_node_remove(lxb_dom_node_t *node);
118 
119 LXB_API lxb_status_t
120 lxb_dom_node_replace_all(lxb_dom_node_t *parent, lxb_dom_node_t *node);
121 
122 LXB_API void
123 lxb_dom_node_simple_walk(lxb_dom_node_t *root,
124                          lxb_dom_node_simple_walker_f walker_cb, void *ctx);
125 
126 LXB_API lxb_status_t
127 lxb_dom_node_by_tag_name(lxb_dom_node_t *root, lxb_dom_collection_t *collection,
128                          const lxb_char_t *qualified_name, size_t len);
129 LXB_API lxb_status_t
130 lxb_dom_node_by_class_name(lxb_dom_node_t *root,
131                            lxb_dom_collection_t *collection,
132                            const lxb_char_t *class_name, size_t len);
133 LXB_API lxb_status_t
134 lxb_dom_node_by_attr(lxb_dom_node_t *root, lxb_dom_collection_t *collection,
135                      const lxb_char_t *qualified_name, size_t qname_len,
136                      const lxb_char_t *value, size_t value_len,
137                      bool case_insensitive);
138 LXB_API lxb_status_t
139 lxb_dom_node_by_attr_begin(lxb_dom_node_t *root,
140                            lxb_dom_collection_t *collection,
141                            const lxb_char_t *qualified_name, size_t qname_len,
142                            const lxb_char_t *value, size_t value_len,
143                            bool case_insensitive);
144 LXB_API lxb_status_t
145 lxb_dom_node_by_attr_end(lxb_dom_node_t *root, lxb_dom_collection_t *collection,
146                          const lxb_char_t *qualified_name, size_t qname_len,
147                          const lxb_char_t *value, size_t value_len,
148                          bool case_insensitive);
149 LXB_API lxb_status_t
150 lxb_dom_node_by_attr_contain(lxb_dom_node_t *root,
151                              lxb_dom_collection_t *collection,
152                              const lxb_char_t *qualified_name, size_t qname_len,
153                              const lxb_char_t *value, size_t value_len,
154                              bool case_insensitive);
155 
156 /*
157  * Memory of returns value will be freed in document destroy moment.
158  * If you need to release returned resource after use, then call the
159  * lxb_dom_document_destroy_text(node->owner_document, text) function.
160  */
161 LXB_API lxb_char_t *
162 lxb_dom_node_text_content(lxb_dom_node_t *node, size_t *len);
163 
164 LXB_API lxb_status_t
165 lxb_dom_node_text_content_set(lxb_dom_node_t *node,
166                               const lxb_char_t *content, size_t len);
167 
168 LXB_API bool
169 lxb_dom_node_is_empty(const lxb_dom_node_t *root);
170 
171 
172 /*
173  * Inline functions
174  */
175 lxb_inline lxb_tag_id_t
lxb_dom_node_tag_id(lxb_dom_node_t * node)176 lxb_dom_node_tag_id(lxb_dom_node_t *node)
177 {
178     return node->local_name;
179 }
180 
181 lxb_inline lxb_dom_node_t *
lxb_dom_node_next(lxb_dom_node_t * node)182 lxb_dom_node_next(lxb_dom_node_t *node)
183 {
184     return node->next;
185 }
186 
187 lxb_inline lxb_dom_node_t *
lxb_dom_node_prev(lxb_dom_node_t * node)188 lxb_dom_node_prev(lxb_dom_node_t *node)
189 {
190     return node->prev;
191 }
192 
193 lxb_inline lxb_dom_node_t *
lxb_dom_node_parent(lxb_dom_node_t * node)194 lxb_dom_node_parent(lxb_dom_node_t *node)
195 {
196     return node->parent;
197 }
198 
199 lxb_inline lxb_dom_node_t *
lxb_dom_node_first_child(lxb_dom_node_t * node)200 lxb_dom_node_first_child(lxb_dom_node_t *node)
201 {
202     return node->first_child;
203 }
204 
205 lxb_inline lxb_dom_node_t *
lxb_dom_node_last_child(lxb_dom_node_t * node)206 lxb_dom_node_last_child(lxb_dom_node_t *node)
207 {
208     return node->last_child;
209 }
210 
211 /*
212  * No inline functions for ABI.
213  */
214 LXB_API lxb_tag_id_t
215 lxb_dom_node_tag_id_noi(lxb_dom_node_t *node);
216 
217 LXB_API lxb_dom_node_t *
218 lxb_dom_node_next_noi(lxb_dom_node_t *node);
219 
220 LXB_API lxb_dom_node_t *
221 lxb_dom_node_prev_noi(lxb_dom_node_t *node);
222 
223 LXB_API lxb_dom_node_t *
224 lxb_dom_node_parent_noi(lxb_dom_node_t *node);
225 
226 LXB_API lxb_dom_node_t *
227 lxb_dom_node_first_child_noi(lxb_dom_node_t *node);
228 
229 LXB_API lxb_dom_node_t *
230 lxb_dom_node_last_child_noi(lxb_dom_node_t *node);
231 
232 
233 #ifdef __cplusplus
234 } /* extern "C" */
235 #endif
236 
237 #endif /* LEXBOR_DOM_NODE_H */
238