summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDodji Seketeli <dodji@src.gnome.org>2003-05-20 20:03:34 +0000
committerDodji Seketeli <dodji@src.gnome.org>2003-05-20 20:03:34 +0000
commitcf0f243f7e99156489019360c062a08d824aed22 (patch)
tree8e9ef02d08646e3720c4a78bf2a8ff69ad2abd34 /src
parentf1f4a02b4c33ad19773c3152c9408e2dadcd31d1 (diff)
downloadlibcroco-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.am11
-rw-r--r--src/layeng/cr-box-view.c13
-rw-r--r--src/layeng/cr-lay-eng.c90
-rw-r--r--src/layeng/cr-lay-eng.h7
-rw-r--r--src/libcroco.h2
-rw-r--r--src/parser/cr-cascade.c23
-rw-r--r--src/parser/cr-cascade.h13
-rw-r--r--src/parser/cr-declaration.c31
-rw-r--r--src/parser/cr-declaration.h15
-rw-r--r--src/parser/cr-om-parser.c24
-rw-r--r--src/parser/cr-statement.c87
-rw-r--r--src/parser/cr-statement.h54
-rw-r--r--src/parser/cr-stylesheet.h21
-rw-r--r--src/seleng/Makefile.am2
-rw-r--r--src/seleng/cr-sel-eng.c270
-rw-r--r--src/seleng/cr-sel-eng.h15
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) ;