hippo-canvas r7286 - trunk/common/hippo



Author: otaylor
Date: Fri Jun 27 23:32:50 2008
New Revision: 7286
URL: http://svn.gnome.org/viewvc/hippo-canvas?rev=7286&view=rev

Log:
Add support for @import url("some-stylesheet.css");


Modified:
   trunk/common/hippo/hippo-canvas-style.c
   trunk/common/hippo/hippo-canvas-theme-internal.h
   trunk/common/hippo/hippo-canvas-theme.c

Modified: trunk/common/hippo/hippo-canvas-style.c
==============================================================================
--- trunk/common/hippo/hippo-canvas-style.c	(original)
+++ trunk/common/hippo/hippo-canvas-style.c	Fri Jun 27 23:32:50 2008
@@ -1470,7 +1470,7 @@
                 break; 
             }
 
-            filename = _hippo_canvas_theme_resolve_url(style->theme, decl, url);
+            filename = _hippo_canvas_theme_resolve_url(style->theme, decl->parent_statement->parent_sheet, url);
             if (filename == NULL)
                 goto next_property;
             

Modified: trunk/common/hippo/hippo-canvas-theme-internal.h
==============================================================================
--- trunk/common/hippo/hippo-canvas-theme-internal.h	(original)
+++ trunk/common/hippo/hippo-canvas-theme-internal.h	Fri Jun 27 23:32:50 2008
@@ -19,7 +19,7 @@
 
 /* Resolve an URL from the stylesheet to a filename */
 char *_hippo_canvas_theme_resolve_url (HippoCanvasTheme *theme,
-                                       CRDeclaration    *decl,
+                                       CRStyleSheet     *base_stylesheet,
                                        const char       *url);
 
 G_END_DECLS

Modified: trunk/common/hippo/hippo-canvas-theme.c
==============================================================================
--- trunk/common/hippo/hippo-canvas-theme.c	(original)
+++ trunk/common/hippo/hippo-canvas-theme.c	Fri Jun 27 23:32:50 2008
@@ -74,6 +74,9 @@
     char *default_stylesheet;
     char *theme_stylesheet;
 
+    GHashTable *stylesheets_by_filename;
+    GHashTable *filenames_by_stylesheet;
+
     CRCascade *cascade;
 };
 
@@ -99,6 +102,9 @@
 static void
 hippo_canvas_theme_init(HippoCanvasTheme *theme)
 {
+    theme->stylesheets_by_filename = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                                           (GDestroyNotify)g_free, (GDestroyNotify)cr_stylesheet_unref);
+    theme->filenames_by_stylesheet = g_hash_table_new(g_direct_hash, g_direct_equal);
 }
 
 static void
@@ -190,6 +196,23 @@
   return stylesheet;
 }
 
+static void
+insert_stylesheet(HippoCanvasTheme *theme,
+                  const char       *filename,
+                  CRStyleSheet     *stylesheet)
+{
+    char *filename_copy;
+
+  if (stylesheet == NULL)
+      return;
+    
+    filename_copy = g_strdup(filename);
+    cr_stylesheet_ref(stylesheet);
+
+    g_hash_table_insert(theme->stylesheets_by_filename, filename_copy, stylesheet);
+    g_hash_table_insert(theme->filenames_by_stylesheet, stylesheet, filename_copy);
+}
+
 static GObject *
 hippo_canvas_theme_constructor (GType                  type,
                                 guint                  n_construct_properties,
@@ -197,19 +220,30 @@
 {
   GObject *object;
   HippoCanvasTheme *theme;
+  CRStyleSheet *application_stylesheet;
+  CRStyleSheet *theme_stylesheet;
+  CRStyleSheet *default_stylesheet;
 
   object = (*G_OBJECT_CLASS (hippo_canvas_theme_parent_class)->constructor) (type,
                                                                              n_construct_properties,
                                                                              construct_properties);
   theme = HIPPO_CANVAS_THEME (object);
 
-  theme->cascade = cr_cascade_new(parse_stylesheet(theme->application_stylesheet),
-                                  parse_stylesheet(theme->theme_stylesheet),
-                                  parse_stylesheet(theme->default_stylesheet));
+  application_stylesheet = parse_stylesheet(theme->application_stylesheet);
+  theme_stylesheet = parse_stylesheet(theme->theme_stylesheet);
+  default_stylesheet = parse_stylesheet(theme->default_stylesheet);
+
+  theme->cascade = cr_cascade_new(application_stylesheet,
+                                  theme_stylesheet,
+                                  default_stylesheet);
 
   if (theme->cascade == NULL)
       g_error("Out of memory when creating cascade object");
-  
+
+  insert_stylesheet(theme, theme->application_stylesheet, application_stylesheet);
+  insert_stylesheet(theme, theme->theme_stylesheet, theme_stylesheet);
+  insert_stylesheet(theme, theme->default_stylesheet, default_stylesheet);
+
   return object;
 }
 
@@ -228,6 +262,9 @@
 
     if (theme->theme_engine)
         g_object_unref(theme->theme_engine);
+
+    g_hash_table_destroy(theme->stylesheets_by_filename);
+    g_hash_table_destroy(theme->filenames_by_stylesheet);
     
     g_free(theme->application_stylesheet);
     g_free(theme->theme_stylesheet);
@@ -772,7 +809,6 @@
     return CR_OK;
 }
 
