[gtk+/wip/css: 4/20] css: Add GtkCssMatcher



commit 7dbc6f00113ecd7b54b527cbcb8849135c43b107
Author: Benjamin Otte <otte redhat com>
Date:   Sat Mar 17 02:17:23 2012 +0100

    css: Add GtkCssMatcher
    
    This is so we can later do matching with other things than
    GtkWidgetPath.
    In particular, this is a requirement for getting rid of GtkWidgetPath.

 gtk/Makefile.am            |    2 +
 gtk/gtkcssmatcher.c        |  174 ++++++++++++++++++++++++++++++++++++++++
 gtk/gtkcssmatcherprivate.h |   61 ++++++++++++++
 gtk/gtkcssselector.c       |  188 +++++++++++++++-----------------------------
 4 files changed, 301 insertions(+), 124 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 3aac754..4be4eb4 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -431,6 +431,7 @@ gtk_private_h_sources =		\
 	gtkcssimageurlprivate.h	\
 	gtkcssimagewin32private.h	\
 	gtkcsslookupprivate.h	\
+	gtkcssmatcherprivate.h	\
 	gtkcssparserprivate.h	\
 	gtkcssproviderprivate.h	\
 	gtkcsssectionprivate.h 	\
@@ -627,6 +628,7 @@ gtk_base_c_sources = 		\
 	gtkcssimageurl.c	\
 	gtkcssimagewin32.c	\
 	gtkcsslookup.c		\
+	gtkcssmatcher.c		\
 	gtkcssparser.c		\
 	gtkcssprovider.c	\
 	gtkcsssection.c 	\
