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 0
343 if (rule->ref_count > 0) {
344 rule->ref_count--;
345 }
346
347 if (rule->ref_count == 0) {
348 (void) lxb_css_rule_destroy(rule, true);
349 }
350 #endif
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