[gtk+/wip/css: 20/154] css: Make CSS resolving work according to spec



commit 8734bb7b5529fcf4dabd42b5d6d47469abe9f856
Author: Benjamin Otte <otte redhat com>
Date:   Thu Dec 29 14:04:33 2011 +0100

    css: Make CSS resolving work according to spec
    
    See inline code comments taken from
      http://dev.w3.org/csswg/css3-cascade/#cascade
    
    This now respects the special values "inherit" and "initial" properly.
    Note that those values cannot be parsed yet. This will be added in a
    future commit.

 gtk/gtkcsslookup.c |   98 ++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 91 insertions(+), 7 deletions(-)
---
diff --git a/gtk/gtkcsslookup.c b/gtk/gtkcsslookup.c
index c5fd148..a3e272d 100644
--- a/gtk/gtkcsslookup.c
+++ b/gtk/gtkcsslookup.c
@@ -21,6 +21,8 @@
 
 #include "gtkcsslookupprivate.h"
 
+#include "gtkcsstypesprivate.h"
+#include "gtkprivatetypebuiltins.h"
 #include "gtkstylepropertyprivate.h"
 #include "gtkstylepropertiesprivate.h"
 
@@ -120,13 +122,95 @@ _gtk_css_lookup_resolve (GtkCssLookup    *lookup,
 
   for (i = 0; i < n; i++)
     {
-      if (lookup->values[i] == NULL)
-        continue;
-
-      _gtk_style_properties_set_property_by_property (props,
-                                                      _gtk_style_property_get (i),
-                                                      0,
-                                                      lookup->values[i]);
+      const GtkStyleProperty *prop = _gtk_style_property_get (i);
+      const GValue *result;
+
+      /* http://www.w3.org/TR/css3-cascade/#cascade
+       * Then, for every element, the value for each property can be found
+       * by following this pseudo-algorithm:
+       * 1) Identify all declarations that apply to the element
+       */
+      if (lookup->values[i] != NULL)
+        {
+          /* 2) If the cascading process (described below) yields a winning
+           * declaration and the value of the winning declaration is not
+           * âinitialâ or âinheritâ, the value of the winning declaration
+           * becomes the specified value.
+           */
+          if (!G_VALUE_HOLDS (lookup->values[i], GTK_TYPE_CSS_SPECIAL_VALUE))
+            {
+              result = lookup->values[i];
+            }
+          else
+            {
+              switch (g_value_get_enum (lookup->values[i]))
+                {
+                case GTK_CSS_INHERIT:
+                  /* 3) if the value of the winning declaration is âinheritâ,
+                   * the inherited value (see below) becomes the specified value.
+                   */
+                  result = NULL;
+                  break;
+                case GTK_CSS_INITIAL:
+                  /* if the value of the winning declaration is âinitialâ,
+                   * the initial value (see below) becomes the specified value.
+                   */
+                  result = _gtk_style_property_get_initial_value (prop);
+                  break;
+                default:
+                  /* This is part of (2) above */
+                  result = lookup->values[i];
+                  break;
+                }
+            }
+        }
+      else
+        {
+          if (_gtk_style_property_is_inherit (prop))
+            {
+              /* 4) if the property is inherited, the inherited value becomes
+               * the specified value.
+               */
+              result = NULL;
+            }
+          else
+            {
+              /* 5) Otherwise, the initial value becomes the specified value.
+               */
+              result = _gtk_style_property_get_initial_value (prop);
+            }
+        }
+
+      if (result)
+        {
+          _gtk_style_properties_set_property_by_property (props,
+                                                          prop,
+                                                          0,
+                                                          result);
+        }
+      else if (parent == NULL)
+        {
+          /* If the âinheritâ value is set on the root element, the property is
+           * assigned its initial value. */
+          _gtk_style_properties_set_property_by_property (props,
+                                                          prop,
+                                                          0,
+                                                          _gtk_style_property_get_initial_value (prop));
+        }
+      else
+        {
+          GValue value = { 0, };
+          /* Set NULL here and do the inheritance upon lookup? */
+          gtk_style_context_get_property (parent,
+                                          prop->pspec->name,
+                                          gtk_style_context_get_state (parent),
+                                          &value);
+          _gtk_style_properties_set_property_by_property (props,
+                                                          prop,
+                                                          0,
+                                                          &value);
+          g_value_unset (&value);
+        }
     }
 
   return props;



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