-
 static void
 add_matched_properties (HippoCanvasTheme *a_this,
                         CRStyleSheet     *a_stylesheet,
@@ -820,10 +856,39 @@
             break;
             
         case AT_IMPORT_RULE_STMT:
-            /*
-             *some recursivity may be needed here.
-             *I don't like this :(
-             */
+            {
+                CRAtImportRule *import_rule = cur_stmt->kind.import_rule;
+                
+                if (import_rule->sheet == NULL) {
+                    char *filename = NULL;
+                    
+                    if (import_rule->url->stryng && import_rule->url->stryng->str)
+                        filename = _hippo_canvas_theme_resolve_url(a_this,
+                                                                   a_stylesheet,
+                                                                   import_rule->url->stryng->str);
+                    
+                    if (filename)
+                        import_rule->sheet = parse_stylesheet(filename);
+                    
+                    if (import_rule->sheet) {
+                        insert_stylesheet(a_this, filename, import_rule->sheet);
+                        /* refcount of stylesheets starts off at zero, so we don't need to unref! */
+                    } else {
+                        /* Set a marker to avoid repeatedly trying to parse a non-existent or
+                         * broken stylesheet
+                         */
+                        import_rule->sheet = (CRStyleSheet *)-1;
+                    }
+                    
+                    if (filename)
+                        g_free(filename);
+                }
+
+                if (import_rule->sheet != (CRStyleSheet *)-1) {
+                    add_matched_properties(a_this, import_rule->sheet,
+                                           a_style, props);
+                }
+            }
             break;
         default:
             break;
@@ -942,11 +1007,10 @@
  */
 char *
 _hippo_canvas_theme_resolve_url (HippoCanvasTheme *theme,
-                                 CRDeclaration    *decl,
+                                 CRStyleSheet     *base_stylesheet,
                                  const char       *url)
 {
-    enum CRStyleOrigin origin = decl->parent_statement->parent_sheet->origin;
-    const char *stylesheet_filename = NULL;
+    const char *base_filename = NULL;
     char *dirname;
     char *filename;
 
@@ -981,20 +1045,15 @@
      */
     if (url[0] == '/')
         return g_strdup(url);
-    
-    if (origin == ORIGIN_UA)
-        stylesheet_filename = theme->default_stylesheet;
-    else if (origin == ORIGIN_AUTHOR)
-        stylesheet_filename = theme->application_stylesheet;
-    else if (origin == ORIGIN_USER)
-        stylesheet_filename = theme->theme_stylesheet;
 
-    if (stylesheet_filename == NULL) {
+    base_filename = g_hash_table_lookup(theme->filenames_by_stylesheet, base_stylesheet);
+    
+    if (base_filename == NULL) {
         g_warning("Can't get base to resolve url '%s'", url);
         return NULL;
     }
 
-    dirname = g_path_get_dirname(stylesheet_filename);
+    dirname = g_path_get_dirname(base_filename);
     filename = g_build_filename(dirname, url, NULL);
     g_free(dirname);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]