diff --git a/gtk/gtkcssmatcher.c b/gtk/gtkcssmatcher.c
new file mode 100644
index 0000000..583b803
--- /dev/null
+++ b/gtk/gtkcssmatcher.c
@@ -0,0 +1,174 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2012 Benjamin Otte <otte gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gtkcssmatcherprivate.h"
+
+#include "gtkwidgetpath.h"
+
+void
+_gtk_css_matcher_init (GtkCssMatcher       *matcher,
+                       const GtkWidgetPath *path,
+                       GtkStateFlags        state)
+{
+  matcher->path = path;
+  matcher->state_flags = state;
+  matcher->index = gtk_widget_path_length (path) - 1;
+  matcher->sibling_index = gtk_widget_path_iter_get_sibling_index (path, matcher->index);
+}
+
+gboolean
+_gtk_css_matcher_get_parent (GtkCssMatcher       *matcher,
+                             const GtkCssMatcher *child)
+{
+  if (child->index == 0)
+    return FALSE;
+
+  matcher->path = child->path;
+  matcher->state_flags = 0;
+  matcher->index = child->index - 1;
+  matcher->sibling_index = gtk_widget_path_iter_get_sibling_index (matcher->path, matcher->index);
+
+  return TRUE;
+}
+
+gboolean
+_gtk_css_matcher_get_previous (GtkCssMatcher       *matcher,
+                               const GtkCssMatcher *next)
+{
+  if (next->sibling_index == 0)
+    return FALSE;
+
+  matcher->path = next->path;
+  matcher->state_flags = 0;
+  matcher->index = next->index;
+  matcher->sibling_index = next->sibling_index - 1;
+
+  return TRUE;
+}
+
+gboolean
+_gtk_css_matcher_has_state (const GtkCssMatcher *matcher,
+                            GtkStateFlags        state_flags)
+{
+  return (matcher->state_flags & state_flags) == state_flags;
+}
+
+gboolean
+_gtk_css_matcher_has_name (const GtkCssMatcher *matcher,
+                           const char          *name)
+{
+  const GtkWidgetPath *siblings;
+  GType type;
+  
+  type = g_type_from_name (name);
+  siblings = gtk_widget_path_iter_get_siblings (matcher->path, matcher->index);
+  if (siblings && matcher->sibling_index != gtk_widget_path_iter_get_sibling_index (matcher->path, matcher->index))
+    return g_type_is_a (gtk_widget_path_iter_get_object_type (siblings, matcher->sibling_index), type);
+  else
+    return g_type_is_a (gtk_widget_path_iter_get_object_type (matcher->path, matcher->index), type);
+}
+
+gboolean
+_gtk_css_matcher_has_class (const GtkCssMatcher *matcher,
+                            const char          *class_name)
+{
+  const GtkWidgetPath *siblings;
+  
+  siblings = gtk_widget_path_iter_get_siblings (matcher->path, matcher->index);
+  if (siblings && matcher->sibling_index != gtk_widget_path_iter_get_sibling_index (matcher->path, matcher->index))
+    return gtk_widget_path_iter_has_class (siblings, matcher->sibling_index, class_name);
+  else
+    return gtk_widget_path_iter_has_class (matcher->path, matcher->index, class_name);
+}
+
+gboolean
+_gtk_css_matcher_has_id (const GtkCssMatcher *matcher,
+                         const char          *id)
+{
+  const GtkWidgetPath *siblings;
+  
+  siblings = gtk_widget_path_iter_get_siblings (matcher->path, matcher->index);
+  if (siblings && matcher->sibling_index != gtk_widget_path_iter_get_sibling_index (matcher->path, matcher->index))
+    return gtk_widget_path_iter_has_name (siblings, matcher->sibling_index, id);
+  else
+    return gtk_widget_path_iter_has_name (matcher->path, matcher->index, id);
+}
+
+gboolean
+_gtk_css_matcher_has_regions (const GtkCssMatcher *matcher)
+{
+  const GtkWidgetPath *siblings;
+  GSList *regions;
+  gboolean result;
+  
+  siblings = gtk_widget_path_iter_get_siblings (matcher->path, matcher->index);
+  if (siblings && matcher->sibling_index != gtk_widget_path_iter_get_sibling_index (matcher->path, matcher->index))
+    regions = gtk_widget_path_iter_list_regions (siblings, matcher->sibling_index);
+  else
+    regions = gtk_widget_path_iter_list_regions (matcher->path, matcher->index);
+  result = regions != NULL;
+  g_slist_free (regions);
+
+  return result;
+}
+
+gboolean
+_gtk_css_matcher_has_region (const GtkCssMatcher *matcher,
+                             const char          *region,
+                             GtkRegionFlags       flags)
+{
+  const GtkWidgetPath *siblings;
+  GtkRegionFlags region_flags;
+  
+  siblings = gtk_widget_path_iter_get_siblings (matcher->path, matcher->index);
+  if (siblings && matcher->sibling_index != gtk_widget_path_iter_get_sibling_index (matcher->path, matcher->index))
+    {
+      if (!gtk_widget_path_iter_has_region (siblings, matcher->sibling_index, region, &region_flags))
+        return FALSE;
+    }
+  else
+    {
+      if (!gtk_widget_path_iter_has_region (matcher->path, matcher->index, region, &region_flags))
+        return FALSE;
+    }
+
+  if ((flags & region_flags) != flags)
+    return FALSE;
+
+  return TRUE;
+}
+
+guint
+_gtk_css_matcher_get_sibling_index (const GtkCssMatcher *matcher)
+{
+  return matcher->sibling_index;
+}
+
+guint
+_gtk_css_matcher_get_n_siblings (const GtkCssMatcher *matcher)
+{
+  const GtkWidgetPath *siblings;
+
+  siblings = gtk_widget_path_iter_get_siblings (matcher->path, matcher->index);
+  if (!siblings)
+    return 0;
+
+  return gtk_widget_path_length (siblings);
+}
+
diff --git a/gtk/gtkcssmatcherprivate.h b/gtk/gtkcssmatcherprivate.h
new file mode 100644
index 0000000..61988a2
--- /dev/null
+++ b/gtk/gtkcssmatcherprivate.h
@@ -0,0 +1,61 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2012 Benjamin Otte <otte gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GTK_CSS_MATCHER_PRIVATE_H__
+#define __GTK_CSS_MATCHER_PRIVATE_H__
+
+#include <gtk/gtkenums.h>
+#include <gtk/gtktypes.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GtkCssMatcher GtkCssMatcher;
+
+struct _GtkCssMatcher {
+  const GtkWidgetPath *path;
+  GtkStateFlags        state_flags;
+  guint                index;
+  guint                sibling_index;
+};
+
+void              _gtk_css_matcher_init           (GtkCssMatcher          *matcher,
+                                                   const GtkWidgetPath    *path,
+                                                   GtkStateFlags           state);
+gboolean          _gtk_css_matcher_get_parent     (GtkCssMatcher          *matcher,
+                                                   const GtkCssMatcher    *child);
+gboolean          _gtk_css_matcher_get_previous   (GtkCssMatcher          *matcher,
+                                                   const GtkCssMatcher    *next);
+
+gboolean          _gtk_css_matcher_has_state      (const GtkCssMatcher   *matcher,
+                                                   GtkStateFlags          state_flags);
+gboolean          _gtk_css_matcher_has_name       (const GtkCssMatcher   *matcher,
+                                                   const char            *name);
+gboolean          _gtk_css_matcher_has_class      (const GtkCssMatcher   *matcher,
+                                                   const char            *class_name);
+gboolean          _gtk_css_matcher_has_id         (const GtkCssMatcher   *matcher,
+                                                   const char            *id);
+gboolean          _gtk_css_matcher_has_regions    (const GtkCssMatcher   *matcher);
+gboolean          _gtk_css_matcher_has_region     (const GtkCssMatcher   *matcher,
+                                                   const char            *region,
+                                                   GtkRegionFlags         flags);
+guint             _gtk_css_matcher_get_sibling_index
+                                                  (const GtkCssMatcher   *matcher);
+guint             _gtk_css_matcher_get_n_siblings (const GtkCssMatcher   *matcher);
+
+G_END_DECLS
+
+#endif /* __GTK_CSS_MATCHER_PRIVATE_H__ */
diff --git a/gtk/gtkcssselector.c b/gtk/gtkcssselector.c
index 2f7735d..f526738 100644
--- a/gtk/gtkcssselector.c
+++ b/gtk/gtkcssselector.c
@@ -21,9 +21,9 @@
 
 #include <string.h>
 
