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 ;
@ PSEUDO_CLASS_ADD_SELECTOR
CRStyleSheet * cr_cascade_get_sheet(CRCascade *a_this, enum CRStyleOrigin a_origin)
cr_cascade_get_sheet: @a_this: the current instance of CRCascade.
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.
void cr_prop_list_destroy(CRPropList *a_this)
cr_prop_list_destroy: @a_this: the current instance of CRPropList
CRPropList * cr_prop_list_get_next(CRPropList *a_this)
cr_prop_list_get_next: @a_this: the current instance of CRPropList
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.
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_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 _CRPropList CRPropList
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)
#define strqcmp(str, lit, lit_len)
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.
void cr_sel_eng_destroy(CRSelEng *a_this)
cr_sel_eng_destroy: @a_this: the current instance of the selection engine.
enum CRStatus cr_sel_eng_get_pseudo_class_selector_handler(CRSelEng *a_this, guchar *a_name, enum CRPseudoType a_type, CRPseudoClassSelectorHandler *a_handler)
CRSelEng * cr_sel_eng_new(void)
cr_sel_eng_new: Creates a new instance of CRSelEng.
enum CRStatus cr_sel_eng_get_matched_properties_from_cascade(CRSelEng *a_this, CRCascade *a_cascade, xmlNode *a_node, CRPropList **a_props)
enum CRStatus cr_sel_eng_unregister_pseudo_class_sel_handler(CRSelEng *a_this, guchar *a_name, enum CRPseudoType a_type)
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...
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 .
#define PRIVATE(a_this)
@CRSelEng:
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.
The declaration of the CRSelEng class.
typedefG_BEGIN_DECLS struct _CRSelEng CRSelEng
gboolean(* CRPseudoClassSelectorHandler)(CRSelEng *a_this, CRAdditionalSel *a_add_sel, xmlNode *a_node)
typedefG_BEGIN_DECLS struct _CRSelector CRSelector
enum CRStatus cr_simple_sel_compute_specificity(CRSimpleSel *a_this)
cr_simple_sel_compute_specificity:
@ AT_IMPORT_RULE_STMT
A css2 import rule.
@ AT_MEDIA_RULE_STMT
A css2 media rule.
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...
CRStyle * cr_style_new(gboolean a_set_props_to_initial_values)
Default constructor of CRStyle.
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_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...
typedefG_BEGIN_DECLS struct _CRStyle CRStyle
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.
#define cr_utils_trace_info(a_msg)
Traces an info message.
CRStatus
The status type returned by the methods of the croco library.
@ CR_PSEUDO_CLASS_SEL_HANDLER_NOT_FOUND_ERROR
@ CR_OUTPUT_TOO_SHORT_ERROR
@ CR_BAD_PSEUDO_CLASS_SEL_HANDLER_ERROR
CRPseudoClassSelectorHandler handler
enum AddSelectorType type
union CRAdditionalSelectorContent content
enum AttrMatchWay match_way
CRString * property
The property.
CRStatement * parent_statement
CRSelector * sel_list
A list of instances of #CRSimpeSel.
CRDeclaration * decl_list
A list of instances of CRDeclaration.
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 a css2 simple selection list as defined by the right part of the "selector" produc...
CRAdditionalSel * add_sel
The additional selector list of the current simple selector.
enum Combinator combinator
The combinator that separates this simple selector from the previous one.
enum SimpleSelectorType type_mask
The abstraction of css statement as defined in the chapter 4 and appendix D.1 of the css2 spec.
enum CRStatementType type
The type of the statement.
CRStyleSheet * parent_sheet
union _CRStatement::@1 kind
CRAtMediaRule * media_rule
An abstraction of a css stylesheet as defined by the css2 spec in chapter 4.
enum CRStyleOrigin origin
CRStatement * statements
The css statements list.