xref: /php-src/ext/dom/lexbor/lexbor/css/rule.h (revision f0934090)
1 /*
2  * Copyright (C) 2021-2023 Alexander Borisov
3  *
4  * Author: Alexander Borisov <borisov@lexbor.com>
5  */
6 
7 #ifndef LXB_CSS_RULE_H
8 #define LXB_CSS_RULE_H
9 
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13 
14 #include "lexbor/css/base.h"
15 #include "lexbor/css/at_rule.h"
16 #include "lexbor/css/property.h"
17 #include "lexbor/css/selectors/selectors.h"
18 
19 
20 #define lxb_css_rule(rule)                  ((lxb_css_rule_t *) (rule))
21 #define lxb_css_rule_list(rule)             ((lxb_css_rule_list_t *) (rule))
22 #define lxb_css_rule_at(rule)               ((lxb_css_rule_at_t *) (rule))
23 #define lxb_css_rule_style(rule)            ((lxb_css_rule_style_t *) (rule))
24 #define lxb_css_rule_bad_style(rule)        ((lxb_css_rule_bad_style_t *) (rule))
25 #define lxb_css_rule_declaration_list(rule) ((lxb_css_rule_declaration_list_t *) (rule))
26 #define lxb_css_rule_declaration(rule)      ((lxb_css_rule_declaration_t *) (rule))
27 
28 
29 typedef enum {
30     LXB_CSS_RULE_UNDEF = 0,
31     LXB_CSS_RULE_STYLESHEET,
32     LXB_CSS_RULE_LIST,
33     LXB_CSS_RULE_AT_RULE,
34     LXB_CSS_RULE_STYLE,
35     LXB_CSS_RULE_BAD_STYLE,
36     LXB_CSS_RULE_DECLARATION_LIST,
37     LXB_CSS_RULE_DECLARATION
38 }
39 lxb_css_rule_type_t;
40 
41 typedef struct lxb_css_rule lxb_css_rule_t;
42 
43 struct lxb_css_rule {
44     lxb_css_rule_type_t type;
45     lxb_css_rule_t      *next;
46     lxb_css_rule_t      *prev;
47     lxb_css_rule_t      *parent;
48 
49     const lxb_char_t    *begin;
50     const lxb_char_t    *end;
51 
52     lxb_css_memory_t    *memory;
53     size_t              ref_count;
54 };
55 
56 struct lxb_css_rule_list {
57     lxb_css_rule_t rule;
58 
59     lxb_css_rule_t *first;
60     lxb_css_rule_t *last;
61 };
62 
63 struct lxb_css_rule_at {
64     lxb_css_rule_t rule;
65 
66     uintptr_t      type;
67 
68     union {
69         lxb_css_at_rule__undef_t    *undef;
70         lxb_css_at_rule__custom_t   *custom;
71         lxb_css_at_rule_media_t     *media;
72         lxb_css_at_rule_namespace_t *ns;
73         void                        *user;
74     } u;
75 };
76 
77 struct lxb_css_rule_style {
78     lxb_css_rule_t                  rule;
79 
80     lxb_css_selector_list_t         *selector;
81     lxb_css_rule_declaration_list_t *declarations;
82 };
83 
84 struct lxb_css_rule_bad_style {
85     lxb_css_rule_t                  rule;
86 
87     lexbor_str_t                    selectors;
88     lxb_css_rule_declaration_list_t *declarations;
89 };
90 
91 struct lxb_css_rule_declaration_list {
92     lxb_css_rule_t rule;
93 
94     lxb_css_rule_t *first;
95     lxb_css_rule_t *last;
96 
97     size_t         count;
98 };
99 
100 struct lxb_css_rule_declaration {
101     lxb_css_rule_t rule;
102     uintptr_t      type;
103 
104     union {
105         lxb_css_property__undef_t                *undef;
106         lxb_css_property__custom_t               *custom;
107         lxb_css_property_display_t               *display;
108         lxb_css_property_order_t                 *order;
109         lxb_css_property_visibility_t            *visibility;
110         lxb_css_property_width_t                 *width;
111         lxb_css_property_height_t                *height;
112         lxb_css_property_box_sizing_t            *box_sizing;
113         lxb_css_property_margin_t                *margin;
114         lxb_css_property_margin_top_t            *margin_top;
115         lxb_css_property_margin_right_t          *margin_right;
116         lxb_css_property_margin_bottom_t         *margin_bottom;
117         lxb_css_property_margin_left_t           *margin_left;
118         lxb_css_property_padding_t               *padding;
119         lxb_css_property_padding_top_t           *padding_top;
120         lxb_css_property_padding_right_t         *padding_right;
121         lxb_css_property_padding_bottom_t        *padding_bottom;
122         lxb_css_property_padding_left_t          *padding_left;
123         lxb_css_property_border_t                *border;
124         lxb_css_property_border_top_t            *border_top;
125         lxb_css_property_border_right_t          *border_right;
126         lxb_css_property_border_bottom_t         *border_bottom;
127         lxb_css_property_border_left_t           *border_left;
128         lxb_css_property_border_top_color_t      *border_top_color;
129         lxb_css_property_border_right_color_t    *border_right_color;
130         lxb_css_property_border_bottom_color_t   *border_bottom_color;
131         lxb_css_property_border_left_color_t     *border_left_color;
132         lxb_css_property_background_color_t      *background_color;
133         lxb_css_property_color_t                 *color;
134         lxb_css_property_opacity_t               *opacity;
135         lxb_css_property_position_t              *position;
136         lxb_css_property_top_t                   *top;
137         lxb_css_property_right_t                 *right;
138         lxb_css_property_bottom_t                *bottom;
139         lxb_css_property_left_t                  *left;
140         lxb_css_property_inset_block_start_t     *inset_block_start;
141         lxb_css_property_inset_inline_start_t    *inset_inline_start;
142         lxb_css_property_inset_block_end_t       *inset_block_end;
143         lxb_css_property_inset_inline_end_t      *inset_inline_end;
144         lxb_css_property_text_transform_t        *text_transform;
145         lxb_css_property_text_align_t            *text_align;
146         lxb_css_property_text_align_all_t        *text_align_all;
147         lxb_css_property_text_align_last_t       *text_align_last;
148         lxb_css_property_text_justify_t          *text_justify;
149         lxb_css_property_text_indent_t           *text_indent;
150         lxb_css_property_white_space_t           *white_space;
151         lxb_css_property_tab_size_t              *tab_size;
152         lxb_css_property_word_break_t            *word_break;
153         lxb_css_property_line_break_t            *line_break;
154         lxb_css_property_hyphens_t               *hyphens;
155         lxb_css_property_overflow_wrap_t         *overflow_wrap;
156         lxb_css_property_word_wrap_t             *word_wrap;
157         lxb_css_property_word_spacing_t          *word_spacing;
158         lxb_css_property_letter_spacing_t        *letter_spacing;
159         lxb_css_property_hanging_punctuation_t   *hanging_punctuation;
160         lxb_css_property_font_family_t           *font_family;
161         lxb_css_property_font_weight_t           *font_weight;
162         lxb_css_property_font_stretch_t          *font_stretch;
163         lxb_css_property_font_style_t            *font_style;
164         lxb_css_property_font_size_t             *font_size;
165         lxb_css_property_float_reference_t       *float_reference;
166         lxb_css_property_float_t                 *floatp;
167         lxb_css_property_clear_t                 *clear;
168         lxb_css_property_float_defer_t           *float_defer;
169         lxb_css_property_float_offset_t          *float_offset;
170         lxb_css_property_wrap_flow_t             *wrap_flow;
171         lxb_css_property_wrap_through_t          *wrap_through;
172         lxb_css_property_flex_direction_t        *flex_direction;
173         lxb_css_property_flex_wrap_t             *flex_wrap;
174         lxb_css_property_flex_flow_t             *flex_flow;
175         lxb_css_property_flex_t                  *flex;
176         lxb_css_property_flex_grow_t             *flex_grow;
177         lxb_css_property_flex_shrink_t           *flex_shrink;
178         lxb_css_property_flex_basis_t            *flex_basis;
179         lxb_css_property_justify_content_t       *justify_content;
180         lxb_css_property_align_items_t           *align_items;
181         lxb_css_property_align_self_t            *align_self;
182         lxb_css_property_align_content_t         *align_content;
183         lxb_css_property_dominant_baseline_t     *dominant_baseline;
184         lxb_css_property_vertical_align_t        *vertical_align;
185         lxb_css_property_baseline_source_t       *baseline_source;
186         lxb_css_property_alignment_baseline_t    *alignment_baseline;
187         lxb_css_property_baseline_shift_t        *baseline_shift;
188         lxb_css_property_line_height_t           *line_height;
189         lxb_css_property_z_index_t               *z_index;
190         lxb_css_property_direction_t             *direction;
191         lxb_css_property_unicode_bidi_t          *unicode_bidi;
192         lxb_css_property_writing_mode_t          *writing_mode;
193         lxb_css_property_text_orientation_t      *text_orientation;
194         lxb_css_property_text_combine_upright_t  *text_combine_upright;
195         lxb_css_property_overflow_x_t            *overflow_x;
196         lxb_css_property_overflow_y_t            *overflow_y;
197         lxb_css_property_overflow_block_t        *overflow_block;
198         lxb_css_property_overflow_inline_t       *overflow_inline;
199         lxb_css_property_text_overflow_t         *text_overflow;
200         lxb_css_property_text_decoration_line_t  *text_decoration_line;
201         lxb_css_property_text_decoration_style_t *text_decoration_style;
202         lxb_css_property_text_decoration_color_t *text_decoration_color;
203         lxb_css_property_text_decoration_t       *text_decoration;
204         void                                     *user;
205     } u;
206 
207     bool            important;
208 };
209 
210 
211 LXB_API void *
212 lxb_css_rule_destroy(lxb_css_rule_t *node, bool self_destroy);
213 
214 LXB_API lxb_status_t
215 lxb_css_rule_serialize(const lxb_css_rule_t *rule,
216                        lexbor_serialize_cb_f cb, void *ctx);
217 
218 LXB_API lxb_status_t
219 lxb_css_rule_serialize_chain(const lxb_css_rule_t *rule,
220                              lexbor_serialize_cb_f cb, void *ctx);
221 
222 LXB_API lxb_css_rule_list_t *
223 lxb_css_rule_list_destroy(lxb_css_rule_list_t *list, bool self_destroy);
224 
225 LXB_API lxb_status_t
226 lxb_css_rule_list_serialize(const lxb_css_rule_list_t *list,
227                             lexbor_serialize_cb_f cb, void *ctx);
228 
229 LXB_API lxb_css_rule_at_t *
230 lxb_css_rule_at_destroy(lxb_css_rule_at_t *at, bool self_destroy);
231 
232 LXB_API lxb_status_t
233 lxb_css_rule_at_serialize(const lxb_css_rule_at_t *at, lexbor_serialize_cb_f cb,
234                           void *ctx);
235 
236 LXB_API lxb_status_t
237 lxb_css_rule_at_serialize_name(const lxb_css_rule_at_t *at, lexbor_serialize_cb_f cb,
238                                void *ctx);
239 
240 LXB_API lxb_css_rule_style_t *
241 lxb_css_rule_style_destroy(lxb_css_rule_style_t *style, bool self_destroy);
242 
243 LXB_API lxb_status_t
244 lxb_css_rule_style_serialize(const lxb_css_rule_style_t *style,
245                              lexbor_serialize_cb_f cb, void *ctx);
246 
247 LXB_API lxb_css_rule_bad_style_t *
248 lxb_css_rule_bad_style_destroy(lxb_css_rule_bad_style_t *bad, bool self_destroy);
249 
250 LXB_API lxb_status_t
251 lxb_css_rule_bad_style_serialize(const lxb_css_rule_bad_style_t *bad,
252                                  lexbor_serialize_cb_f cb, void *ctx);
253 
254 LXB_API lxb_css_rule_declaration_list_t *
255 lxb_css_rule_declaration_list_destroy(lxb_css_rule_declaration_list_t *list,
256                                       bool self_destroy);
257 
258 LXB_API lxb_status_t
259 lxb_css_rule_declaration_list_serialize(const lxb_css_rule_declaration_list_t *list,
260                                         lexbor_serialize_cb_f cb, void *ctx);
261 
262 LXB_API lxb_css_rule_declaration_t *
263 lxb_css_rule_declaration_destroy(lxb_css_rule_declaration_t *declr,
264                                  bool self_destroy);
265 
266 LXB_API lxb_status_t
267 lxb_css_rule_declaration_serialize(const lxb_css_rule_declaration_t *declaration,
268                                    lexbor_serialize_cb_f cb, void *ctx);
269 
270 LXB_API lxb_status_t
271 lxb_css_rule_declaration_serialize_name(const lxb_css_rule_declaration_t *declr,
272                                         lexbor_serialize_cb_f cb, void *ctx);
273 
274 /*
275  * Inline functions
276  */
277 lxb_inline void
lxb_css_rule_insert_next(lxb_css_rule_t * root,lxb_css_rule_t * rule)278 lxb_css_rule_insert_next(lxb_css_rule_t *root, lxb_css_rule_t *rule)
279 {
280     if (root->next != NULL) {
281         rule->next = root->next;
282     }
283 
284     root->next = rule;
285     rule->prev = root;
286 }
287 
288 lxb_inline lxb_css_rule_t *
lxb_css_rule_create(lxb_css_memory_t * memory,size_t size,lxb_css_rule_type_t type)289 lxb_css_rule_create(lxb_css_memory_t *memory, size_t size,
290                     lxb_css_rule_type_t type)
291 {
292     lxb_css_rule_t *rule;
293 
294     rule = (lxb_css_rule_t *) lexbor_mraw_calloc(memory->tree, size);
295     if (rule== NULL) {
296         return NULL;
297     }
298 
299     rule->type = type;
300     rule->memory = memory;
301 
302     return rule;
303 }
304 
305 lxb_inline lxb_css_rule_list_t *
lxb_css_rule_list_create(lxb_css_memory_t * memory)306 lxb_css_rule_list_create(lxb_css_memory_t *memory)
307 {
308     return (lxb_css_rule_list_t *) lxb_css_rule_create(memory,
309                                                        sizeof(lxb_css_rule_list_t),
310                                                        LXB_CSS_RULE_LIST);
311 }
312 
313 lxb_inline size_t
lxb_css_rule_ref_count(lxb_css_rule_t * rule)314 lxb_css_rule_ref_count(lxb_css_rule_t *rule)
315 {
316     return rule->ref_count;
317 }
318 
319 lxb_inline lxb_status_t
lxb_css_rule_ref_inc(lxb_css_rule_t * rule)320 lxb_css_rule_ref_inc(lxb_css_rule_t *rule)
321 {
322     if (SIZE_MAX - rule->ref_count == 0) {
323         return LXB_STATUS_ERROR_OVERFLOW;
324     }
325 
326     rule->ref_count++;
327 
328     return LXB_STATUS_OK;
329 }
330 
331 lxb_inline void
lxb_css_rule_ref_dec(lxb_css_rule_t * rule)332 lxb_css_rule_ref_dec(lxb_css_rule_t *rule)
333 {
334     if (rule->ref_count > 0) {
335         rule->ref_count--;
336     }
337 }
338 
339 lxb_inline void
lxb_css_rule_ref_dec_destroy(lxb_css_rule_t * rule)340 lxb_css_rule_ref_dec_destroy(lxb_css_rule_t *rule)
341 {
342     if (rule->ref_count > 0) {
343         rule->ref_count--;
344     }
345 
346     if (rule->ref_count == 0) {
347 #if 0
348         (void) lxb_css_rule_destroy(rule, true);
349 #endif
350     }
351 }
352 
353 lxb_inline void
lxb_css_rule_list_append(lxb_css_rule_list_t * list,lxb_css_rule_t * rule)354 lxb_css_rule_list_append(lxb_css_rule_list_t *list, lxb_css_rule_t *rule)
355 {
356     if (list->first == NULL) {
357         list->first = rule;
358     }
359     else {
360         lxb_css_rule_insert_next(list->last, rule);
361     }
362 
363     list->last = rule;
364     rule->parent = lxb_css_rule(list);
365 
366     (void) lxb_css_rule_ref_inc(rule);
367 }
368 
369 lxb_inline lxb_css_rule_at_t *
lxb_css_rule_at_create(lxb_css_memory_t * memory)370 lxb_css_rule_at_create(lxb_css_memory_t *memory)
371 {
372     return (lxb_css_rule_at_t *)
373         lxb_css_rule_create(memory, sizeof(lxb_css_rule_at_t),
374                             LXB_CSS_RULE_AT_RULE);
375 }
376 
377 lxb_inline lxb_css_rule_style_t *
lxb_css_rule_style_create(lxb_css_memory_t * memory)378 lxb_css_rule_style_create(lxb_css_memory_t *memory)
379 {
380     return (lxb_css_rule_style_t *)
381         lxb_css_rule_create(memory, sizeof(lxb_css_rule_style_t),
382                             LXB_CSS_RULE_STYLE);
383 }
384 
385 lxb_inline lxb_css_rule_bad_style_t *
lxb_css_rule_bad_style_create(lxb_css_memory_t * memory)386 lxb_css_rule_bad_style_create(lxb_css_memory_t *memory)
387 {
388     return (lxb_css_rule_bad_style_t *)
389         lxb_css_rule_create(memory, sizeof(lxb_css_rule_bad_style_t),
390                             LXB_CSS_RULE_BAD_STYLE);
391 }
392 
393 lxb_inline lxb_css_rule_declaration_list_t *
lxb_css_rule_declaration_list_create(lxb_css_memory_t * memory)394 lxb_css_rule_declaration_list_create(lxb_css_memory_t *memory)
395 {
396     return (lxb_css_rule_declaration_list_t *)
397         lxb_css_rule_create(memory, sizeof(lxb_css_rule_declaration_list_t),
398                             LXB_CSS_RULE_DECLARATION_LIST);
399 }
400 
401 lxb_inline void
lxb_css_rule_declaration_list_append(lxb_css_rule_declaration_list_t * list,lxb_css_rule_t * rule)402 lxb_css_rule_declaration_list_append(lxb_css_rule_declaration_list_t *list,
403                                      lxb_css_rule_t *rule)
404 {
405     if (list->first == NULL) {
406         list->first = rule;
407     }
408     else {
409         lxb_css_rule_insert_next(list->last, rule);
410     }
411 
412     list->last = rule;
413     rule->parent = lxb_css_rule(list);
414 
415     (void) lxb_css_rule_ref_inc(rule);
416 
417     list->count++;
418 }
419 
420 lxb_inline lxb_css_rule_declaration_t *
lxb_css_rule_declaration_create(lxb_css_memory_t * memory)421 lxb_css_rule_declaration_create(lxb_css_memory_t *memory)
422 {
423     return (lxb_css_rule_declaration_t *)
424         lxb_css_rule_create(memory, sizeof(lxb_css_rule_declaration_t),
425                             LXB_CSS_RULE_DECLARATION);
426 }
427 
428 
429 #ifdef __cplusplus
430 } /* extern "C" */
431 #endif
432 
433 #endif /* LXB_CSS_RULE_H */
434