+#include "gtkcssmatcherprivate.h"
 #include "gtkcssprovider.h"
 #include "gtkstylecontextprivate.h"
-#include "gtkwidgetpath.h"
 
 typedef struct _GtkCssSelectorClass GtkCssSelectorClass;
 
@@ -33,10 +33,7 @@ struct _GtkCssSelectorClass {
   void              (* print)   (const GtkCssSelector       *selector,
                                  GString                    *string);
   gboolean          (* match)   (const GtkCssSelector       *selector,
-                                 GtkStateFlags               state,
-                                 const GtkWidgetPath        *path,
-                                 guint                       id,
-                                 guint                       sibling);
+                                 const GtkCssMatcher        *matcher);
 
   guint         increase_id_specificity :1;
   guint         increase_class_specificity :1;
@@ -53,15 +50,12 @@ struct _GtkCssSelector
 
 static gboolean
 gtk_css_selector_match (const GtkCssSelector *selector,
-                        GtkStateFlags         state,
-                        const GtkWidgetPath  *path,
-                        guint                 id,
-                        guint                 sibling)
+                        const GtkCssMatcher  *matcher)
 {
   if (selector == NULL)
     return TRUE;
 
-  return selector->class->match (selector, state, path, id, sibling);
+  return selector->class->match (selector, matcher);
 }
 
 static const GtkCssSelector *
