diff options
author | Dodji Seketeli <dodji@src.gnome.org> | 2003-03-02 02:24:52 +0000 |
---|---|---|
committer | Dodji Seketeli <dodji@src.gnome.org> | 2003-03-02 02:24:52 +0000 |
commit | 65045e6d2723c15105a5c33aaef059a3a366fe63 (patch) | |
tree | d7919629e629c05937491cc83ec337dd31674769 /src/cr-sel-eng.c | |
parent | b3a178051bb3f7186613e65645749f4febfd6671 (diff) | |
download | libcroco-65045e6d2723c15105a5c33aaef059a3a366fe63.tar.gz |
started to write a selector "requester".
Diffstat (limited to 'src/cr-sel-eng.c')
-rw-r--r-- | src/cr-sel-eng.c | 192 |
1 files changed, 190 insertions, 2 deletions
diff --git a/src/cr-sel-eng.c b/src/cr-sel-eng.c index f12da75..b376a55 100644 --- a/src/cr-sel-eng.c +++ b/src/cr-sel-eng.c @@ -53,6 +53,21 @@ sel_matches_node_real (CRSelEng *a_this, CRSimpleSel *a_sel, xmlNode *a_node, gboolean *a_result, gboolean a_recurse) ; +struct _CRSelEngPriv +{ + /*not used yet*/ + gboolean case_sensitive ; + + CRStyleSheet *sheet ; + + /** + *where to store the next statement + *to be visited so that we can remember + *it from one method call to another. + */ + CRStatement *cur_stmt ; +}; + static gboolean class_add_sel_matches_node (CRAdditionalSel *a_add_sel, xmlNode *a_node) @@ -475,10 +490,164 @@ sel_matches_node_real (CRSelEng *a_this, CRSimpleSel *a_sel, return CR_OK ; } -struct _CRSelEngPriv + +/** + *Returns array of the ruleset statements that matches the + *given xml node. + *The engine keeps in memory the last statement he + *visited during the match. So, the next call + *to this function will eventually return a rulesets list starting + *from the last ruleset statement visited during the previous call. + *The enable users to get matching rulesets in an incremental way. + * + *@param a_sel_eng the current selection engine + *@param a_node the xml node for which the request + *is being made. + *@param a_sel_list the list of selectors to perform the search in. + *@param a_rulesets in/out parameter. A pointer to the + *returned array of rulesets statements that match the xml node + *given in parameter. The caller allocates the array before calling this + *function. + *@param a_len in/out parameter the length (in sizeof (#CRStatement*)) + *of the returned array. + *(the length of a_rulesets, more precisely). + *The caller must set it to the length of a_ruleset prior to calling this + *function. In return, the function sets it to the length + *(in sizeof (#CRStatement)) of the actually returned CRStatement array. + *@return CR_OK if everything went well, an error code otherwise. + */ +static enum CRStatus +cr_sel_eng_get_rulesets_real (CRSelEng *a_this, + CRStyleSheet *a_stylesheet, + xmlNode *a_node, + CRStatement **a_rulesets, + glong *a_len) { + CRStatement *cur_stmt = NULL ; + CRSelector *sel_list = NULL, *cur_sel = NULL ; + gboolean matches = FALSE ; + enum CRStatus status = CR_OK ; + glong i = 0; + + g_return_val_if_fail (a_this + && a_stylesheet + && a_stylesheet->statements + && a_node + && a_rulesets, + CR_BAD_PARAM_ERROR) ; + + /* + *if this stylesheet is "new one" + *let's remember it for subsequent calls. + */ + if (PRIVATE (a_this)->sheet != a_stylesheet) + { + PRIVATE (a_this)->sheet = a_stylesheet ; + PRIVATE (a_this)->cur_stmt = a_stylesheet->statements ; + } + + /* + *walk through the list of statements and, + *get the selectors list inside the statements that + *contain some, and try to match our xml node in these + *selectors lists. + */ + for (cur_stmt = PRIVATE (a_this)->cur_stmt, i = 0 ; + (PRIVATE (a_this)->cur_stmt = cur_stmt) && i < *a_len ; + cur_stmt = cur_stmt->next) + { + /* + *initialyze the selector list in which we will + *really perform the search. + */ + sel_list = NULL ; + + /* + *get the the damn selector list in + *which we have to look + */ + switch (cur_stmt->type) + { + case RULESET_STMT: + if (cur_stmt->kind.ruleset + && cur_stmt->kind.ruleset->sel_list) + { + sel_list = cur_stmt->kind.ruleset->sel_list ; + } + break ; + + case AT_MEDIA_RULE_STMT: + if (cur_stmt->kind.media_rule + && cur_stmt->kind.media_rule->rulesets + && cur_stmt->kind.media_rule->rulesets-> + kind.ruleset + &&cur_stmt->kind.media_rule->rulesets-> + kind.ruleset->sel_list) + { + sel_list = + cur_stmt->kind.media_rule-> + rulesets->kind.ruleset->sel_list ; + } + break ; + + case AT_IMPORT_RULE_STMT: + /* + *some recursivity may be needed here. + *I don't like this :( + */ + break ; + default: + break ; + } + + if (!sel_list) + continue ; + + /* + *now, we have a selector list to look in. + *let's walk through it and try to match the xml_node + *on each item of the list. + */ + for (cur_sel = sel_list ; cur_sel ; cur_sel = cur_sel->next) + { + if (!cur_sel->simple_sel) + continue ; + + status = cr_sel_eng_sel_matches_node + (a_this, cur_sel->simple_sel, + a_node, &matches) ; + + if (status == CR_OK && matches == TRUE) + { + /* + *bingo, we found one ruleset that + *matches that fucking node. + *lets put it in the out array. + */ + + if (i < *a_len) + { + a_rulesets[i] = cur_stmt ; + i++ ; + } + } + } + } + + if (!PRIVATE (a_this)->cur_stmt) + { + /* + *we reached the end of stylesheet + *no need to store any info. + */ + PRIVATE (a_this)->sheet = NULL ; + } + + *a_len = i ; + + return CR_OK ; +} -}; /** @@ -498,6 +667,16 @@ cr_sel_eng_new (void) return NULL ; } memset (result, 0, sizeof (CRSelEng)) ; + + PRIVATE (result) = g_try_malloc (sizeof (CRSelEngPriv)) ; + if (!PRIVATE (result)) + { + cr_utils_trace_info ("Out of memory") ; + g_free (result) ; + return NULL ; + } + memset (result, 0, sizeof (CRSelEngPriv)) ; + return result ; } @@ -506,6 +685,14 @@ cr_sel_eng_new (void) *Evaluates a chained list of simple selectors (known as a css2 selector). *Says wheter if this selector matches the xml node given in parameter or *not. + *@param a_this the selection engine. + *@param a_sel the simple selector against which the xml node + *is going to be matched. + *@param a_node the node against which the selector is going to be matched. + *@param a_result out parameter. The result of the match. Is set to + *TRUE if the selector matches the node, FALSE otherwise. This value + *is considered if and only if this functions returns CR_OK. + *@return the CR_OK if the selection ran correctly, an error code otherwise. */ enum CRStatus cr_sel_eng_sel_matches_node (CRSelEng *a_this, CRSimpleSel *a_sel, @@ -521,6 +708,7 @@ cr_sel_eng_sel_matches_node (CRSelEng *a_this, CRSimpleSel *a_sel, a_result, TRUE) ; } + /** *The destructor of #CRSelEng *@param a_this the current instance of the selection engine. |