[gtk+/wip/otte/tokenizer: 49/78] css: Add token parser for keyframes rule



commit 69506210a230e0e1f92defb645c268f997310ec5
Author: Benjamin Otte <otte redhat com>
Date:   Tue Mar 22 22:19:39 2016 +0100

    css: Add token parser for keyframes rule

 gtk/Makefile.am                  |    4 +
 gtk/gtkcsskeyframerule.c         |  139 ++++++++++++++++++++
 gtk/gtkcsskeyframeruleprivate.h  |   57 ++++++++
 gtk/gtkcsskeyframesrule.c        |  264 ++++++++++++++++++++++++++++++++++++++
 gtk/gtkcsskeyframesruleprivate.h |   57 ++++++++
 gtk/gtkcssrule.c                 |    5 +
 6 files changed, 526 insertions(+), 0 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 42a4de5..c68a0ae 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -422,7 +422,9 @@ gtk_private_h_sources =             \
        gtkcssimportruleprivate.h       \
        gtkcssinheritvalueprivate.h     \
        gtkcssinitialvalueprivate.h     \
+       gtkcsskeyframeruleprivate.h     \
        gtkcsskeyframesprivate.h        \
+       gtkcsskeyframesruleprivate.h    \
        gtkcsslookupprivate.h   \
        gtkcssmatcherprivate.h  \
        gtkcssnodeprivate.h             \
@@ -701,7 +703,9 @@ gtk_base_c_sources =                \
        gtkcssimportrule.c      \
        gtkcssinheritvalue.c    \
        gtkcssinitialvalue.c    \
+       gtkcsskeyframerule.c    \
        gtkcsskeyframes.c       \
+       gtkcsskeyframesrule.c   \
        gtkcsslookup.c          \
        gtkcssmatcher.c         \
        gtkcssnode.c            \