@@ -83,18 +77,15 @@ gtk_css_selector_descendant_print (const GtkCssSelector *selector,
 
 static gboolean
 gtk_css_selector_descendant_match (const GtkCssSelector *selector,
-                                   GtkStateFlags         state,
-                                   const GtkWidgetPath  *path,
-                                   guint                 id,
-                                   guint                 sibling)
+                                   const GtkCssMatcher  *matcher)
 {
-  while (id-- > 0)
+  GtkCssMatcher descendant;
+
+  while (_gtk_css_matcher_get_parent (&descendant, matcher))
     {
-      if (gtk_css_selector_match (gtk_css_selector_previous (selector),
-                                  0,
-                                  path,
-                                  id,
-                                  gtk_widget_path_iter_get_sibling_index (path, id)))
+      matcher = &descendant;
+
+      if (gtk_css_selector_match (gtk_css_selector_previous (selector), matcher))
         return TRUE;
     }
 
@@ -119,19 +110,14 @@ gtk_css_selector_child_print (const GtkCssSelector *selector,
 
 static gboolean
 gtk_css_selector_child_match (const GtkCssSelector *selector,
-                              GtkStateFlags         state,
-                              const GtkWidgetPath  *path,
-                              guint                 id,
-                              guint                 sibling)
+                              const GtkCssMatcher  *matcher)
 {
-  if (id == 0)
+  GtkCssMatcher parent;
+
+  if (!_gtk_css_matcher_get_parent (&parent, matcher))
     return FALSE;
 
-  return gtk_css_selector_match (gtk_css_selector_previous (selector),
-                                 0,
-                                 path,
-                                 id - 1,
-                                 gtk_widget_path_iter_get_sibling_index (path, id - 1));
+  return gtk_css_selector_match (gtk_css_selector_previous (selector), &parent);
 }
 
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_CHILD = {
@@ -152,18 +138,15 @@ gtk_css_selector_sibling_print (const GtkCssSelector *selector,
 
 static gboolean
 gtk_css_selector_sibling_match (const GtkCssSelector *selector,
-                                GtkStateFlags         state,
-                                const GtkWidgetPath  *path,
-                                guint                 id,
-                                guint                 sibling)
+                                const GtkCssMatcher  *matcher)
 {
-  while (sibling-- > 0)
+  GtkCssMatcher previous;
+
+  while (_gtk_css_matcher_get_previous (&previous, matcher))
     {
-      if (gtk_css_selector_match (gtk_css_selector_previous (selector),
-                                  0,
-                                  path,
-                                  id,
-                                  sibling))
+      matcher = &previous;
+
+      if (gtk_css_selector_match (gtk_css_selector_previous (selector), matcher))
         return TRUE;
     }
 
@@ -188,19 +171,14 @@ gtk_css_selector_adjacent_print (const GtkCssSelector *selector,
 
 static gboolean
 gtk_css_selector_adjacent_match (const GtkCssSelector *selector,
-                                 GtkStateFlags         state,
-                                 const GtkWidgetPath  *path,
-                                 guint                 id,
-                                 guint                 sibling)
+                                 const GtkCssMatcher  *matcher)
 {
-  if (sibling == 0)
+  GtkCssMatcher previous;
+
+  if (!_gtk_css_matcher_get_previous (&previous, matcher))
     return FALSE;
 
-  return gtk_css_selector_match (gtk_css_selector_previous (selector),
-                                 0,
-                                 path,
-                                 id,
-                                 sibling - 1);
+  return gtk_css_selector_match (gtk_css_selector_previous (selector), &previous);
 }
 
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_ADJACENT = {
@@ -221,24 +199,19 @@ gtk_css_selector_any_print (const GtkCssSelector *selector,
 
 static gboolean
 gtk_css_selector_any_match (const GtkCssSelector *selector,
-                            GtkStateFlags         state,
-                            const GtkWidgetPath  *path,
-                            guint                 id,
-                            guint                 sibling)
+                            const GtkCssMatcher  *matcher)
 {
   const GtkCssSelector *previous = gtk_css_selector_previous (selector);
-  GSList *regions;
   
   if (previous &&
       previous->class == &GTK_CSS_SELECTOR_DESCENDANT &&
-      (regions = gtk_widget_path_iter_list_regions (path, id)) != NULL)
+      _gtk_css_matcher_has_regions (matcher))
     {
-      g_slist_free (regions);
-      if (gtk_css_selector_match (gtk_css_selector_previous (previous), state, path, id, sibling))
+      if (gtk_css_selector_match (gtk_css_selector_previous (previous), matcher))
         return TRUE;
     }
   
-  return gtk_css_selector_match (previous, state, path, id, sibling);
+  return gtk_css_selector_match (previous, matcher);
 }
 
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_ANY = {
@@ -259,17 +232,12 @@ gtk_css_selector_name_print (const GtkCssSelector *selector,
 
 static gboolean
 gtk_css_selector_name_match (const GtkCssSelector *selector,
-                             GtkStateFlags         state,
-                             const GtkWidgetPath  *path,
-                             guint                 id,
-                             guint                 sibling)
+                             const GtkCssMatcher  *matcher)
 {
-  GType type = g_type_from_name (selector->data);
-
-  if (!g_type_is_a (gtk_widget_path_iter_get_object_type (path, id), type))
+  if (!_gtk_css_matcher_has_name (matcher, selector->data))
     return FALSE;
 
-  return gtk_css_selector_match (gtk_css_selector_previous (selector), state, path, id, sibling);
+  return gtk_css_selector_match (gtk_css_selector_previous (selector), matcher);
 }
 
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_NAME = {
@@ -290,22 +258,19 @@ gtk_css_selector_region_print (const GtkCssSelector *selector,
 
 static gboolean
 gtk_css_selector_region_match (const GtkCssSelector *selector,
-                               GtkStateFlags         state,
-                               const GtkWidgetPath  *path,
-                               guint                 id,
-                               guint                 sibling)
+                               const GtkCssMatcher  *matcher)
 {
   const GtkCssSelector *previous;
 
-  if (!gtk_widget_path_iter_has_region (path, id, selector->data, NULL))
+  if (!_gtk_css_matcher_has_region (matcher, selector->data, 0))
     return FALSE;
 
   previous = gtk_css_selector_previous (selector);
   if (previous && previous->class == &GTK_CSS_SELECTOR_DESCENDANT &&
-      gtk_css_selector_match (gtk_css_selector_previous (previous), state, path, id, sibling))
+      gtk_css_selector_match (gtk_css_selector_previous (previous), matcher))
     return TRUE;
 
-  return gtk_css_selector_match (previous, state, path, id, sibling);
+  return gtk_css_selector_match (previous, matcher);
 }
 
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_REGION = {
@@ -327,15 +292,12 @@ gtk_css_selector_class_print (const GtkCssSelector *selector,
 
 static gboolean
 gtk_css_selector_class_match (const GtkCssSelector *selector,
-                              GtkStateFlags         state,
-                              const GtkWidgetPath  *path,
-                              guint                 id,
-                              guint                 sibling)
+                              const GtkCssMatcher  *matcher)
 {
-  if (!gtk_widget_path_iter_has_class (path, id, selector->data))
+  if (!_gtk_css_matcher_has_class (matcher, selector->data))
     return FALSE;
 
-  return gtk_css_selector_match (gtk_css_selector_previous (selector), state, path, id, sibling);
+  return gtk_css_selector_match (gtk_css_selector_previous (selector), matcher);
 }
 
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_CLASS = {
@@ -357,15 +319,12 @@ gtk_css_selector_id_print (const GtkCssSelector *selector,
 
 static gboolean
 gtk_css_selector_id_match (const GtkCssSelector *selector,
-                           GtkStateFlags         state,
-                           const GtkWidgetPath  *path,
-                           guint                 id,
-                           guint                 sibling)
+                           const GtkCssMatcher  *matcher)
 {
-  if (!gtk_widget_path_iter_has_name (path, id, selector->data))
+  if (!_gtk_css_matcher_has_id (matcher, selector->data))
     return FALSE;
 
-  return gtk_css_selector_match (gtk_css_selector_previous (selector), state, path, id, sibling);
+  return gtk_css_selector_match (gtk_css_selector_previous (selector), matcher);
 }
 
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_ID = {
@@ -409,15 +368,12 @@ gtk_css_selector_pseudoclass_state_print (const GtkCssSelector *selector,
 
 static gboolean
 gtk_css_selector_pseudoclass_state_match (const GtkCssSelector *selector,
-                                          GtkStateFlags         state,
-                                          const GtkWidgetPath  *path,
-                                          guint                 id,
-                                          guint                 sibling)
+                                          const GtkCssMatcher  *matcher)
 {
-  if (!(GPOINTER_TO_UINT (selector->data) & state))
+  if (!_gtk_css_matcher_has_state (matcher, GPOINTER_TO_UINT (selector->data)))
     return FALSE;
 
-  return gtk_css_selector_match (gtk_css_selector_previous (selector), state, path, id, sibling);
+  return gtk_css_selector_match (gtk_css_selector_previous (selector), matcher);
 }
 
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_PSEUDOCLASS_STATE = {
@@ -460,53 +416,43 @@ gtk_css_selector_pseudoclass_region_print (const GtkCssSelector *selector,
 
 static gboolean
 gtk_css_selector_pseudoclass_region_match_for_region (const GtkCssSelector *selector,
-                                                      GtkStateFlags         state,
-                                                      const GtkWidgetPath  *path,
-                                                      guint                 id,
-                                                      guint                 sibling)
+                                                      const GtkCssMatcher  *matcher)
 {
-  GtkRegionFlags selector_flags, path_flags;
+  GtkRegionFlags selector_flags;
   const GtkCssSelector *previous;
   
   selector_flags = GPOINTER_TO_UINT (selector->data);
   selector = gtk_css_selector_previous (selector);
 
-  if (!gtk_widget_path_iter_has_region (path, id, selector->data, &path_flags))
-    return FALSE;
-
-  if ((selector_flags & path_flags) != selector_flags)
+  if (!_gtk_css_matcher_has_region (matcher, selector->data, selector_flags))
     return FALSE;
 
   previous = gtk_css_selector_previous (selector);
   if (previous && previous->class == &GTK_CSS_SELECTOR_DESCENDANT &&
-      gtk_css_selector_match (gtk_css_selector_previous (previous), state, path, id, sibling))
+      gtk_css_selector_match (gtk_css_selector_previous (previous), matcher))
     return TRUE;
 
-  return gtk_css_selector_match (previous, state, path, id, sibling);
+  return gtk_css_selector_match (previous, matcher);
 }
 
 static gboolean
 gtk_css_selector_pseudoclass_region_match (const GtkCssSelector *selector,
-                                           GtkStateFlags         state,
-                                           const GtkWidgetPath  *path,
-                                           guint                 id,
-                                           guint                 sibling)
+                                           const GtkCssMatcher  *matcher)
 {
   GtkRegionFlags region;
-  const GtkWidgetPath *siblings;
-  guint n_siblings;
+  guint sibling, n_siblings;
   const GtkCssSelector *previous;
 
   previous = gtk_css_selector_previous (selector);
   if (previous && previous->class == &GTK_CSS_SELECTOR_REGION)
-    return gtk_css_selector_pseudoclass_region_match_for_region (selector, state, path, id, sibling);
+    return gtk_css_selector_pseudoclass_region_match_for_region (selector, matcher);
 
-  siblings = gtk_widget_path_iter_get_siblings (path, id);
-  if (siblings == NULL)
-    return 0;
+  n_siblings = _gtk_css_matcher_get_n_siblings (matcher);
+  if (n_siblings == 0)
+    return FALSE;
+  sibling = _gtk_css_matcher_get_sibling_index (matcher);
 
   region = GPOINTER_TO_UINT (selector->data);
-  n_siblings = gtk_widget_path_length (siblings);
 
   switch (region)
     {
@@ -537,7 +483,7 @@ gtk_css_selector_pseudoclass_region_match (const GtkCssSelector *selector,
       return FALSE;
     }
 
-  return gtk_css_selector_match (previous, state, path, id, sibling);
+  return gtk_css_selector_match (previous, matcher);
 }
 
 static const GtkCssSelectorClass GTK_CSS_SELECTOR_PSEUDOCLASS_REGION = {
@@ -887,20 +833,14 @@ _gtk_css_selector_matches (const GtkCssSelector      *selector,
                            const GtkWidgetPath       *path,
                            GtkStateFlags              state)
 {
-  guint length;
+  GtkCssMatcher matcher;
 
   g_return_val_if_fail (selector != NULL, FALSE);
   g_return_val_if_fail (path != NULL, FALSE);
 
-  length = gtk_widget_path_length (path);
-  if (length == 0)
-    return FALSE;
+  _gtk_css_matcher_init (&matcher, path, state);
 
-  return gtk_css_selector_match (selector,
-                                 state,
-                                 path,
-                                 length - 1,
-                                 gtk_widget_path_iter_get_sibling_index (path, length - 1));
+  return gtk_css_selector_match (selector, &matcher);
 }
 
 /* Computes specificity according to CSS 2.1.



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