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 ;
CRSelector * sel_list
A list of instances of #CRSimpeSel.
enum CRStatus cr_sel_eng_matches_node(CRSelEng *a_this, CRSimpleSel *a_sel, xmlNode *a_node, gboolean *a_result)
cr_sel_eng_matches_node: @a_this: the selection engine.
CRDeclaration * decl_list
A list of instances of CRDeclaration.
CRAtMediaRule * media_rule
union _CRStatement::@1 kind
CRStyleSheet * cr_cascade_get_sheet(CRCascade *a_this, enum CRStyleOrigin a_origin)
cr_cascade_get_sheet: @a_this: the current instance of CRCascade.
enum CRStatus cr_style_set_style_from_decl(CRStyle *a_this, CRDeclaration *a_decl)
Walks through a css2 property declaration, and populated the according field(s) in the CRStyle struct...
CRPropList * cr_prop_list_append2(CRPropList *a_this, CRString *a_prop, CRDeclaration *a_decl)
cr_prop_list_append2: Appends a pair of prop/declaration to the current prop list.
enum AttrMatchWay match_way
enum AddSelectorType type
enum Combinator combinator
The combinator that separates this simple selector from the previous one.
CRStatement * statements
The css statements list.
enum CRStatus cr_sel_eng_get_matched_style(CRSelEng *a_this, CRCascade *a_cascade, xmlNode *a_node, CRStyle *a_parent_style, CRStyle **a_style, gboolean a_set_props_to_initial_values)
An abstraction of a css stylesheet as defined by the css2 spec in chapter 4.
CRSelEng * cr_sel_eng_new(void)
cr_sel_eng_new: Creates a new instance of CRSelEng.
enum CRStatus cr_prop_list_lookup_prop(CRPropList *a_this, CRString *a_prop, CRPropList **a_pair)
cr_prop_list_lookup_prop: @a_this: the current instance of CRPropList @a_prop: the property to lookup...
typedefG_BEGIN_DECLS struct _CRSelector CRSelector
CRStatus
The status type returned by the methods of the croco library.
enum CRStatus cr_sel_eng_get_matched_properties_from_cascade(CRSelEng *a_this, CRCascade *a_cascade, xmlNode *a_node, CRPropList **a_props)
CRAdditionalSel * add_sel
The additional selector list of the current simple selector.
enum CRStatementType type
The type of the statement.
enum CRStatus cr_sel_eng_get_matched_rulesets(CRSelEng *a_this, CRStyleSheet *a_sheet, xmlNode *a_node, CRStatement ***a_rulesets, gulong *a_len)
cr_sel_eng_get_matched_rulesets: @a_this: the current instance of the selection engine.
enum CRStyleOrigin origin
typedefG_BEGIN_DECLS struct _CRPropList CRPropList
void cr_prop_list_destroy(CRPropList *a_this)
cr_prop_list_destroy: @a_this: the current instance of CRPropList
The abstraction of a css2 simple selection list as defined by the right part of the "selector" produc...
CRStatement * cur_stmt
where to store the next statement to be visited so that we can remember it from one method call to an...
The abstraction of css statement as defined in the chapter 4 and appendix D.1 of the css2 spec.
CRPropList * cr_prop_list_get_next(CRPropList *a_this)
cr_prop_list_get_next: @a_this: the current instance of CRPropList
void cr_sel_eng_destroy(CRSelEng *a_this)
cr_sel_eng_destroy: @a_this: the current instance of the selection engine.
CRStyle * cr_style_new(gboolean a_set_props_to_initial_values)
Default constructor of CRStyle.
union CRAdditionalSelectorContent content
CRString * property
The property.
CRPropList * cr_prop_list_unlink(CRPropList *a_this, CRPropList *a_pair)
cr_prop_list_unlink: @a_this: the current list of prop/decl pairs @a_pair: the prop/decl pair to unli...
enum CRStatus cr_sel_eng_get_pseudo_class_selector_handler(CRSelEng *a_this, guchar *a_name, enum CRPseudoType a_type, CRPseudoClassSelectorHandler *a_handler)
#define PRIVATE(a_this)
@CRSelEng:
CRStatement * parent_statement
enum CRStatus cr_sel_eng_unregister_pseudo_class_sel_handler(CRSelEng *a_this, guchar *a_name, enum CRPseudoType a_type)
enum CRStatus cr_prop_list_get_decl(CRPropList const *a_this, CRDeclaration **a_decl)
cr_prop_list_get_decl: @a_this: the current instance of CRPropList @a_decl: out parameter.
enum SimpleSelectorType type_mask
The declaration of the CRSelEng class.
gboolean(* CRPseudoClassSelectorHandler)(CRSelEng *a_this, CRAdditionalSel *a_add_sel, xmlNode *a_node)
CRStyleSheet * parent_sheet
enum CRStatus cr_style_set_props_to_initial_values(CRStyle *a_this)
Sets the style properties to their initial value according to the css2 spec.
enum CRStatus cr_sel_eng_unregister_all_pseudo_class_sel_handlers(CRSelEng *a_this)
cr_sel_eng_unregister_all_pseudo_class_sel_handlers: @a_this: the current instance of CRSelEng .
enum CRStatus cr_style_set_props_to_default_values(CRStyle *a_this)
Sets the style properties to their default values according to the css2 spec i.e inherit if the prope...
enum CRStatus cr_sel_eng_register_pseudo_class_sel_handler(CRSelEng *a_this, guchar *a_name, enum CRPseudoType a_type, CRPseudoClassSelectorHandler a_handler)
cr_sel_eng_register_pseudo_class_sel_handler: @a_this: the current instance of CRSelEng @a_pseudo_cla...
gboolean cr_utils_is_white_space(guint32 a_char)
Returns TRUE if a_char is a white space as defined in the css spec in chap 4.1.1.
CRPseudoClassSelectorHandler handler
#define strqcmp(str, lit, lit_len)
enum CRStatus cr_simple_sel_compute_specificity(CRSimpleSel *a_this)
cr_simple_sel_compute_specificity:
#define cr_utils_trace_info(a_msg)
Traces an info message.
typedefG_BEGIN_DECLS struct _CRSelEng CRSelEng
typedefG_BEGIN_DECLS struct _CRStyle CRStyle