diff --git a/gtk/gtkcsskeyframerule.c b/gtk/gtkcsskeyframerule.c
new file mode 100644
index 0000000..bb73e61
--- /dev/null
+++ b/gtk/gtkcsskeyframerule.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright © 2016 Red Hat Inc.
+ *
+ * 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.1 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/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#include "config.h"
+
+#include "gtkcsskeyframeruleprivate.h"
+
+#include "gtkcssstylesheetprivate.h"
+
+typedef struct _GtkCssKeyframeRulePrivate GtkCssKeyframeRulePrivate;
+struct _GtkCssKeyframeRulePrivate {
+  double *offsets;
+  gsize n_offsets;
+  GtkCssStyleDeclaration *style;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtkCssKeyframeRule, gtk_css_keyframe_rule, GTK_TYPE_CSS_RULE)
+
+static void
+gtk_css_keyframe_rule_finalize (GObject *object)
+{
+  GtkCssKeyframeRule *keyframe_rule = GTK_CSS_KEYFRAME_RULE (object);
+  GtkCssKeyframeRulePrivate *priv = gtk_css_keyframe_rule_get_instance_private (keyframe_rule);
+
+  g_free (priv->offsets);
+  g_object_unref (priv->style);
+
+  G_OBJECT_CLASS (gtk_css_keyframe_rule_parent_class)->finalize (object);
+}
+
+static void
+gtk_css_keyframe_rule_class_init (GtkCssKeyframeRuleClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = gtk_css_keyframe_rule_finalize;
+}
+
+static void
+gtk_css_keyframe_rule_init (GtkCssKeyframeRule *keyframe_rule)
+{
+  GtkCssKeyframeRulePrivate *priv = gtk_css_keyframe_rule_get_instance_private (keyframe_rule);
+
+  priv->style = gtk_css_style_declaration_new (GTK_CSS_RULE (keyframe_rule));
+}
+
+static GtkCssRule *
+gtk_css_keyframe_rule_new (GtkCssRule       *parent_rule,
+                           GtkCssStyleSheet *parent_style_sheet)
+{
+  return g_object_new (GTK_TYPE_CSS_KEYFRAME_RULE,
+                       "parent-rule", parent_rule,
+                       "parent-stylesheet", parent_style_sheet,
+                       NULL);
+}
+
+GtkCssRule *
+gtk_css_keyframe_rule_new_parse (GtkCssTokenSource *source,
+                                 GtkCssRule        *parent_rule,
+                                 GtkCssStyleSheet  *parent_style_sheet)
+{
+  GtkCssKeyframeRulePrivate *priv;
+  GtkCssTokenSource *style_source;
+  const GtkCssToken *token;
+  GtkCssRule *rule;
+  GArray *offsets;
+
+  g_return_val_if_fail (source != NULL, NULL);
+  g_return_val_if_fail (parent_rule == NULL || GTK_IS_CSS_RULE (parent_rule), NULL);
+  g_return_val_if_fail (GTK_IS_CSS_STYLE_SHEET (parent_style_sheet), NULL);
+
+  rule = gtk_css_keyframe_rule_new (parent_rule, parent_style_sheet);
+  priv = gtk_css_keyframe_rule_get_instance_private (GTK_CSS_KEYFRAME_RULE (rule));
+  gtk_css_token_source_set_consumer (source, G_OBJECT (rule));
+
+  offsets = g_array_new (FALSE, FALSE, sizeof (double));
+  while (TRUE)
+    {
+      double offset;
+
+      token = gtk_css_token_source_get_token (source);
+      if (gtk_css_token_is_ident (token, "from"))
+        offset = 0;
+      else if (gtk_css_token_is_ident (token, "to"))
+        offset = 100;
+      else if (gtk_css_token_is (token, GTK_CSS_TOKEN_PERCENTAGE))
+        offset = token->number.number;
+      else 
+        {
+          gtk_css_token_source_error (source, "Expected percentage");
+          gtk_css_token_source_consume_all (source);
+          g_array_free (offsets, TRUE);
+          g_object_unref (rule);
+          return NULL;
+        }
+      g_array_append_val (offsets, offset);
+      gtk_css_token_source_consume_token (source);
+      token = gtk_css_token_source_get_token (source);
+      if (!gtk_css_token_is (token, GTK_CSS_TOKEN_COMMA))
+        break;
+      gtk_css_token_source_consume_token (source);
+    }
+
+  priv->n_offsets = offsets->len;
+  priv->offsets = (double *) g_array_free (offsets, FALSE);
+
+  if (!gtk_css_token_is (token, GTK_CSS_TOKEN_OPEN_CURLY))
+    {
+      gtk_css_token_source_error (source, "Expected percentage");
+      gtk_css_token_source_consume_all (source);
+      g_object_unref (rule);
+      return NULL;
+    }
+  gtk_css_token_source_consume_token (source);
+
+  style_source = gtk_css_token_source_new_for_part (source, GTK_CSS_TOKEN_CLOSE_CURLY);
+  gtk_css_style_declaration_parse (priv->style, style_source);
+  gtk_css_token_source_unref (style_source);
+  gtk_css_token_source_consume_token (source);
+
+  return rule;
+}
+
diff --git a/gtk/gtkcsskeyframeruleprivate.h b/gtk/gtkcsskeyframeruleprivate.h
new file mode 100644
index 0000000..c17879a
--- /dev/null
+++ b/gtk/gtkcsskeyframeruleprivate.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright © 2016 Red Hat Inc.
+ *
+ * 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.1 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/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#ifndef __GTK_CSS_KEYFRAME_RULE_PRIVATE_H__
+#define __GTK_CSS_KEYFRAME_RULE_PRIVATE_H__
+
+#include "gtk/gtkcssruleprivate.h"
+#include "gtk/gtkcssstyledeclarationprivate.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_CSS_KEYFRAME_RULE           (gtk_css_keyframe_rule_get_type ())
+#define GTK_CSS_KEYFRAME_RULE(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_KEYFRAME_RULE, 
GtkCssKeyframeRule))
+#define GTK_CSS_KEYFRAME_RULE_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_KEYFRAME_RULE, 
GtkCssKeyframeRuleClass))
+#define GTK_IS_CSS_KEYFRAME_RULE(obj)        (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_KEYFRAME_RULE))
+#define GTK_IS_CSS_KEYFRAME_RULE_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_KEYFRAME_RULE))
+#define GTK_CSS_KEYFRAME_RULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_KEYFRAME_RULE, 
GtkCssKeyframeRuleClass))
+
+typedef struct _GtkCssKeyframeRule           GtkCssKeyframeRule;
+typedef struct _GtkCssKeyframeRuleClass      GtkCssKeyframeRuleClass;
+
+struct _GtkCssKeyframeRule
+{
+  GtkCssRule parent;
+};
+
+struct _GtkCssKeyframeRuleClass
+{
+  GtkCssRuleClass parent_class;
+};
+
+GType                   gtk_css_keyframe_rule_get_type          (void) G_GNUC_CONST;
+
+GtkCssRule *            gtk_css_keyframe_rule_new_parse         (GtkCssTokenSource      *source,
+                                                                 GtkCssRule             *parent_rule,
+                                                                 GtkCssStyleSheet       *parent_style_sheet);
+
+
+G_END_DECLS
+
+#endif /* __GTK_CSS_KEYFRAME_RULE_PRIVATE_H__ */
diff --git a/gtk/gtkcsskeyframesrule.c b/gtk/gtkcsskeyframesrule.c
new file mode 100644
index 0000000..5b2c8dd
--- /dev/null
+++ b/gtk/gtkcsskeyframesrule.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright © 2016 Red Hat Inc.
+ *
+ * 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.1 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/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#include "config.h"
+
+#include "gtkcsskeyframesruleprivate.h"
+
+#include "gtkcsskeyframeruleprivate.h"
+#include "gtkcssstylesheetprivate.h"
+
+typedef struct _GtkCssKeyframesRulePrivate GtkCssKeyframesRulePrivate;
+struct _GtkCssKeyframesRulePrivate {
+  char *name;
+  GtkCssRuleList *rules;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtkCssKeyframesRule, gtk_css_keyframes_rule, GTK_TYPE_CSS_RULE)
+
+typedef struct _GtkCssTokenSourceKeyframe GtkCssTokenSourceKeyframe;
+struct _GtkCssTokenSourceKeyframe {
+  GtkCssTokenSource parent;
+  GtkCssTokenSource *source;
+  GSList *blocks;
+  gboolean done;
+};
+
+static void
+gtk_css_token_source_keyframe_finalize (GtkCssTokenSource *source)
+{
+  GtkCssTokenSourceKeyframe *keyframe = (GtkCssTokenSourceKeyframe *) source;
+
+  g_slist_free (keyframe->blocks);
+
+  gtk_css_token_source_unref (keyframe->source);
+}
+
+static void
+gtk_css_token_source_keyframe_consume_token (GtkCssTokenSource *source,
+                                             GObject           *consumer)
+{
+  GtkCssTokenSourceKeyframe *keyframe = (GtkCssTokenSourceKeyframe *) source;
+  const GtkCssToken *token;
+
+  if (keyframe->done)
+    return;
+
+  token = gtk_css_token_source_peek_token (keyframe->source);
+  switch (token->type)
+    {
+    case GTK_CSS_TOKEN_FUNCTION:
+    case GTK_CSS_TOKEN_OPEN_PARENS:
+      keyframe->blocks = g_slist_prepend (keyframe->blocks, GUINT_TO_POINTER (GTK_CSS_TOKEN_CLOSE_PARENS));
+      break;
+    case GTK_CSS_TOKEN_OPEN_SQUARE:
+      keyframe->blocks = g_slist_prepend (keyframe->blocks, GUINT_TO_POINTER (GTK_CSS_TOKEN_CLOSE_SQUARE));
+      break;
+    case GTK_CSS_TOKEN_OPEN_CURLY:
+      keyframe->blocks = g_slist_prepend (keyframe->blocks, GUINT_TO_POINTER (GTK_CSS_TOKEN_CLOSE_CURLY));
+      break;
+    case GTK_CSS_TOKEN_CLOSE_PARENS:
+    case GTK_CSS_TOKEN_CLOSE_SQUARE:
+    case GTK_CSS_TOKEN_CLOSE_CURLY:
+      if (keyframe->blocks && GPOINTER_TO_UINT (keyframe->blocks->data) == token->type)
+        keyframe->blocks = g_slist_remove (keyframe->blocks, keyframe->blocks->data);
+      if (token->type == GTK_CSS_TOKEN_CLOSE_CURLY && keyframe->blocks == NULL)
+        keyframe->done = TRUE;
+      break;
+    default:
+      break;
+    }
+
+  gtk_css_token_source_consume_token_as (keyframe->source, consumer);
+}
+
+const GtkCssToken *
+gtk_css_token_source_keyframe_peek_token (GtkCssTokenSource *source)
+{
+  GtkCssTokenSourceKeyframe *keyframe = (GtkCssTokenSourceKeyframe *) source;
+  static GtkCssToken eof_token = { GTK_CSS_TOKEN_EOF };
+
+  if (keyframe->done)
+    return &eof_token;
+
+  return gtk_css_token_source_peek_token (keyframe->source);
+}
+
+static void
+gtk_css_token_source_keyframe_error (GtkCssTokenSource *source,
+                                     const GError      *error)
+{
+  GtkCssTokenSourceKeyframe *keyframe = (GtkCssTokenSourceKeyframe *) source;
+
+  gtk_css_token_source_emit_error (keyframe->source, error);
+}
+
+static GFile *
+gtk_css_token_source_keyframe_get_location (GtkCssTokenSource *source)
+{
+  GtkCssTokenSourceKeyframe *keyframe = (GtkCssTokenSourceKeyframe *) source;
+
+  return gtk_css_token_source_get_location (keyframe->source);
+}
+
+static const GtkCssTokenSourceClass GTK_CSS_TOKEN_SOURCE_KEYFRAME = {
+  gtk_css_token_source_keyframe_finalize,
+  gtk_css_token_source_keyframe_consume_token,
+  gtk_css_token_source_keyframe_peek_token,
+  gtk_css_token_source_keyframe_error,
+  gtk_css_token_source_keyframe_get_location,
+};
+
+static GtkCssTokenSource *
+gtk_css_token_source_new_keyframe (GtkCssTokenSource *source)
+{
+  GtkCssTokenSourceKeyframe *keyframe = gtk_css_token_source_new (GtkCssTokenSourceKeyframe, 
&GTK_CSS_TOKEN_SOURCE_KEYFRAME);
+
+  keyframe->source = gtk_css_token_source_ref (source);
+  gtk_css_token_source_set_consumer (&keyframe->parent,
+                                     gtk_css_token_source_get_consumer (source));
+
+  return &keyframe->parent;
+}
+
+static void
+gtk_css_keyframes_rule_finalize (GObject *object)
+{
+  GtkCssKeyframesRule *keyframes_rule = GTK_CSS_KEYFRAMES_RULE (object);
+  GtkCssKeyframesRulePrivate *priv = gtk_css_keyframes_rule_get_instance_private (keyframes_rule);
+
+  g_free (priv->name);
+  g_object_unref (priv->rules);
+
+  G_OBJECT_CLASS (gtk_css_keyframes_rule_parent_class)->finalize (object);
+}
+
+static void
+gtk_css_keyframes_rule_class_init (GtkCssKeyframesRuleClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = gtk_css_keyframes_rule_finalize;
+}
+
+static void
+gtk_css_keyframes_rule_init (GtkCssKeyframesRule *keyframes_rule)
+{
+  GtkCssKeyframesRulePrivate *priv = gtk_css_keyframes_rule_get_instance_private (keyframes_rule);
+
+  priv->rules = gtk_css_rule_list_new ();
+}
+
+static void
+gtk_css_keyframes_rule_set_name (GtkCssKeyframesRule *keyframes,
+                                 const char          *name)
+{
+  GtkCssKeyframesRulePrivate *priv;
+  
+  priv = gtk_css_keyframes_rule_get_instance_private (keyframes);
+
+  g_free (priv->name);
+  priv->name = g_strdup (name);
+}
+
+static void
+gtk_css_keyframes_rule_append (GtkCssKeyframesRule *keyframes,
+                               GtkCssRule          *rule)
+{
+  GtkCssKeyframesRulePrivate *priv;
+  
+  priv = gtk_css_keyframes_rule_get_instance_private (keyframes);
+
+  gtk_css_rule_list_append (priv->rules, rule);
+}
+
+static GtkCssRule *
+gtk_css_keyframes_rule_new (GtkCssRule       *parent_rule,
+                            GtkCssStyleSheet *parent_style_sheet)
+{
+  return g_object_new (GTK_TYPE_CSS_KEYFRAMES_RULE,
+                       "parent-rule", parent_rule,
+                       "parent-stylesheet", parent_style_sheet,
+                       NULL);
+}
+
+GtkCssRule *
+gtk_css_keyframes_rule_new_parse (GtkCssTokenSource *source,
+                                  GtkCssRule        *parent_rule,
+                                  GtkCssStyleSheet  *parent_style_sheet)
+{
+  const GtkCssToken *token;
+  GtkCssRule *rule;
+
+  g_return_val_if_fail (source != NULL, NULL);
+  g_return_val_if_fail (parent_rule == NULL || GTK_IS_CSS_RULE (parent_rule), NULL);
+  g_return_val_if_fail (GTK_IS_CSS_STYLE_SHEET (parent_style_sheet), NULL);
+
+  rule = gtk_css_keyframes_rule_new (parent_rule, parent_style_sheet);
+  gtk_css_token_source_set_consumer (source, G_OBJECT (rule));
+
+  token = gtk_css_token_source_get_token (source);
+  if (token->type != GTK_CSS_TOKEN_AT_KEYWORD ||
+      g_ascii_strcasecmp (token->string.string, "keyframes") != 0)
+    {
+      gtk_css_token_source_error (source, "Expected '@keyframes'");
+      gtk_css_token_source_consume_all (source);
+      g_object_unref (rule);
+      return NULL;
+    }
+  gtk_css_token_source_consume_token (source);
+
+  token = gtk_css_token_source_get_token (source);
+  if (!gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
+    {
+      gtk_css_token_source_error (source, "Expected name of keyframes");
+      gtk_css_token_source_consume_all (source);
+      return NULL;
+    }
+  gtk_css_keyframes_rule_set_name (GTK_CSS_KEYFRAMES_RULE (rule), token->string.string);
+  gtk_css_token_source_consume_token (source);
+
+  token = gtk_css_token_source_get_token (source);
+  if (!gtk_css_token_is (token, GTK_CSS_TOKEN_OPEN_CURLY))
+    {
+      gtk_css_token_source_error (source, "Expected '{'");
+      gtk_css_token_source_consume_all (source);
+      return NULL;
+    }
+  gtk_css_token_source_consume_token (source);
+
+  for (token = gtk_css_token_source_get_token (source);
+       !gtk_css_token_is (token, GTK_CSS_TOKEN_EOF) && !gtk_css_token_is (token, GTK_CSS_TOKEN_CLOSE_CURLY);
+       token = gtk_css_token_source_get_token (source))
+    {
+      GtkCssTokenSource *keyframe_source = gtk_css_token_source_new_keyframe (source);
+      GtkCssRule *keyframe;
+
+      keyframe = gtk_css_keyframe_rule_new_parse (keyframe_source, rule, parent_style_sheet);
+      if (keyframe)
+        gtk_css_keyframes_rule_append (GTK_CSS_KEYFRAMES_RULE (rule), keyframe);
+      
+      gtk_css_token_source_unref (keyframe_source);
+    }
+
+  gtk_css_token_source_consume_token (source);
+
+  return rule;
+}
+
diff --git a/gtk/gtkcsskeyframesruleprivate.h b/gtk/gtkcsskeyframesruleprivate.h
new file mode 100644
index 0000000..c45ff5c
--- /dev/null
+++ b/gtk/gtkcsskeyframesruleprivate.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright © 2016 Red Hat Inc.
+ *
+ * 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.1 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/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#ifndef __GTK_CSS_KEYFRAMES_RULE_PRIVATE_H__
+#define __GTK_CSS_KEYFRAMES_RULE_PRIVATE_H__
+
+#include "gtk/gtkcssruleprivate.h"
+#include "gtk/gtkcssrulelistprivate.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_CSS_KEYFRAMES_RULE           (gtk_css_keyframes_rule_get_type ())
+#define GTK_CSS_KEYFRAMES_RULE(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_KEYFRAMES_RULE, 
GtkCssKeyframesRule))
+#define GTK_CSS_KEYFRAMES_RULE_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_KEYFRAMES_RULE, 
GtkCssKeyframesRuleClass))
+#define GTK_IS_CSS_KEYFRAMES_RULE(obj)        (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_KEYFRAMES_RULE))
+#define GTK_IS_CSS_KEYFRAMES_RULE_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_KEYFRAMES_RULE))
+#define GTK_CSS_KEYFRAMES_RULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), 
GTK_TYPE_CSS_KEYFRAMES_RULE, GtkCssKeyframesRuleClass))
+
+typedef struct _GtkCssKeyframesRule           GtkCssKeyframesRule;
+typedef struct _GtkCssKeyframesRuleClass      GtkCssKeyframesRuleClass;
+
+struct _GtkCssKeyframesRule
+{
+  GtkCssRule parent;
+};
+
+struct _GtkCssKeyframesRuleClass
+{
+  GtkCssRuleClass parent_class;
+};
+
+GType                   gtk_css_keyframes_rule_get_type         (void) G_GNUC_CONST;
+
+GtkCssRule *            gtk_css_keyframes_rule_new_parse        (GtkCssTokenSource      *source,
+                                                                 GtkCssRule             *parent_rule,
+                                                                 GtkCssStyleSheet       *parent_style_sheet);
+
+
+G_END_DECLS
+
+#endif /* __GTK_CSS_KEYFRAMES_RULE_PRIVATE_H__ */
diff --git a/gtk/gtkcssrule.c b/gtk/gtkcssrule.c
index a5a9794..4fd22b9 100644
--- a/gtk/gtkcssrule.c
+++ b/gtk/gtkcssrule.c
@@ -23,6 +23,7 @@
 
 #include "gtkcssdefinecolorruleprivate.h"
 #include "gtkcssimportruleprivate.h"
+#include "gtkcsskeyframesruleprivate.h"
 #include "gtkcssstylesheetprivate.h"
 #include "gtkintl.h"
 #include "gtkprivate.h"
@@ -277,6 +278,10 @@ gtk_css_rule_new_from_at_rule (GtkCssTokenSource *source,
     {
       rule = gtk_css_define_color_rule_new_parse (at_source, parent_rule, parent_style_sheet);
     }
+  else if (g_ascii_strcasecmp (token->string.string, "keyframes") == 0)
+    {
+      rule = gtk_css_keyframes_rule_new_parse (at_source, parent_rule, parent_style_sheet);
+    }
   else
     {
       gtk_css_token_source_unknown (at_source, "Unknown rule @%s", token->string.string);


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