36 #define PRIVATE(a_this) (a_this)->priv
59 static gboolean class_add_sel_matches_node (
CRAdditionalSel * a_add_sel,
72 gboolean a_eval_sel_list_from_end,
75 static enum CRStatus cr_sel_eng_get_matched_rulesets_real (
CRSelEng * a_this,
87 static gboolean pseudo_class_add_sel_matches_node (
CRSelEng * a_this,
92 static gboolean lang_pseudo_class_handler (
CRSelEng * a_this,
96 static gboolean first_child_pseudo_class_handler (
CRSelEng * a_this,
100 static xmlNode *get_next_element_node (xmlNode * a_node);
102 static xmlNode *get_next_child_element_node (xmlNode * a_node);
104 static xmlNode *get_prev_element_node (xmlNode * a_node);
106 static xmlNode *get_next_parent_element_node (xmlNode * a_node);
109 #define strqcmp(str,lit,lit_len) \
110 (strlen (str) != (lit_len) || memcmp (str, lit, lit_len))
113 lang_pseudo_class_handler (
CRSelEng * a_this,
116 xmlNode *node = a_node;
118 gboolean result = FALSE;
120 g_return_val_if_fail (a_this &&
PRIVATE (a_this)
138 for (; node; node = get_next_parent_element_node (node)) {
139 val = xmlGetProp (node, (
const xmlChar *)
"lang");
141 && !
strqcmp ((
const char *) val,
156 first_child_pseudo_class_handler (
CRSelEng * a_this,
159 xmlNode *node = NULL;
161 g_return_val_if_fail (a_this &&
PRIVATE (a_this)
176 node = get_next_child_element_node (a_node->parent);
183 pseudo_class_add_sel_matches_node (
CRSelEng * a_this,
190 g_return_val_if_fail (a_this &&
PRIVATE (a_this)
201 if (status !=
CR_OK || !handler)
204 return handler (a_this, a_add_sel, a_node);
214 class_add_sel_matches_node (
CRAdditionalSel * a_add_sel, xmlNode * a_node)
216 gboolean result = FALSE;
217 xmlChar *klass = NULL,
220 g_return_val_if_fail (a_add_sel
227 if (xmlHasProp (a_node, (
const xmlChar *)
"class")) {
228 klass = xmlGetProp (a_node, (
const xmlChar *)
"class");
229 for (cur = klass; cur && *cur; cur++) {
235 if (!strncmp ((
const char *) cur,
266 id_add_sel_matches_node (
CRAdditionalSel * a_add_sel, xmlNode * a_node)
268 gboolean result = FALSE;
271 g_return_val_if_fail (a_add_sel
277 g_return_val_if_fail (a_add_sel
281 if (xmlHasProp (a_node, (
const xmlChar *)
"id")) {
282 id = xmlGetProp (a_node, (
const xmlChar *)
"id");
305 attr_add_sel_matches_node (
CRAdditionalSel * a_add_sel, xmlNode * a_node)
309 g_return_val_if_fail (a_add_sel
314 cur_sel; cur_sel = cur_sel->
next) {
318 || !cur_sel->
name->stryng
319 || !cur_sel->
name->stryng->str)
322 if (!xmlHasProp (a_node,
323 (
const xmlChar *) cur_sel->
name->stryng->str))
329 xmlChar *value = NULL;
332 || !cur_sel->
name->stryng
333 || !cur_sel->
name->stryng->str
335 || !cur_sel->
value->stryng
336 || !cur_sel->
value->stryng->str)
341 (
const xmlChar *) cur_sel->
name->stryng->str))
346 (
const xmlChar *) cur_sel->
name->stryng->str);
350 ((
const char *) value,
351 cur_sel->
value->stryng->str)) {
361 xmlChar *value = NULL,
365 gboolean found = FALSE;
369 (
const xmlChar *) cur_sel->
name->stryng->str))
373 (
const xmlChar *) cur_sel->
name->stryng->str);
383 for (cur = value; *cur; cur++) {
389 (*cur) == TRUE && *cur)
399 (*cur) == FALSE && *cur)
405 ((
const char *) ptr1,
406 cur_sel->
value->stryng->str,
414 if (found == FALSE) {
424 xmlChar *value = NULL,
428 gboolean found = FALSE;
432 (
const xmlChar *) cur_sel->
name->stryng->str))
436 (
const xmlChar *) cur_sel->
name->stryng->str);
443 for (cur = value; *cur; cur++) {
448 while (*cur !=
'-' && *cur)
454 ((
const gchar *) ptr1, ptr2 - ptr1 + 1,
455 cur_sel->
value->stryng->str)
462 if (found == FALSE) {
484 additional_selector_matches_node (
CRSelEng * a_this,
489 gboolean evaluated = FALSE ;
491 for (tail = a_add_sel ;
495 g_return_val_if_fail (tail, FALSE) ;
497 for (cur_add_sel = tail ;
499 cur_add_sel = cur_add_sel->
prev) {
510 if (class_add_sel_matches_node (cur_add_sel,
519 if (id_add_sel_matches_node (cur_add_sel, a_node) == FALSE) {
530 if (attr_add_sel_matches_node (cur_add_sel, a_node)
537 if (pseudo_class_add_sel_matches_node
538 (a_this, cur_add_sel, a_node) == TRUE) {
544 if (evaluated == TRUE)
550 get_next_element_node (xmlNode * a_node)
552 xmlNode *cur_node = NULL;
554 g_return_val_if_fail (a_node, NULL);
556 cur_node = a_node->next;
557 while (cur_node && cur_node->type != XML_ELEMENT_NODE) {
558 cur_node = cur_node->next;
564 get_next_child_element_node (xmlNode * a_node)
566 xmlNode *cur_node = NULL;
568 g_return_val_if_fail (a_node, NULL);
570 cur_node = a_node->children;
573 if (a_node->children->type == XML_ELEMENT_NODE)
574 return a_node->children;
575 return get_next_element_node (a_node->children);
579 get_prev_element_node (xmlNode * a_node)
581 xmlNode *cur_node = NULL;
583 g_return_val_if_fail (a_node, NULL);
585 cur_node = a_node->prev;
586 while (cur_node && cur_node->type != XML_ELEMENT_NODE) {
587 cur_node = cur_node->prev;
593 get_next_parent_element_node (xmlNode * a_node)
595 xmlNode *cur_node = NULL;
597 g_return_val_if_fail (a_node, NULL);
599 cur_node = a_node->parent;
600 while (cur_node && cur_node->type != XML_ELEMENT_NODE) {
601 cur_node = cur_node->parent;
626 xmlNode * a_node, gboolean * a_result,
627 gboolean a_eval_sel_list_from_end,
631 xmlNode *cur_node = NULL;
633 g_return_val_if_fail (a_this &&
PRIVATE (a_this)
639 if (a_node->type != XML_ELEMENT_NODE)
642 if (a_eval_sel_list_from_end == TRUE) {
644 for (cur_sel = a_sel;
645 cur_sel && cur_sel->
next; cur_sel = cur_sel->
next) ;
650 for (cur_node = a_node; cur_sel; cur_sel = cur_sel->
prev) {
653 && cur_sel->
name->stryng
654 && cur_sel->
name->stryng->str)
655 && (!strcmp (cur_sel->
name->stryng->str,
656 (
const char *) cur_node->name)))
666 if (additional_selector_matches_node (a_this, cur_sel->
add_sel,
668 goto walk_a_step_in_expr;
673 goto walk_a_step_in_expr;
681 if (additional_selector_matches_node
682 (a_this, cur_sel->
add_sel, cur_node)
684 goto walk_a_step_in_expr;
693 if (a_recurse == FALSE) {
714 gboolean matches = FALSE;
720 for (n = cur_node->parent; n; n = n->parent) {
721 status = sel_matches_node_real
722 (a_this, cur_sel->
prev,
723 n, &matches, FALSE, TRUE);
728 if (matches == TRUE) {
753 cur_node = get_prev_element_node (cur_node);
759 cur_node = get_next_parent_element_node (cur_node);
819 cr_sel_eng_get_matched_rulesets_real (
CRSelEng * a_this,
828 gboolean matches = FALSE;
832 g_return_val_if_fail (a_this
846 if (
PRIVATE (a_this)->sheet != a_stylesheet) {
847 PRIVATE (a_this)->sheet = a_stylesheet;
857 for (cur_stmt =
PRIVATE (a_this)->cur_stmt, i = 0;
858 (
PRIVATE (a_this)->cur_stmt = cur_stmt);
859 cur_stmt = cur_stmt->
next) {
870 switch (cur_stmt->
type) {
887 rulesets->kind.ruleset->sel_list;
909 for (cur_sel = sel_list; cur_sel; cur_sel = cur_sel->next) {
910 if (!cur_sel->simple_sel)
914 (a_this, cur_sel->simple_sel,
917 if (status ==
CR_OK && matches == TRUE) {
925 a_rulesets[i] = cur_stmt;
939 g_return_val_if_fail (status ==
CR_OK,
942 cur_sel->simple_sel->
960 PRIVATE (a_this)->sheet = NULL;
973 g_return_val_if_fail (a_props && a_stmt
980 cur_decl; cur_decl = cur_decl->
next) {
988 || !cur_decl->
property->stryng->str)
1003 (props, cur_decl->
property, cur_decl);
1018 g_return_val_if_fail (decl,
CR_ERROR);
1051 (props, cur_decl->
property, cur_decl);
1057 parent_sheet->origin
1060 (
"We should not reach this line\n");
1125 result = g_try_malloc (
sizeof (
CRSelEng));
1130 memset (result, 0,
sizeof (
CRSelEng));
1140 (result, (guchar *)
"first-child",
1142 first_child_pseudo_class_handler);
1144 (result, (guchar *)
"lang",
1146 lang_pseudo_class_handler);
1173 g_return_val_if_fail (a_this &&
PRIVATE (a_this)
1176 handler_entry = g_try_malloc
1178 if (!handler_entry) {
1181 memset (handler_entry, 0,
1183 handler_entry->
name = (guchar *) g_strdup ((
const gchar *) a_name);
1184 handler_entry->
type = a_type;
1185 handler_entry->
handler = a_handler;
1186 list = g_list_append (
PRIVATE (a_this)->pcs_handlers, handler_entry);
1190 PRIVATE (a_this)->pcs_handlers = list;
1200 *deleted_elem = NULL;
1201 gboolean found = FALSE;
1206 for (elem =
PRIVATE (a_this)->pcs_handlers;
1207 elem; elem = g_list_next (elem)) {
1209 if (!strcmp ((
const char *) entry->
name, (
const char *) a_name)
1210 && entry->
type == a_type) {
1217 PRIVATE (a_this)->pcs_handlers = g_list_delete_link
1218 (
PRIVATE (a_this)->pcs_handlers, elem);
1221 g_free (entry->
name);
1223 g_list_free (deleted_elem);
1246 if (!
PRIVATE (a_this)->pcs_handlers)
1248 for (elem =
PRIVATE (a_this)->pcs_handlers;
1249 elem; elem = g_list_next (elem)) {
1254 g_free (entry->
name);
1260 g_list_free (
PRIVATE (a_this)->pcs_handlers);
1261 PRIVATE (a_this)->pcs_handlers = NULL;
1274 gboolean found = FALSE;
1276 g_return_val_if_fail (a_this &&
PRIVATE (a_this)
1279 for (elem =
PRIVATE (a_this)->pcs_handlers;
1280 elem; elem = g_list_next (elem)) {
1282 if (!strcmp ((
const char *) a_name, (
const char *) entry->
name)
1283 && entry->
type == a_type) {
1313 xmlNode * a_node, gboolean * a_result)
1315 g_return_val_if_fail (a_this &&
PRIVATE (a_this)
1319 if (a_node->type != XML_ELEMENT_NODE) {
1324 return sel_matches_node_real (a_this, a_sel,
1355 gulong tab_size = 0,
1358 gushort stmts_chunck_size = 8;
1360 g_return_val_if_fail (a_this
1363 && a_rulesets && *a_rulesets == NULL
1366 stmts_tab = g_try_malloc (stmts_chunck_size *
sizeof (
CRStatement *));
1373 memset (stmts_tab, 0, stmts_chunck_size *
sizeof (
CRStatement *));
1375 tab_size = stmts_chunck_size;
1378 while ((status = cr_sel_eng_get_matched_rulesets_real
1379 (a_this, a_sheet, a_node, stmts_tab + index, &tab_len))
1381 stmts_tab = g_try_realloc (stmts_tab,
1382 (tab_size + stmts_chunck_size)
1389 tab_size += stmts_chunck_size;
1391 tab_len = tab_size - index;
1394 tab_len = tab_size - stmts_chunck_size + tab_len;
1395 *a_rulesets = stmts_tab;
1421 gulong tab_size = 0,
1426 gushort stmts_chunck_size = 8;
1429 g_return_val_if_fail (a_this
1437 if (tab_size - index < 1) {
1438 stmts_tab = g_try_realloc
1439 (stmts_tab, (tab_size + stmts_chunck_size)
1446 tab_size += stmts_chunck_size;
1451 tab_len = tab_size - index;
1453 while ((status = cr_sel_eng_get_matched_rulesets_real
1454 (a_this, sheet, a_node, stmts_tab + index, &tab_len))
1456 stmts_tab = g_try_realloc
1457 (stmts_tab, (tab_size + stmts_chunck_size)
1464 tab_size += stmts_chunck_size;
1470 tab_len = tab_size - index;
1472 if (status !=
CR_OK) {
1478 tab_len = tab_size - index;
1487 for (i = 0; i < index; i++) {
1492 switch (stmt->
type) {
1496 status = put_css_properties_in_props_list
1520 gboolean a_set_props_to_initial_values)
1526 g_return_val_if_fail (a_this && a_cascade
1530 (a_this, a_cascade, a_node, &props);
1532 g_return_val_if_fail (status ==
CR_OK, status);
1535 *a_style =
cr_style_new (a_set_props_to_initial_values) ;
1536 g_return_val_if_fail (*a_style,
CR_ERROR);
1538 if (a_set_props_to_initial_values == TRUE) {
1544 (*a_style)->parent_style = a_parent_style;
1546 set_style_from_props (*a_style, props);
1564 g_return_if_fail (a_this);
1568 if (
PRIVATE (a_this)->pcs_handlers) {
1571 PRIVATE (a_this)->pcs_handlers = NULL ;