diff options
author | Dodji Seketeli <dodji@src.gnome.org> | 2003-05-20 20:03:34 +0000 |
---|---|---|
committer | Dodji Seketeli <dodji@src.gnome.org> | 2003-05-20 20:03:34 +0000 |
commit | cf0f243f7e99156489019360c062a08d824aed22 (patch) | |
tree | 8e9ef02d08646e3720c4a78bf2a8ff69ad2abd34 /src | |
parent | f1f4a02b4c33ad19773c3152c9408e2dadcd31d1 (diff) | |
download | libcroco-cf0f243f7e99156489019360c062a08d824aed22.tar.gz |
went forward in the cascading support. I still have a long way to go.
Dodji.
Diffstat (limited to 'src')
-rw-r--r-- | src/layeng/Makefile.am | 11 | ||||
-rw-r--r-- | src/layeng/cr-box-view.c | 13 | ||||
-rw-r--r-- | src/layeng/cr-lay-eng.c | 90 | ||||
-rw-r--r-- | src/layeng/cr-lay-eng.h | 7 | ||||
-rw-r--r-- | src/libcroco.h | 2 | ||||
-rw-r--r-- | src/parser/cr-cascade.c | 23 | ||||
-rw-r--r-- | src/parser/cr-cascade.h | 13 | ||||
-rw-r--r-- | src/parser/cr-declaration.c | 31 | ||||
-rw-r--r-- | src/parser/cr-declaration.h | 15 | ||||
-rw-r--r-- | src/parser/cr-om-parser.c | 24 | ||||
-rw-r--r-- | src/parser/cr-statement.c | 87 | ||||
-rw-r--r-- | src/parser/cr-statement.h | 54 | ||||
-rw-r--r-- | src/parser/cr-stylesheet.h | 21 | ||||
-rw-r--r-- | src/seleng/Makefile.am | 2 | ||||
-rw-r--r-- | src/seleng/cr-sel-eng.c | 270 | ||||
-rw-r--r-- | src/seleng/cr-sel-eng.h | 15 |
16 files changed, 501 insertions, 177 deletions
diff --git a/src/layeng/Makefile.am b/src/layeng/Makefile.am index 0108d58..ff297f0 100644 --- a/src/layeng/Makefile.am +++ b/src/layeng/Makefile.am @@ -5,15 +5,16 @@ crlayenginc_HEADERS= *.h #the layout engine files if HAVE_LAYENG -LAYENG_SRCS= cr-style.c cr-box.c cr-box-view.c cr-lay-eng.c +LAYENG_SRCS= cr-box.c cr-box-view.c cr-lay-eng.c endif libcrlayeng_la_SOURCES=$(LAYENG_SRCS) -INCLUDES=-I$(top_srcdir) -I$(top_srcdir)/src/parser -I$(top_srcdir)/src/seleng -I$(top_srcdir)/intl \ +INCLUDES=-I$(top_srcdir) -I$(top_srcdir)/src/parser \ +-I$(top_srcdir)/src/seleng -I$(top_srcdir)/intl \ @GLIB2_CFLAGS@ @LIBXML2_CFLAGS@ @LIBGNOMEUI2_CFLAGS@ +LDADD=$(top_srcdir)/src/parser/@CROCO_PARSER_LIB@ -LDADD=$(top_srcdir)/src/parser/libcroco.la $(top_srcdir)/src/parser/libcrseleng.la - -libcrlayeng_la_LDFLAGS=-version-info @LIBCROCO_VERSION_INFO@ @LIBXML2_LIBS@ \ +libcrlayeng_la_LDFLAGS=-version-info @LIBCROCO_VERSION_INFO@ \ +$(top_srcdir)/src/seleng/@CROCO_SELENG_LIB@ @LIBXML2_LIBS@ \ @LIBGNOMEUI2_LIBS@ diff --git a/src/layeng/cr-box-view.c b/src/layeng/cr-box-view.c index 14ba6c3..a6cdfe6 100644 --- a/src/layeng/cr-box-view.c +++ b/src/layeng/cr-box-view.c @@ -98,12 +98,13 @@ set_color (CRBoxView *a_this, CRRgb *a_rgb_color, static void cr_box_view_class_init (CRBoxViewClass *a_klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (a_klass) ; - GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (a_klass) ; - - gv_parent_class = (GtkLayoutClass *) - g_type_class_peek_parent (gobject_class) ; + GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (a_klass) ; + gv_parent_class = + g_type_class_peek_parent (a_klass) ; + + g_return_if_fail (gv_parent_class) ; + g_return_if_fail (gtk_object_class) ; gtk_object_class->destroy = cr_box_view_destroy ; } @@ -689,7 +690,7 @@ cr_box_view_get_box_model (CRBoxView *a_this, CRBoxModel **a_box_model) void cr_box_view_destroy (GtkObject *a_this) -{ +{ CRBoxView *self = NULL ; g_return_if_fail (a_this && CR_IS_BOX_VIEW (a_this)) ; diff --git a/src/layeng/cr-lay-eng.c b/src/layeng/cr-lay-eng.c index 91c1c30..6a352d1 100644 --- a/src/layeng/cr-lay-eng.c +++ b/src/layeng/cr-lay-eng.c @@ -544,8 +544,8 @@ create_box_tree_real (CRLayEng * a_this, if (cur->type == XML_ELEMENT_NODE) { status = - cr_lay_eng_get_matched_style - (a_this, + cr_sel_eng_get_matched_style + (PRIVATE (a_this)->sel_eng, PRIVATE (a_this)->cascade, cur, parent_style, &style) ; @@ -1385,92 +1385,6 @@ cr_lay_eng_create_box_model (CRLayEng *a_this, } -/** - *Retrieves the style structure that matches the xml node - *from the cascade. - *NOTE: this does not implement the complex cascade algorithms - *described in the css2 spec from chapter 6.4 on, but instead, - *is just an empty design sketch so that other hackers (yeah, we can dream) - *can come an implement it. I don't have the time for this right now. - *@param a_this the current instance of #CRLayEng. - *@param a_cascade the cascade from which the request is to be made. - *@param a_node the xml node to match - *@param a_parent_style the style of the parent xml node. - *@param a_style out parameter. a pointer to the style - *structure to be returned. *a_style must be set to NULL, otherwise - *a CR_BAD_PARAM_ERROR is returned. The caller must free the - *the returned *a_style using cr_style_destroy(). - *@return CR_OK upon successfull completion, an error code otherwise. - */ -enum CRStatus -cr_lay_eng_get_matched_style (CRLayEng *a_this, - CRCascade *a_cascade, - xmlNode *a_node, - CRStyle *a_parent_style, - CRStyle **a_style) -{ - CRStatement **rulesets = NULL ; - CRStyleSheet *author_sheet = NULL ; - gulong len = 0 ; - CRStyle *result_style = NULL ; - CRSelEng * sel_eng = NULL ; - enum CRStatus status = CR_OK ; - - g_return_val_if_fail (a_this && a_cascade - && a_node && a_style - && (*a_style == NULL), - CR_BAD_PARAM_ERROR) ; - - author_sheet = cr_cascade_get_sheet (a_cascade, - ORIGIN_AUTHOR) ; - if (!author_sheet) - { - cr_utils_trace_info ("Could not get author sheet " - "from cascade") ; - return CR_ERROR ; - } - - sel_eng = cr_sel_eng_new () ; - if (!sel_eng) - { - cr_utils_trace_info ("Failed to instanciate " - "The Selection Engine") ; - return CR_ERROR ; - } - - status = cr_sel_eng_get_matched_rulesets (sel_eng, author_sheet, - a_node, &rulesets, - &len) ; - if (len && rulesets[len - 1]) - { - status = cr_style_new_from_ruleset - (rulesets[len - 1], a_parent_style, - &result_style) ; - - } - - if (result_style) - { - *a_style = result_style ; - result_style = NULL ; - } - - if (rulesets) - { - g_free (rulesets) ; - rulesets = NULL ; - } - -/* cleanup:*/ - - if (sel_eng) - { - cr_sel_eng_destroy (sel_eng) ; - sel_eng = NULL ; - } - - return status ; -} /** *Recursively computes the sizes and positions of each diff --git a/src/layeng/cr-lay-eng.h b/src/layeng/cr-lay-eng.h index 8108427..47fef34 100644 --- a/src/layeng/cr-lay-eng.h +++ b/src/layeng/cr-lay-eng.h @@ -55,12 +55,7 @@ cr_lay_eng_init (glong a_argc, gchar ** a_argv) ; CRLayEng * cr_lay_eng_new (void) ; -enum CRStatus -cr_lay_eng_get_matched_style (CRLayEng *a_this, - CRCascade *a_cascade, - xmlNode *a_node, - CRStyle *a_parent_style, - CRStyle **a_style) ; + enum CRStatus cr_lay_eng_create_box_model (CRLayEng *a_this, xmlDoc *a_xml_doc, diff --git a/src/libcroco.h b/src/libcroco.h index 46a978b..fe12e23 100644 --- a/src/libcroco.h +++ b/src/libcroco.h @@ -40,10 +40,10 @@ #ifdef CROCO_SELENG_ENABLED /*The selection engine headers*/ #include "seleng/cr-sel-eng.h" +#include "seleng/cr-style.h" #endif /*CROCO_SELENG_ENABLED*/ #ifdef CROCO_LAYENG_ENABLED /*the layout engine headers*/ -#include "layeng/cr-style.h" #include "layeng/cr-box.h" #include "layeng/cr-box-view.h" #include "layeng/cr-lay-eng.h" diff --git a/src/parser/cr-cascade.c b/src/parser/cr-cascade.c index fcc2091..c62998e 100644 --- a/src/parser/cr-cascade.c +++ b/src/parser/cr-cascade.c @@ -73,7 +73,7 @@ cr_cascade_new (CRStyleSheet *a_author_sheet, } memset (result, 0, sizeof (CRCascade)) ; - PRIVATE (result) = g_try_malloc (sizeof (CRCascade)) ; + PRIVATE (result) = g_try_malloc (sizeof (CRCascadePriv)) ; if (!PRIVATE (result)) { cr_utils_trace_info ("Out of memory") ; @@ -83,19 +83,18 @@ cr_cascade_new (CRStyleSheet *a_author_sheet, if (a_author_sheet) { - PRIVATE (result)->sheets[ORIGIN_AUTHOR] = - a_author_sheet ; - cr_stylesheet_ref (a_author_sheet) ; + cr_cascade_set_sheet (result, a_author_sheet, + ORIGIN_AUTHOR) ; } if (a_user_sheet) { - PRIVATE (result)->sheets[ORIGIN_USER] = a_user_sheet ; - cr_stylesheet_ref (a_user_sheet) ; + cr_cascade_set_sheet (result, a_user_sheet, + ORIGIN_USER) ; } if (a_ua_sheet) { - PRIVATE (result)->sheets[ORIGIN_UA] = a_ua_sheet ; - cr_stylesheet_ref (a_ua_sheet) ; + cr_cascade_set_sheet (result, a_user_sheet, + ORIGIN_UA) ; } return result ; @@ -120,7 +119,7 @@ cr_cascade_get_sheet (CRCascade *a_this, { g_return_val_if_fail (a_this && a_origin >= ORIGIN_AUTHOR - && a_origin < ORIGIN_END, + && a_origin < NB_ORIGINS, NULL) ; return PRIVATE (a_this)->sheets[a_origin] ; @@ -143,7 +142,7 @@ cr_cascade_set_sheet (CRCascade *a_this, g_return_val_if_fail (a_this && a_sheet && a_origin >= ORIGIN_AUTHOR - && a_origin < ORIGIN_END, + && a_origin < NB_ORIGINS, CR_BAD_PARAM_ERROR) ; if (PRIVATE (a_this)->sheets[a_origin]) @@ -151,7 +150,7 @@ cr_cascade_set_sheet (CRCascade *a_this, (PRIVATE (a_this)->sheets[a_origin]) ; PRIVATE (a_this)->sheets[a_origin] = a_sheet ; cr_stylesheet_ref (a_sheet) ; - + a_sheet->origin = a_origin ; return CR_OK ; } @@ -170,7 +169,7 @@ cr_cascade_destroy (CRCascade *a_this) for (i = 0 ; PRIVATE (a_this)->sheets - && i < ORIGIN_END ; + && i < NB_ORIGINS ; i++) { if (PRIVATE (a_this)->sheets[i]) diff --git a/src/parser/cr-cascade.h b/src/parser/cr-cascade.h index bc228c2..f139721 100644 --- a/src/parser/cr-cascade.h +++ b/src/parser/cr-cascade.h @@ -39,19 +39,6 @@ G_BEGIN_DECLS -enum CRStyleOrigin -{ - /*Please don't change the order of - *the values enumerated here ... - *New values should be added at the end, - *just before ORIGIN_END. - */ - ORIGIN_AUTHOR = 0, - ORIGIN_USER , - ORIGIN_UA, - ORIGIN_END /*must always be the last one*/ -} ; - typedef struct _CRCascadePriv CRCascadePriv ; /** diff --git a/src/parser/cr-declaration.c b/src/parser/cr-declaration.c index 9081024..3f822d6 100644 --- a/src/parser/cr-declaration.c +++ b/src/parser/cr-declaration.c @@ -26,6 +26,7 @@ #include <string.h> #include "cr-declaration.h" +#include "cr-statement.h" /** *@file @@ -107,10 +108,21 @@ dump (CRDeclaration *a_this, FILE *a_fp, glong a_indent) *case of error. */ CRDeclaration * -cr_declaration_new (GString *a_property, CRTerm *a_value) +cr_declaration_new (CRStatement *a_statement, + GString *a_property, + CRTerm *a_value) { CRDeclaration *result = NULL ; + g_return_val_if_fail (a_statement + && ((a_statement->type + == RULESET_STMT) + || (a_statement->type + == AT_FONT_FACE_RULE_STMT) + || (a_statement->type + == AT_PAGE_RULE_STMT)), + NULL) ; + result = g_try_malloc (sizeof (CRDeclaration)) ; if (!result) { @@ -125,7 +137,7 @@ cr_declaration_new (GString *a_property, CRTerm *a_value) { cr_term_ref (a_value) ; } - + result->parent_statement = a_statement ; return result ; } @@ -187,12 +199,23 @@ cr_declaration_prepend (CRDeclaration *a_this, CRDeclaration *a_new) *case of an error. */ CRDeclaration * -cr_declaration_append2 (CRDeclaration *a_this, GString *a_prop, +cr_declaration_append2 (CRDeclaration *a_this, + GString *a_prop, CRTerm *a_value) { CRDeclaration *new_elem = NULL ; - new_elem = cr_declaration_new (a_prop, a_value) ; + g_return_val_if_fail (a_this && a_this->parent_statement + && ((a_this->parent_statement->type + == RULESET_STMT) + || (a_this->parent_statement->type + == AT_FONT_FACE_RULE_STMT) + || (a_this->parent_statement->type + == AT_PAGE_RULE_STMT)), + NULL) ; + + new_elem = cr_declaration_new (a_this->parent_statement, + a_prop, a_value) ; g_return_val_if_fail (new_elem, NULL) ; return cr_declaration_append (a_this, new_elem) ; diff --git a/src/parser/cr-declaration.h b/src/parser/cr-declaration.h index 460e154..ff512a0 100644 --- a/src/parser/cr-declaration.h +++ b/src/parser/cr-declaration.h @@ -38,9 +38,13 @@ G_BEGIN_DECLS *The declaration of the #CRDeclaration class. */ +/*forward declaration of what is defined in cr-statement.h*/ +typedef struct _CRStatement CRStatement ; + /** *The abstraction of a css declaration defined by the *css2 spec in chapter 4. + *It is actually a chained list of property/value pairs. */ typedef struct _CRDeclaration CRDeclaration ; struct _CRDeclaration @@ -51,14 +55,23 @@ struct _CRDeclaration /**The value of the property.*/ CRTerm *value ; + /*the ruleset that contains this declaration*/ + CRStatement *parent_statement ; + + /*the next declaration*/ CRDeclaration *next ; + + /*the previous one declaration*/ CRDeclaration *prev ; + glong ref_count ; } ; CRDeclaration * -cr_declaration_new (GString *a_property, CRTerm *a_value) ; +cr_declaration_new (CRStatement *a_statement, + GString *a_property, + CRTerm *a_value) ; CRDeclaration * cr_declaration_append (CRDeclaration *a_this, CRDeclaration *a_new) ; diff --git a/src/parser/cr-om-parser.c b/src/parser/cr-om-parser.c index 57bf8bc..86f3b9f 100644 --- a/src/parser/cr-om-parser.c +++ b/src/parser/cr-om-parser.c @@ -237,7 +237,10 @@ start_font_face (CRDocHandler *a_this) ctxt = a_this->context ; g_return_if_fail (ctxt->cur_stmt == NULL) ; - ctxt->cur_stmt = cr_statement_new_at_font_face_rule (NULL) ; + ctxt->cur_stmt = + cr_statement_new_at_font_face_rule + (ctxt->stylesheet, NULL) ; + g_return_if_fail (ctxt->cur_stmt) ; } @@ -325,7 +328,8 @@ charset (CRDocHandler *a_this, GString *a_charset) charset = g_string_new_len (a_charset->str, a_charset->len) ; - stmt = cr_statement_new_at_charset_rule (charset) ; + stmt = cr_statement_new_at_charset_rule + (ctxt->stylesheet, charset) ; g_return_if_fail (stmt) ; stmt2 = cr_statement_append (ctxt->stylesheet->statements, @@ -359,7 +363,8 @@ start_page (CRDocHandler *a_this, GString *a_page, ctxt = a_this->context ; g_return_if_fail (ctxt->cur_stmt == NULL) ; - ctxt->cur_stmt = cr_statement_new_at_page_rule (NULL, NULL, NULL) ; + ctxt->cur_stmt = cr_statement_new_at_page_rule + (ctxt->stylesheet, NULL, NULL, NULL) ; if (a_page) { @@ -459,7 +464,8 @@ start_media (CRDocHandler *a_this, GList *a_media_list) } ctxt->cur_media_stmt = - cr_statement_new_at_media_rule (NULL, media_list) ; + cr_statement_new_at_media_rule + (ctxt->stylesheet, NULL, media_list) ; } @@ -521,9 +527,8 @@ import_style (CRDocHandler *a_this, GList *a_media_list, } } - stmt = cr_statement_new_at_import_rule (uri, - media_list, - NULL) ; + stmt = cr_statement_new_at_import_rule + (ctxt->stylesheet, uri, media_list, NULL) ; if (!stmt) goto error ; @@ -579,7 +584,7 @@ start_selector (CRDocHandler *a_this, } ctxt->cur_stmt =cr_statement_new_ruleset - (a_selector_list,NULL, NULL) ; + (ctxt->stylesheet, a_selector_list,NULL, NULL) ; } @@ -672,7 +677,8 @@ property (CRDocHandler *a_this, } /*instanciates a new declaration*/ - decl = cr_declaration_new (str, a_expression) ; + decl = cr_declaration_new (ctxt->cur_stmt, + str, a_expression) ; g_return_if_fail (decl) ; str = NULL ; diff --git a/src/parser/cr-statement.c b/src/parser/cr-statement.c index eddfa40..c461d36 100644 --- a/src/parser/cr-statement.c +++ b/src/parser/cr-statement.c @@ -450,12 +450,15 @@ cr_statement_dump_import_rule (CRStatement *a_this, FILE *a_fp, *went wrong. */ CRStatement* -cr_statement_new_ruleset (CRSelector *a_sel_list, +cr_statement_new_ruleset (CRStyleSheet * a_sheet, + CRSelector *a_sel_list, CRDeclaration *a_decl_list, CRAtMediaRule *a_media_rule) { CRStatement *result = NULL ; + g_return_val_if_fail (a_sheet, NULL) ; + result = g_try_malloc (sizeof (CRStatement)) ; if (!result) @@ -482,6 +485,8 @@ cr_statement_new_ruleset (CRSelector *a_sel_list, result->kind.ruleset->decl_list = a_decl_list; result->kind.ruleset->media_rule = a_media_rule; + cr_statement_set_parent_sheet (result, a_sheet) ; + return result ; } @@ -493,11 +498,14 @@ cr_statement_new_ruleset (CRSelector *a_sel_list, *@param a_media, the media string list. A list of GString pointers. */ CRStatement * -cr_statement_new_at_media_rule (CRStatement *a_rulesets, +cr_statement_new_at_media_rule (CRStyleSheet *a_sheet, + CRStatement *a_rulesets, GList *a_media) { CRStatement *result = NULL ; - + + g_return_val_if_fail (a_sheet, NULL) ; + if (a_rulesets) g_return_val_if_fail (a_rulesets->type == RULESET_STMT, NULL) ; @@ -523,6 +531,8 @@ cr_statement_new_at_media_rule (CRStatement *a_rulesets, memset (result->kind.media_rule, 0, sizeof (CRAtMediaRule)) ; result->kind.media_rule->rulesets = a_rulesets ; result->kind.media_rule->media_list = a_media ; + cr_statement_set_parent_sheet (result, a_sheet) ; + return result ; } @@ -536,12 +546,15 @@ cr_statement_new_at_media_rule (CRStatement *a_rulesets, *@return the newly built instance of #CRStatement. */ CRStatement* -cr_statement_new_at_import_rule (GString *a_url, +cr_statement_new_at_import_rule (CRStyleSheet *a_container_sheet, + GString *a_url, GList *a_media_list, - CRStyleSheet *a_sheet) + CRStyleSheet *a_imported_sheet) { CRStatement *result = NULL ; + g_return_val_if_fail (a_container_sheet, NULL) ; + result = g_try_malloc (sizeof (CRStatement)) ; if (!result) @@ -566,7 +579,8 @@ cr_statement_new_at_import_rule (GString *a_url, memset (result->kind.import_rule, 0, sizeof (CRAtImportRule)) ; result->kind.import_rule->url = a_url; result->kind.import_rule->media_list = a_media_list ; - result->kind.import_rule->sheet = a_sheet; + result->kind.import_rule->sheet = a_imported_sheet; + cr_statement_set_parent_sheet (result, a_container_sheet) ; return result ; } @@ -582,12 +596,15 @@ cr_statement_new_at_import_rule (GString *a_url, *in case of error. */ CRStatement * -cr_statement_new_at_page_rule (CRDeclaration *a_decl_list, +cr_statement_new_at_page_rule (CRStyleSheet *a_sheet, + CRDeclaration *a_decl_list, GString *a_name, GString *a_pseudo) { CRStatement *result = NULL ; + g_return_val_if_fail (a_sheet, NULL) ; + result = g_try_malloc (sizeof (CRStatement)) ; if (!result) @@ -612,6 +629,8 @@ cr_statement_new_at_page_rule (CRDeclaration *a_decl_list, result->kind.page_rule->decls_list = a_decl_list; result->kind.page_rule->name = a_name ; result->kind.page_rule->name = a_pseudo ; + cr_statement_set_parent_sheet (result, a_sheet) ; + return result ; } @@ -623,10 +642,13 @@ cr_statement_new_at_page_rule (CRDeclaration *a_decl_list, *if an error arises. */ CRStatement * -cr_statement_new_at_charset_rule (GString *a_charset) +cr_statement_new_at_charset_rule (CRStyleSheet *a_sheet, + GString *a_charset) { CRStatement * result = NULL ; + g_return_val_if_fail (a_sheet, NULL) ; + result = g_try_malloc (sizeof (CRStatement)) ; if (!result) @@ -649,6 +671,7 @@ cr_statement_new_at_charset_rule (GString *a_charset) } memset (result->kind.charset_rule, 0, sizeof (CRAtCharsetRule)) ; result->kind.charset_rule->charset = a_charset ; + cr_statement_set_parent_sheet (result, a_sheet) ; return result ; } @@ -660,11 +683,15 @@ cr_statement_new_at_charset_rule (GString *a_charset) *@return the newly built instance of #CRStatement. */ CRStatement * -cr_statement_new_at_font_face_rule (CRDeclaration *a_font_decls) +cr_statement_new_at_font_face_rule (CRStyleSheet *a_sheet, + CRDeclaration *a_font_decls) { CRStatement *result = NULL ; + g_return_val_if_fail (a_sheet, NULL) ; + result = g_try_malloc (sizeof (CRStatement)) ; + if (!result) { cr_utils_trace_info ("Out of memory") ; @@ -686,11 +713,43 @@ cr_statement_new_at_font_face_rule (CRDeclaration *a_font_decls) sizeof (CRAtFontFaceRule)); result->kind.font_face_rule->decls_list = a_font_decls ; + cr_statement_set_parent_sheet (result, a_sheet) ; return result ; } /** + *Sets the container stylesheet. + *@param a_this the current instance of #CRStatement. + *@param a_sheet the sheet that contains the current statement. + *@return CR_OK upon successfull completion, an errror code otherwise. + */ +enum CRStatus +cr_statement_set_parent_sheet (CRStatement *a_this, + CRStyleSheet *a_sheet) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + a_this->parent_sheet = a_sheet ; + return CR_OK ; +} + +/** + *Gets the sheets that contains the current statement. + *@param a_this the current #CRStatement. + *@param a_sheet out parameter. A pointer to the sheets that + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_statement_get_parent_sheet (CRStatement *a_this, + CRStyleSheet **a_sheet) +{ + g_return_val_if_fail (a_this && a_sheet, + CR_BAD_PARAM_ERROR) ; + *a_sheet = a_this->parent_sheet ; + return CR_OK ; +} + +/** *Appends a new statement to the statement list. *@param a_this the current instance of the statement list. *@param a_this a_new the new instance of #CRStatement to append. @@ -915,8 +974,8 @@ cr_statement_ruleset_append_decl (CRStatement *a_this, *@return CR_OK upon successfull completion, an error code otherwise. */ enum CRStatus -cr_statement_at_import_rule_set_sheet (CRStatement *a_this, - CRStyleSheet *a_sheet) +cr_statement_at_import_rule_set_imported_sheet (CRStatement *a_this, + CRStyleSheet *a_sheet) { g_return_val_if_fail (a_this && a_this->type == AT_IMPORT_RULE_STMT @@ -937,16 +996,14 @@ cr_statement_at_import_rule_set_sheet (CRStatement *a_this, *@return CR_OK upon sucessfull completion, an error code otherwise. */ enum CRStatus -cr_statement_at_import_rule_get_sheet (CRStatement *a_this, - CRStyleSheet **a_sheet) +cr_statement_at_import_rule_get_imported_sheet (CRStatement *a_this, + CRStyleSheet **a_sheet) { g_return_val_if_fail (a_this && a_this->type == AT_IMPORT_RULE_STMT && a_this->kind.import_rule, CR_BAD_PARAM_ERROR) ; - *a_sheet = a_this->kind.import_rule->sheet ; - return CR_OK ; } diff --git a/src/parser/cr-statement.h b/src/parser/cr-statement.h index eda2371..9cbabd1 100644 --- a/src/parser/cr-statement.h +++ b/src/parser/cr-statement.h @@ -40,8 +40,18 @@ G_BEGIN_DECLS *Declaration of the #CRStatement class. */ +/* + *forward declaration of CRStyleSheet which is defined in + *cr-stylesheet.h + */ + struct _CRStatement ; -typedef struct _CRStatement CRStatement ; + +/* + *typedef struct _CRStatement CRStatement ; + *this is forward declared in + *cr-declaration.h already. + */ struct _CRAtMediaRule ; typedef struct _CRAtMediaRule CRAtMediaRule ; @@ -186,6 +196,11 @@ struct _CRStatement CRAtFontFaceRule *font_face_rule ; } kind ; + /* + *the style sheet that contains + *this css statement. + */ + CRStyleSheet *parent_sheet ; CRStatement *next ; CRStatement *prev ; @@ -204,33 +219,48 @@ struct _CRStatement *pointer. */ gpointer *croco_data ; + } ; CRStatement* -cr_statement_new_ruleset (CRSelector *a_sel_list, +cr_statement_new_ruleset (CRStyleSheet *a_sheet, + CRSelector *a_sel_list, CRDeclaration *a_decl_list, CRAtMediaRule *a_media_rule) ; CRStatement* -cr_statement_new_at_import_rule (GString *a_url, +cr_statement_new_at_import_rule (CRStyleSheet *a_container_sheet, + GString *a_url, GList *a_media_list, - CRStyleSheet *a_sheet) ; + CRStyleSheet *a_imported_sheet) ; CRStatement * -cr_statement_new_at_media_rule (CRStatement *a_ruleset, +cr_statement_new_at_media_rule (CRStyleSheet *a_sheet, + CRStatement *a_ruleset, GList *a_media) ; CRStatement * -cr_statement_new_at_charset_rule (GString *a_charset) ; +cr_statement_new_at_charset_rule (CRStyleSheet *a_sheet, + GString *a_charset) ; CRStatement * -cr_statement_new_at_font_face_rule (CRDeclaration *a_font_decls) ; +cr_statement_new_at_font_face_rule (CRStyleSheet *a_sheet, + CRDeclaration *a_font_decls) ; CRStatement * -cr_statement_new_at_page_rule (CRDeclaration *a_decl_list, +cr_statement_new_at_page_rule (CRStyleSheet *a_sheet, + CRDeclaration *a_decl_list, GString *a_name, GString *a_pseudo) ; +enum CRStatus +cr_statement_set_parent_sheet (CRStatement *a_this, + CRStyleSheet *a_sheet) ; + +enum CRStatus +cr_statement_get_parent_sheet (CRStatement *a_this, + CRStyleSheet **a_sheet) ; + CRStatement * cr_statement_append (CRStatement *a_this, CRStatement *a_new) ; @@ -264,12 +294,12 @@ cr_statement_ruleset_append_decl (CRStatement *a_this, CRDeclaration *a_decl) ; enum CRStatus -cr_statement_at_import_rule_set_sheet (CRStatement *a_this, - CRStyleSheet *a_sheet) ; +cr_statement_at_import_rule_set_imported_sheet (CRStatement *a_this, + CRStyleSheet *a_sheet) ; enum CRStatus -cr_statement_at_import_rule_get_sheet (CRStatement *a_this, - CRStyleSheet **a_sheet) ; +cr_statement_at_import_rule_get_imported_sheet (CRStatement *a_this, + CRStyleSheet **a_sheet) ; enum CRStatus cr_statement_at_import_rule_set_url (CRStatement *a_this, diff --git a/src/parser/cr-stylesheet.h b/src/parser/cr-stylesheet.h index a19c04c..3dca4e6 100644 --- a/src/parser/cr-stylesheet.h +++ b/src/parser/cr-stylesheet.h @@ -35,6 +35,22 @@ *The declaration of the #CRStyleSheet class. */ + +enum CRStyleOrigin +{ + /*Please don't change the order of + *the values enumerated here ... + *New values should be added at the end, + *just before ORIGIN_END. + */ + ORIGIN_UA = 0, + ORIGIN_USER, + ORIGIN_AUTHOR, + + /*must always be the last one*/ + NB_ORIGINS +} ; + /** *An abstraction of a css stylesheet as defined *by the css2 spec in chapter 4. @@ -44,6 +60,11 @@ struct _CRStyleSheet /**The css statements list*/ CRStatement *statements ; + enum CRStyleOrigin origin ; + + /*the parent import rule, if any.*/ + CRStatement *parent_import_rule ; + /**custom data used by libcroco*/ void *croco_data ; diff --git a/src/seleng/Makefile.am b/src/seleng/Makefile.am index b8c04e8..be3a453 100644 --- a/src/seleng/Makefile.am +++ b/src/seleng/Makefile.am @@ -5,7 +5,7 @@ crselenginc_HEADERS= *.h #the selection engine files if HAVE_SELENG -SELENG_SRCS= cr-sel-eng.c +SELENG_SRCS= cr-style.c cr-sel-eng.c endif libcrseleng_la_SOURCES=$(SELENG_SRCS) diff --git a/src/seleng/cr-sel-eng.c b/src/seleng/cr-sel-eng.c index 9fd4777..1174fcf 100644 --- a/src/seleng/cr-sel-eng.c +++ b/src/seleng/cr-sel-eng.c @@ -58,6 +58,11 @@ cr_sel_eng_get_matched_rulesets_real (CRSelEng *a_this, xmlNode *a_node, CRStatement **a_rulesets, gulong *a_len) ; + +static enum CRStatus +put_css_properties_in_hashtable (GHashTable **a_props_hashtable, + CRStatement *a_ruleset) ; + struct _CRSelEngPriv { /*not used yet*/ @@ -701,7 +706,87 @@ cr_sel_eng_get_matched_rulesets_real (CRSelEng *a_this, return CR_OK ; } +/** + *Walks through the property/value pairs of a ruleset + *statement and put the properties found into a hashtable. + *Each key of the hashtable is a css property. The + *associated value is a pointer to the current #CRStatement. + * + *@param a_props_hashtable in/out parameter. The hashtable into + *which the the property/statement pairs will be added. + *Note that each hashtable key (a statement property) is a null terminated + *instance of guchar *. + *Each value associated to a key is an instance of #CRStatement. The statement + *is actually the css ruleset that contains the property (the key). + *@param a_ruleset the ruleset from wich the properties are gathered. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +static enum CRStatus +put_css_properties_in_hashtable (GHashTable **a_props_hashtable, + CRStatement *a_ruleset) +{ + CRStatement *cur_stmt = NULL ; + GHashTable *props_hash = NULL ; + + g_return_val_if_fail (a_props_hashtable && a_ruleset + && a_ruleset->type == RULESET_STMT, + CR_BAD_PARAM_ERROR) ; + + if (!*a_props_hashtable) + { + *a_props_hashtable = g_hash_table_new (g_str_hash, + g_str_equal) ; + } + props_hash = *a_props_hashtable ; + for (cur_stmt = a_ruleset ; cur_stmt ; cur_stmt = cur_stmt->next) + { + CRDeclaration *cur_decl = NULL ; + + if (cur_stmt->type != RULESET_STMT + || !cur_stmt->kind.ruleset) + continue ; + + for (cur_decl = cur_stmt->kind.ruleset->decl_list ; + cur_decl ; cur_decl = cur_decl->next) + { + if (cur_decl->property && cur_decl->property->str) + { + GString *prop = NULL ; + gboolean insert_property = FALSE ; + + /* + *First, test if the property is not + *already present in our properties hashtable. + *If yes, apply the cascading rules to + *compute the precedence. If not, insert + *the property into the hashtable. + */ + prop = g_hash_table_lookup + (props_hash, cur_decl->property->str) ; + + if (prop) + { + /* + *the property already exists. + *TODO: We must apply here some cascading rule + *to compute the precedence. + */ + + } + + + if (insert_property == TRUE) + g_hash_table_replace + (props_hash, + cur_decl->property, + a_ruleset) ; + } + } + } + + return CR_OK ; +} /** *Creates a new instance of #CRSelEng. @@ -791,7 +876,7 @@ cr_sel_eng_get_matched_rulesets (CRSelEng *a_this, { CRStatement ** stmts_tab = NULL ; enum CRStatus status = CR_OK ; - gulong tab_size = 0, tab_len = 0 ; + gulong tab_size = 0, tab_len = 0, index = 0 ; gushort stmts_chunck_size = 8 ; g_return_val_if_fail (a_this @@ -816,10 +901,9 @@ cr_sel_eng_get_matched_rulesets (CRSelEng *a_this, tab_len = tab_size ; while ((status = cr_sel_eng_get_matched_rulesets_real - (a_this, a_sheet, a_node, stmts_tab, &tab_len)) + (a_this, a_sheet, a_node, stmts_tab + index, &tab_len)) == CR_OUTPUT_TOO_SHORT_ERROR) { - tab_size += tab_len ; stmts_tab = g_try_realloc (stmts_tab, (tab_size + stmts_chunck_size) * sizeof (CRStatement*)) ; @@ -829,8 +913,12 @@ cr_sel_eng_get_matched_rulesets (CRSelEng *a_this, status = CR_ERROR ; goto error ; } + tab_size += stmts_chunck_size ; + index += tab_len ; + tab_len = tab_size - index ; } + tab_len = tab_size - stmts_chunck_size +tab_len ; *a_rulesets = stmts_tab ; *a_len = tab_len ; @@ -850,7 +938,183 @@ cr_sel_eng_get_matched_rulesets (CRSelEng *a_this, return status ; } +enum CRStatus +cr_sel_eng_get_matched_rulesets_from_cascade (CRSelEng *a_this, + CRCascade *a_cascade, + xmlNode *a_node, + GHashTable **a_props_hashtable) +{ + CRStatement ** stmts_tab = NULL ; + enum CRStatus status = CR_OK ; + gulong tab_size = 0, tab_len = 0, index = 0, i = 0 ; + enum CRStyleOrigin origin = 0 ; + gushort stmts_chunck_size = 8 ; + CRStyleSheet *sheet = NULL ; + + g_return_val_if_fail (a_this + && a_cascade + && a_node + && a_props_hashtable, + CR_BAD_PARAM_ERROR) ; + + stmts_tab = g_try_malloc (stmts_chunck_size * + sizeof (CRStatement *)) ; + + if (!stmts_tab) + { + cr_utils_trace_info ("Out of memory") ; + status = CR_ERROR ; + goto error ; + } + memset (stmts_tab, 0, stmts_chunck_size * sizeof (CRStatement*)) ; + tab_size = stmts_chunck_size ; + tab_len = tab_size ; + + for (origin = ORIGIN_UA ; origin < NB_ORIGINS ; origin++) + { + sheet = cr_cascade_get_sheet (a_cascade, origin) ; + if (!sheet) + continue ; + + while ((status = cr_sel_eng_get_matched_rulesets_real + (a_this, sheet, a_node, stmts_tab + index, &tab_len)) + == CR_OUTPUT_TOO_SHORT_ERROR) + { + stmts_tab = g_try_realloc + (stmts_tab, + (tab_size + stmts_chunck_size) + * sizeof (CRStatement*)) ; + if (!stmts_tab) + { + cr_utils_trace_info ("Out of memory") ; + status = CR_ERROR ; + goto error ; + } + tab_size += stmts_chunck_size ; + index += tab_len ; + tab_len = tab_size - index ; + } + if (status != CR_OK) + { + cr_utils_trace_info ("Error while running " + "selector engine") ; + goto error ; + } + + } + + /* + *TODO, walk down the stmts_tab and build the + *property_name/declaration hashtable. + *Make sure one can walk from the declaration to + *the stylesheet. + */ + for (i = 0 ; i < tab_len ; i ++) + { + CRStatement *stmt = stmts_tab[i] ; + + if (!stmt) + continue ; + + switch (stmt->type) + { + case RULESET_STMT: + if (!stmt->parent_sheet) + continue ; + put_css_properties_in_hashtable + (a_props_hashtable, + stmt) ; + break ; + + default: + break ; + } + + } + + return CR_OK ; + error: + + if (stmts_tab) + { + g_free (stmts_tab) ; + stmts_tab = NULL ; + + } + + return status ; +} + +/** + *Retrieves the style structure that matches the xml node + *from the cascade. + *NOTE: this does not implement the complex cascade algorithms + *described in the css2 spec from chapter 6.4 on, but instead, + *is just an empty design sketch so that other hackers (yeah, we can dream) + *can come an implement it. I don't have the time for this right now. + *@param a_this the current instance of #CRLayEng. + *@param a_cascade the cascade from which the request is to be made. + *@param a_node the xml node to match + *@param a_parent_style the style of the parent xml node. + *@param a_style out parameter. a pointer to the style + *structure to be returned. *a_style must be set to NULL, otherwise + *a CR_BAD_PARAM_ERROR is returned. The caller must free the + *the returned *a_style using cr_style_destroy(). + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_sel_eng_get_matched_style (CRSelEng *a_this, + CRCascade *a_cascade, + xmlNode *a_node, + CRStyle *a_parent_style, + CRStyle **a_style) +{ + CRStatement **rulesets = NULL ; + CRStyleSheet *author_sheet = NULL ; + gulong len = 0 ; + CRStyle *result_style = NULL ; + enum CRStatus status = CR_OK ; + + g_return_val_if_fail (a_this && a_cascade + && a_node && a_style + && (*a_style == NULL), + CR_BAD_PARAM_ERROR) ; + + author_sheet = cr_cascade_get_sheet (a_cascade, + ORIGIN_AUTHOR) ; + if (!author_sheet) + { + cr_utils_trace_info ("Could not get author sheet " + "from cascade") ; + return CR_ERROR ; + } + + status = cr_sel_eng_get_matched_rulesets + (a_this, author_sheet, + a_node, &rulesets, &len) ; + + if (len && rulesets[len - 1]) + { + status = cr_style_new_from_ruleset + (rulesets[len - 1], a_parent_style, + &result_style) ; + + } + if (result_style) + { + *a_style = result_style ; + result_style = NULL ; + } + + if (rulesets) + { + g_free (rulesets) ; + rulesets = NULL ; + } + + return status ; +} /** *The destructor of #CRSelEng diff --git a/src/seleng/cr-sel-eng.h b/src/seleng/cr-sel-eng.h index a132707..e1b7508 100644 --- a/src/seleng/cr-sel-eng.h +++ b/src/seleng/cr-sel-eng.h @@ -26,7 +26,7 @@ #include "cr-utils.h" #include "cr-stylesheet.h" #include "cr-cascade.h" - +#include "cr-style.h" #ifdef CROCO_HAVE_LIBXML2 #include <libxml/tree.h> @@ -73,6 +73,19 @@ cr_sel_eng_get_matched_rulesets (CRSelEng *a_this, CRStatement ***a_rulesets, gulong *a_len) ; +enum CRStatus +cr_sel_eng_get_matched_rulesets_from_cascade (CRSelEng *a_this, + CRCascade *a_cascade, + xmlNode *a_node, + GHashTable **props_decls_dict) ; + +enum CRStatus +cr_sel_eng_get_matched_style (CRSelEng *a_this, + CRCascade *a_cascade, + xmlNode *a_node, + CRStyle *a_parent_style, + CRStyle **a_style) ; + void cr_sel_eng_destroy (CRSelEng *a_this) ; |