css: Add skeleton for new parsing infrastructure
This infrastructure will be based around the CSSOM and return a GtkCssStyleSheet object as its result. The initial intended use for this is as a syntax tree while editing in the inspector, but we might even want to look into exporting the CSSOM parts as public API at some point.
This commit is contained in:
@@ -434,6 +434,8 @@ gtk_private_h_sources = \
|
||||
gtkcssrbtreeprivate.h \
|
||||
gtkcssrepeatvalueprivate.h \
|
||||
gtkcssrgbavalueprivate.h \
|
||||
gtkcssruleprivate.h \
|
||||
gtkcssrulelistprivate.h \
|
||||
gtkcsssectionprivate.h \
|
||||
gtkcssselectorprivate.h \
|
||||
gtkcssshadowsvalueprivate.h \
|
||||
@@ -445,7 +447,11 @@ gtk_private_h_sources = \
|
||||
gtkcssstylechangeprivate.h \
|
||||
gtkcssstyleprivate.h \
|
||||
gtkcssstylepropertyprivate.h \
|
||||
gtkcssstyledeclarationprivate.h \
|
||||
gtkcssstyleruleprivate.h \
|
||||
gtkcssstylesheetprivate.h \
|
||||
gtkcsstokenizerprivate.h \
|
||||
gtkcsstokensourceprivate.h \
|
||||
gtkcsstransformvalueprivate.h \
|
||||
gtkcsstransientnodeprivate.h \
|
||||
gtkcsstransitionprivate.h \
|
||||
@@ -704,11 +710,15 @@ gtk_base_c_sources = \
|
||||
gtkcssrbtree.c \
|
||||
gtkcssrepeatvalue.c \
|
||||
gtkcssrgbavalue.c \
|
||||
gtkcssrule.c \
|
||||
gtkcssrulelist.c \
|
||||
gtkcsssection.c \
|
||||
gtkcssselector.c \
|
||||
gtkcssstringvalue.c \
|
||||
gtkcssstyle.c \
|
||||
gtkcssstylechange.c \
|
||||
gtkcssstyledeclaration.c \
|
||||
gtkcssstylerule.c \
|
||||
gtkcssshadowsvalue.c \
|
||||
gtkcssshadowvalue.c \
|
||||
gtkcssshorthandproperty.c \
|
||||
@@ -717,7 +727,9 @@ gtk_base_c_sources = \
|
||||
gtkcssstylefuncs.c \
|
||||
gtkcssstyleproperty.c \
|
||||
gtkcssstylepropertyimpl.c \
|
||||
gtkcssstylesheet.c \
|
||||
gtkcsstokenizer.c \
|
||||
gtkcsstokensource.c \
|
||||
gtkcsstransformvalue.c \
|
||||
gtkcsstransientnode.c \
|
||||
gtkcsstransition.c \
|
||||
|
||||
215
gtk/gtkcssrule.c
Normal file
215
gtk/gtkcssrule.c
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* 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 "gtkcssruleprivate.h"
|
||||
|
||||
#include "gtkcssstylesheetprivate.h"
|
||||
|
||||
typedef struct _GtkCssRulePrivate GtkCssRulePrivate;
|
||||
struct _GtkCssRulePrivate {
|
||||
GtkCssRule *parent_rule;
|
||||
GtkCssStyleSheet *parent_style_sheet;
|
||||
};
|
||||
|
||||
typedef struct _GtkCssTokenSourceAt GtkCssTokenSourceAt;
|
||||
struct _GtkCssTokenSourceAt {
|
||||
GtkCssTokenSource parent;
|
||||
GtkCssTokenSource *source;
|
||||
guint inside_curly_block :1;
|
||||
guint done :1;
|
||||
};
|
||||
|
||||
static void
|
||||
gtk_css_token_source_at_finalize (GtkCssTokenSource *source)
|
||||
{
|
||||
GtkCssTokenSourceAt *at = (GtkCssTokenSourceAt *) source;
|
||||
|
||||
gtk_css_token_source_unref (at->source);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_token_source_at_consume_token (GtkCssTokenSource *source)
|
||||
{
|
||||
GtkCssTokenSourceAt *at = (GtkCssTokenSourceAt *) source;
|
||||
const GtkCssToken *token;
|
||||
|
||||
if (at->done)
|
||||
return;
|
||||
|
||||
if (gtk_css_token_get_pending_block (source))
|
||||
{
|
||||
gtk_css_token_source_consume_token (at->source);
|
||||
return;
|
||||
}
|
||||
|
||||
token = gtk_css_token_source_get_token (at->source);
|
||||
if (gtk_css_token_is (token, GTK_CSS_TOKEN_SEMICOLON))
|
||||
at->done = TRUE;
|
||||
else if (at->inside_curly_block && gtk_css_token_is (token, GTK_CSS_TOKEN_CLOSE_CURLY))
|
||||
at->done = TRUE;
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_OPEN_CURLY))
|
||||
at->inside_curly_block = TRUE;
|
||||
|
||||
gtk_css_token_source_consume_token (at->source);
|
||||
}
|
||||
|
||||
const GtkCssToken *
|
||||
gtk_css_token_source_at_get_token (GtkCssTokenSource *source)
|
||||
{
|
||||
GtkCssTokenSourceAt *at = (GtkCssTokenSourceAt *) source;
|
||||
static GtkCssToken eof_token = { GTK_CSS_TOKEN_EOF };
|
||||
|
||||
if (at->done)
|
||||
return &eof_token;
|
||||
|
||||
return gtk_css_token_source_get_token (at->source);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_token_source_at_error (GtkCssTokenSource *source,
|
||||
const GError *error)
|
||||
{
|
||||
GtkCssTokenSourceAt *at = (GtkCssTokenSourceAt *) source;
|
||||
|
||||
gtk_css_token_source_emit_error (at->source, error);
|
||||
}
|
||||
|
||||
static const GtkCssTokenSourceClass GTK_CSS_TOKEN_SOURCE_AT = {
|
||||
gtk_css_token_source_at_finalize,
|
||||
gtk_css_token_source_at_consume_token,
|
||||
gtk_css_token_source_at_get_token,
|
||||
gtk_css_token_source_at_error
|
||||
};
|
||||
|
||||
static GtkCssTokenSource *
|
||||
gtk_css_token_source_new_at (GtkCssTokenSource *source)
|
||||
{
|
||||
GtkCssTokenSourceAt *at = gtk_css_token_source_new (GtkCssTokenSourceAt, >K_CSS_TOKEN_SOURCE_AT);
|
||||
|
||||
at->source = gtk_css_token_source_ref (source);
|
||||
|
||||
return &at->parent;
|
||||
}
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GtkCssRule, gtk_css_rule, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gtk_css_rule_class_init (GtkCssRuleClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_rule_init (GtkCssRule *rule)
|
||||
{
|
||||
}
|
||||
|
||||
GtkCssRule *
|
||||
gtk_css_rule_new_from_at_rule (GtkCssTokenSource *source,
|
||||
GtkCssRule *parent_rule,
|
||||
GtkCssStyleSheet *parent_style_sheet)
|
||||
{
|
||||
GtkCssTokenSource *at_source;
|
||||
const GtkCssToken *token;
|
||||
|
||||
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);
|
||||
|
||||
at_source = gtk_css_token_source_new_at (source);
|
||||
|
||||
token = gtk_css_token_source_get_token (at_source);
|
||||
if (token->type != GTK_CSS_TOKEN_AT_KEYWORD)
|
||||
{
|
||||
gtk_css_token_source_error (at_source, "Expected an '@'");
|
||||
gtk_css_token_source_unref (at_source);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *name = token->string.string;
|
||||
|
||||
if (g_ascii_strcasecmp (name, "import") == 0)
|
||||
{
|
||||
gtk_css_token_source_error (source, "Add code to parse @import here");
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_source_unknown (source, "Unknown rule @%s", name);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_css_token_source_consume_all (at_source);
|
||||
gtk_css_token_source_unref (at_source);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_rule_print_css_text (GtkCssRule *rule,
|
||||
GString *string)
|
||||
{
|
||||
GtkCssRuleClass *klass;
|
||||
|
||||
g_return_if_fail (GTK_IS_CSS_RULE (rule));
|
||||
g_return_if_fail (string != NULL);
|
||||
|
||||
klass = GTK_CSS_RULE_GET_CLASS (rule);
|
||||
|
||||
klass->get_css_text (rule, string);
|
||||
}
|
||||
|
||||
char *
|
||||
gtk_css_rule_get_css_text (GtkCssRule *rule)
|
||||
{
|
||||
GString *string;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CSS_RULE (rule), NULL);
|
||||
|
||||
string = g_string_new (NULL);
|
||||
|
||||
gtk_css_rule_print_css_text (rule, string);
|
||||
|
||||
return g_string_free (string, FALSE);
|
||||
}
|
||||
|
||||
GtkCssRule *
|
||||
gtk_css_rule_get_parent_rule (GtkCssRule *rule)
|
||||
{
|
||||
GtkCssRulePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CSS_RULE (rule), NULL);
|
||||
|
||||
priv = gtk_css_rule_get_instance_private (rule);
|
||||
|
||||
return priv->parent_rule;
|
||||
}
|
||||
|
||||
GtkCssStyleSheet *
|
||||
gtk_css_rule_get_parent_style_sheet (GtkCssRule *rule)
|
||||
{
|
||||
GtkCssRulePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CSS_RULE (rule), NULL);
|
||||
|
||||
priv = gtk_css_rule_get_instance_private (rule);
|
||||
|
||||
return priv->parent_style_sheet;
|
||||
}
|
||||
166
gtk/gtkcssrulelist.c
Normal file
166
gtk/gtkcssrulelist.c
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* 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 "gtkcssrulelistprivate.h"
|
||||
#include "gtkcssstyleruleprivate.h"
|
||||
#include "gtkcssstylesheetprivate.h"
|
||||
|
||||
typedef struct _GtkCssRuleListPrivate GtkCssRuleListPrivate;
|
||||
struct _GtkCssRuleListPrivate {
|
||||
GPtrArray *items;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkCssRuleList, gtk_css_rule_list, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gtk_css_rule_list_finalize (GObject *object)
|
||||
{
|
||||
GtkCssRuleList *rule_list = GTK_CSS_RULE_LIST (object);
|
||||
GtkCssRuleListPrivate *priv = gtk_css_rule_list_get_instance_private (rule_list);
|
||||
|
||||
g_ptr_array_unref (priv->items);
|
||||
|
||||
G_OBJECT_CLASS (gtk_css_rule_list_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_rule_list_class_init (GtkCssRuleListClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gtk_css_rule_list_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_rule_list_init (GtkCssRuleList *rule_list)
|
||||
{
|
||||
GtkCssRuleListPrivate *priv = gtk_css_rule_list_get_instance_private (rule_list);
|
||||
|
||||
priv->items = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
}
|
||||
|
||||
GtkCssRuleList *
|
||||
gtk_css_rule_list_new (void)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_CSS_RULE_LIST, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_rule_list_parse (GtkCssRuleList *rule_list,
|
||||
GtkCssTokenSource *source,
|
||||
GtkCssRule *parent_rule,
|
||||
GtkCssStyleSheet *parent_style_sheet)
|
||||
{
|
||||
GtkCssRule *rule;
|
||||
const GtkCssToken *token;
|
||||
|
||||
g_return_if_fail (GTK_IS_CSS_RULE_LIST (rule_list));
|
||||
g_return_if_fail (source != NULL);
|
||||
g_return_if_fail (parent_rule == NULL || GTK_IS_CSS_RULE (parent_rule));
|
||||
g_return_if_fail (GTK_IS_CSS_STYLE_SHEET (parent_style_sheet));
|
||||
|
||||
for (token = gtk_css_token_source_get_token (source);
|
||||
token->type != GTK_CSS_TOKEN_EOF;
|
||||
token = gtk_css_token_source_get_token (source))
|
||||
{
|
||||
switch (token->type)
|
||||
{
|
||||
case GTK_CSS_TOKEN_WHITESPACE:
|
||||
gtk_css_token_source_consume_token (source);
|
||||
break;
|
||||
|
||||
case GTK_CSS_TOKEN_AT_KEYWORD:
|
||||
rule = gtk_css_rule_new_from_at_rule (source, parent_rule, parent_style_sheet);
|
||||
if (rule)
|
||||
gtk_css_rule_list_append (rule_list, rule);
|
||||
break;
|
||||
|
||||
case GTK_CSS_TOKEN_CDO:
|
||||
case GTK_CSS_TOKEN_CDC:
|
||||
if (parent_rule == NULL)
|
||||
{
|
||||
gtk_css_token_source_consume_token (source);
|
||||
break;
|
||||
}
|
||||
/* else fall through */
|
||||
default:
|
||||
rule = gtk_css_style_rule_new_parse (source, parent_rule, parent_style_sheet);
|
||||
if (rule)
|
||||
gtk_css_rule_list_append (rule_list, rule);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_rule_list_insert (GtkCssRuleList *rule_list,
|
||||
gsize id,
|
||||
GtkCssRule *rule)
|
||||
{
|
||||
GtkCssRuleListPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_CSS_RULE_LIST (rule_list));
|
||||
g_return_if_fail (GTK_IS_CSS_RULE (rule));
|
||||
|
||||
priv = gtk_css_rule_list_get_instance_private (rule_list);
|
||||
|
||||
g_ptr_array_insert (priv->items, id, g_object_ref (rule));
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_rule_list_append (GtkCssRuleList *rule_list,
|
||||
GtkCssRule *rule)
|
||||
{
|
||||
GtkCssRuleListPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_CSS_RULE_LIST (rule_list));
|
||||
g_return_if_fail (GTK_IS_CSS_RULE (rule));
|
||||
|
||||
priv = gtk_css_rule_list_get_instance_private (rule_list);
|
||||
|
||||
g_ptr_array_add (priv->items, g_object_ref (rule));
|
||||
}
|
||||
|
||||
GtkCssRule *
|
||||
gtk_css_rule_list_get_item (GtkCssRuleList *rule_list,
|
||||
gsize id)
|
||||
{
|
||||
GtkCssRuleListPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CSS_RULE_LIST (rule_list), NULL);
|
||||
|
||||
priv = gtk_css_rule_list_get_instance_private (rule_list);
|
||||
g_return_val_if_fail (id < priv->items->len, NULL);
|
||||
|
||||
return g_ptr_array_index (priv->items, id);
|
||||
}
|
||||
|
||||
gsize
|
||||
gtk_css_rule_list_get_length (GtkCssRuleList *rule_list)
|
||||
{
|
||||
GtkCssRuleListPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CSS_RULE_LIST (rule_list), 0);
|
||||
|
||||
priv = gtk_css_rule_list_get_instance_private (rule_list);
|
||||
|
||||
return priv->items->len;
|
||||
}
|
||||
69
gtk/gtkcssrulelistprivate.h
Normal file
69
gtk/gtkcssrulelistprivate.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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_RULE_LIST_PRIVATE_H__
|
||||
#define __GTK_CSS_RULE_LIST_PRIVATE_H__
|
||||
|
||||
#include "gtk/gtkcssruleprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_CSS_RULE_LIST (gtk_css_rule_list_get_type ())
|
||||
#define GTK_CSS_RULE_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_RULE_LIST, GtkCssRuleList))
|
||||
#define GTK_CSS_RULE_LIST_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_RULE_LIST, GtkCssRuleListClass))
|
||||
#define GTK_IS_CSS_RULE_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_RULE_LIST))
|
||||
#define GTK_IS_CSS_RULE_LIST_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_RULE_LIST))
|
||||
#define GTK_CSS_RULE_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_RULE_LIST, GtkCssRuleListClass))
|
||||
|
||||
typedef struct _GtkCssRuleList GtkCssRuleList;
|
||||
typedef struct _GtkCssRuleListClass GtkCssRuleListClass;
|
||||
|
||||
struct _GtkCssRuleList
|
||||
{
|
||||
GObject parent;
|
||||
};
|
||||
|
||||
struct _GtkCssRuleListClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_css_rule_list_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkCssRuleList * gtk_css_rule_list_new (void);
|
||||
|
||||
void gtk_css_rule_list_parse (GtkCssRuleList *rule_list,
|
||||
GtkCssTokenSource *source,
|
||||
GtkCssRule *parent_rule,
|
||||
GtkCssStyleSheet *parent_style_sheet);
|
||||
void gtk_css_rule_list_insert (GtkCssRuleList *rule_list,
|
||||
gsize id,
|
||||
GtkCssRule *rule);
|
||||
void gtk_css_rule_list_append (GtkCssRuleList *rule_list,
|
||||
GtkCssRule *rule);
|
||||
|
||||
/* GtkCSSRule DOM */
|
||||
GtkCssRule * gtk_css_rule_list_get_item (GtkCssRuleList *rule_list,
|
||||
gsize id);
|
||||
gsize gtk_css_rule_list_get_length (GtkCssRuleList *rule_list);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_RULE_LIST_PRIVATE_H__ */
|
||||
70
gtk/gtkcssruleprivate.h
Normal file
70
gtk/gtkcssruleprivate.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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_RULE_PRIVATE_H__
|
||||
#define __GTK_CSS_RULE_PRIVATE_H__
|
||||
|
||||
#include "gtk/gtkcsstokensourceprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_CSS_RULE (gtk_css_rule_get_type ())
|
||||
#define GTK_CSS_RULE(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_RULE, GtkCssRule))
|
||||
#define GTK_CSS_RULE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_RULE, GtkCssRuleClass))
|
||||
#define GTK_IS_CSS_RULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_RULE))
|
||||
#define GTK_IS_CSS_RULE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_RULE))
|
||||
#define GTK_CSS_RULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_RULE, GtkCssRuleClass))
|
||||
|
||||
/* forward declaration */
|
||||
typedef struct _GtkCssStyleSheet GtkCssStyleSheet;
|
||||
|
||||
typedef struct _GtkCssRule GtkCssRule;
|
||||
typedef struct _GtkCssRuleClass GtkCssRuleClass;
|
||||
|
||||
struct _GtkCssRule
|
||||
{
|
||||
GObject parent;
|
||||
};
|
||||
|
||||
struct _GtkCssRuleClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* gets the cssText for this rule */
|
||||
void (* get_css_text) (GtkCssRule *rule,
|
||||
GString *string);
|
||||
};
|
||||
|
||||
GType gtk_css_rule_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkCssRule * gtk_css_rule_new_from_at_rule (GtkCssTokenSource *source,
|
||||
GtkCssRule *parent_rule,
|
||||
GtkCssStyleSheet *parent_style_sheet);
|
||||
|
||||
void gtk_css_rule_print_css_text (GtkCssRule *rule,
|
||||
GString *string);
|
||||
char * gtk_css_rule_get_css_text (GtkCssRule *rule);
|
||||
|
||||
GtkCssRule * gtk_css_rule_get_parent_rule (GtkCssRule *rule);
|
||||
GtkCssStyleSheet * gtk_css_rule_get_parent_style_sheet (GtkCssRule *rule);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_RULE_PRIVATE_H__ */
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "gtkcssprovider.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1500
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
@@ -1102,42 +1104,42 @@ parse_selector_pseudo_class_nth_child (GtkCssParser *parser,
|
||||
return selector;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
gboolean deprecated;
|
||||
GtkStateFlags state_flag;
|
||||
PositionType position_type;
|
||||
int position_a;
|
||||
int position_b;
|
||||
} pseudo_classes[] = {
|
||||
{ "first-child", 0, 0, POSITION_FORWARD, 0, 1 },
|
||||
{ "last-child", 0, 0, POSITION_BACKWARD, 0, 1 },
|
||||
{ "only-child", 0, 0, POSITION_ONLY, 0, 0 },
|
||||
{ "sorted", 1, 0, POSITION_SORTED, 0, 0 },
|
||||
{ "active", 0, GTK_STATE_FLAG_ACTIVE, },
|
||||
{ "prelight", 1, GTK_STATE_FLAG_PRELIGHT, },
|
||||
{ "hover", 0, GTK_STATE_FLAG_PRELIGHT, },
|
||||
{ "selected", 0, GTK_STATE_FLAG_SELECTED, },
|
||||
{ "insensitive", 1, GTK_STATE_FLAG_INSENSITIVE, },
|
||||
{ "disabled", 0, GTK_STATE_FLAG_INSENSITIVE, },
|
||||
{ "inconsistent", 1, GTK_STATE_FLAG_INCONSISTENT, },
|
||||
{ "indeterminate", 0, GTK_STATE_FLAG_INCONSISTENT, },
|
||||
{ "focused", 1, GTK_STATE_FLAG_FOCUSED, },
|
||||
{ "focus", 0, GTK_STATE_FLAG_FOCUSED, },
|
||||
{ "backdrop", 0, GTK_STATE_FLAG_BACKDROP, },
|
||||
{ "dir(ltr)", 0, GTK_STATE_FLAG_DIR_LTR, },
|
||||
{ "dir(rtl)", 0, GTK_STATE_FLAG_DIR_RTL, },
|
||||
{ "link", 0, GTK_STATE_FLAG_LINK, },
|
||||
{ "visited", 0, GTK_STATE_FLAG_VISITED, },
|
||||
{ "checked", 0, GTK_STATE_FLAG_CHECKED, },
|
||||
{ "drop(active)", 0, GTK_STATE_FLAG_DROP_ACTIVE, }
|
||||
};
|
||||
|
||||
static GtkCssSelector *
|
||||
parse_selector_pseudo_class (GtkCssParser *parser,
|
||||
GtkCssSelector *selector,
|
||||
gboolean negate)
|
||||
{
|
||||
static const struct {
|
||||
const char *name;
|
||||
gboolean deprecated;
|
||||
GtkStateFlags state_flag;
|
||||
PositionType position_type;
|
||||
int position_a;
|
||||
int position_b;
|
||||
} pseudo_classes[] = {
|
||||
{ "first-child", 0, 0, POSITION_FORWARD, 0, 1 },
|
||||
{ "last-child", 0, 0, POSITION_BACKWARD, 0, 1 },
|
||||
{ "only-child", 0, 0, POSITION_ONLY, 0, 0 },
|
||||
{ "sorted", 1, 0, POSITION_SORTED, 0, 0 },
|
||||
{ "active", 0, GTK_STATE_FLAG_ACTIVE, },
|
||||
{ "prelight", 1, GTK_STATE_FLAG_PRELIGHT, },
|
||||
{ "hover", 0, GTK_STATE_FLAG_PRELIGHT, },
|
||||
{ "selected", 0, GTK_STATE_FLAG_SELECTED, },
|
||||
{ "insensitive", 1, GTK_STATE_FLAG_INSENSITIVE, },
|
||||
{ "disabled", 0, GTK_STATE_FLAG_INSENSITIVE, },
|
||||
{ "inconsistent", 1, GTK_STATE_FLAG_INCONSISTENT, },
|
||||
{ "indeterminate", 0, GTK_STATE_FLAG_INCONSISTENT, },
|
||||
{ "focused", 1, GTK_STATE_FLAG_FOCUSED, },
|
||||
{ "focus", 0, GTK_STATE_FLAG_FOCUSED, },
|
||||
{ "backdrop", 0, GTK_STATE_FLAG_BACKDROP, },
|
||||
{ "dir(ltr)", 0, GTK_STATE_FLAG_DIR_LTR, },
|
||||
{ "dir(rtl)", 0, GTK_STATE_FLAG_DIR_RTL, },
|
||||
{ "link", 0, GTK_STATE_FLAG_LINK, },
|
||||
{ "visited", 0, GTK_STATE_FLAG_VISITED, },
|
||||
{ "checked", 0, GTK_STATE_FLAG_CHECKED, },
|
||||
{ "drop(active)", 0, GTK_STATE_FLAG_DROP_ACTIVE, }
|
||||
|
||||
};
|
||||
guint i;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "nth-child", FALSE))
|
||||
@@ -1305,6 +1307,539 @@ _gtk_css_selector_parse (GtkCssParser *parser)
|
||||
return selector;
|
||||
}
|
||||
|
||||
GtkCssSelector *
|
||||
token_parse_selector_class (GtkCssTokenSource *source,
|
||||
GtkCssSelector *selector,
|
||||
gboolean negate)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
|
||||
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))
|
||||
{
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_CLASS
|
||||
: >K_CSS_SELECTOR_CLASS,
|
||||
selector);
|
||||
selector->style_class.style_class = g_quark_from_string (token->string.string);
|
||||
gtk_css_token_source_consume_token (source);
|
||||
return selector;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_source_error (source, "No class name after '.' in selector");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_plus_b (GtkCssTokenSource *source,
|
||||
gboolean negate,
|
||||
gint *b)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
gboolean has_seen_sign;
|
||||
|
||||
gtk_css_token_source_consume_whitespace (source);
|
||||
token = gtk_css_token_source_get_token (source);
|
||||
|
||||
if (negate)
|
||||
{
|
||||
has_seen_sign = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gtk_css_token_is_delim (token, '+'))
|
||||
{
|
||||
gtk_css_token_source_consume_token (source);
|
||||
gtk_css_token_source_consume_whitespace (source);
|
||||
has_seen_sign = TRUE;
|
||||
}
|
||||
else if (gtk_css_token_is_delim (token, '-'))
|
||||
{
|
||||
gtk_css_token_source_consume_token (source);
|
||||
gtk_css_token_source_consume_whitespace (source);
|
||||
negate = TRUE;
|
||||
has_seen_sign = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
token = gtk_css_token_source_get_token (source);
|
||||
if (gtk_css_token_is (token, GTK_CSS_TOKEN_INTEGER))
|
||||
{
|
||||
if (has_seen_sign && token->number.number >= 0)
|
||||
{
|
||||
*b = token->number.number;
|
||||
if (negate)
|
||||
*b = - *b;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
gtk_css_token_source_error (source, "Not a valid an+b type");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
parse_a_n_plus_b (GtkCssTokenSource *source,
|
||||
gint *a,
|
||||
gint *b)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
|
||||
token = gtk_css_token_source_get_token (source);
|
||||
|
||||
if (gtk_css_token_is_ident (token, "even"))
|
||||
{
|
||||
*a = 2;
|
||||
*b = 0;
|
||||
gtk_css_token_source_consume_token (source);
|
||||
return TRUE;
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "odd"))
|
||||
{
|
||||
*a = 2;
|
||||
*b = 1;
|
||||
gtk_css_token_source_consume_token (source);
|
||||
return TRUE;
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_INTEGER))
|
||||
{
|
||||
*a = 0;
|
||||
*b = token->number.number;
|
||||
gtk_css_token_source_consume_token (source);
|
||||
return TRUE;
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_INTEGER_DIMENSION) &&
|
||||
g_ascii_strcasecmp (token->dimension.dimension, "n") == 0)
|
||||
{
|
||||
*a = token->dimension.value;
|
||||
gtk_css_token_source_consume_token (source);
|
||||
return parse_plus_b (source, FALSE, b);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_INTEGER_DIMENSION) &&
|
||||
g_ascii_strcasecmp (token->dimension.dimension, "n-") == 0)
|
||||
{
|
||||
*a = token->dimension.value;
|
||||
gtk_css_token_source_consume_token (source);
|
||||
return parse_plus_b (source, TRUE, b);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_INTEGER_DIMENSION) &&
|
||||
g_ascii_strncasecmp (token->dimension.dimension, "n-", 2) == 0)
|
||||
{
|
||||
char *end;
|
||||
*a = token->dimension.value;
|
||||
errno = 0;
|
||||
*b = strtoul (token->dimension.dimension + 2, &end, 10);
|
||||
if (*end == '\0' && errno == 0)
|
||||
{
|
||||
gtk_css_token_source_consume_token (source);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "-n"))
|
||||
{
|
||||
*a = -1;
|
||||
gtk_css_token_source_consume_token (source);
|
||||
return parse_plus_b (source, FALSE, b);
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "-n-"))
|
||||
{
|
||||
*a = -1;
|
||||
gtk_css_token_source_consume_token (source);
|
||||
return parse_plus_b (source, TRUE, b);
|
||||
}
|
||||
|
||||
gtk_css_token_source_error (source, "Not a valid an+b type");
|
||||
return FALSE;
|
||||
}
|
||||
GtkCssSelector *
|
||||
token_parse_selector_pseudo_class (GtkCssTokenSource *source,
|
||||
GtkCssSelector *selector,
|
||||
gboolean negate)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
|
||||
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))
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (pseudo_classes); i++)
|
||||
{
|
||||
if (g_ascii_strcasecmp (pseudo_classes[i].name, token->string.string) == 0)
|
||||
{
|
||||
if (pseudo_classes[i].state_flag)
|
||||
{
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_STATE
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_STATE,
|
||||
selector);
|
||||
selector->state.state = pseudo_classes[i].state_flag;
|
||||
if (pseudo_classes[i].deprecated)
|
||||
{
|
||||
if (pseudo_classes[i + 1].state_flag == pseudo_classes[i].state_flag)
|
||||
gtk_css_token_source_deprecated (source,
|
||||
"The :%s pseudo-class is deprecated. Use :%s instead.",
|
||||
pseudo_classes[i].name,
|
||||
pseudo_classes[i + 1].name);
|
||||
else
|
||||
gtk_css_token_source_deprecated (source,
|
||||
"The :%s pseudo-class is deprecated.",
|
||||
pseudo_classes[i].name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_POSITION
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_POSITION,
|
||||
selector);
|
||||
selector->position.type = pseudo_classes[i].position_type;
|
||||
selector->position.a = pseudo_classes[i].position_a;
|
||||
selector->position.b = pseudo_classes[i].position_b;
|
||||
}
|
||||
gtk_css_token_source_consume_token (source);
|
||||
return selector;
|
||||
}
|
||||
}
|
||||
|
||||
gtk_css_token_source_unknown (source, "Unknown name of pseudo-class");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_FUNCTION))
|
||||
{
|
||||
gint a, b;
|
||||
|
||||
if (gtk_css_token_is_function (token, "nth-child"))
|
||||
{
|
||||
gtk_css_token_source_consume_token (source);
|
||||
if (parse_a_n_plus_b (source, &a, &b))
|
||||
{
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_POSITION
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_POSITION,
|
||||
selector);
|
||||
selector->position.type = POSITION_FORWARD;
|
||||
selector->position.a = a;
|
||||
selector->position.b = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
gtk_css_token_source_consume_whitespace (source);
|
||||
token = gtk_css_token_source_get_token (source);
|
||||
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_CLOSE_PARENS))
|
||||
{
|
||||
gtk_css_token_source_error (source, "Expected ')' at end of :nth-child()");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "nth-last-child"))
|
||||
{
|
||||
gtk_css_token_source_consume_token (source);
|
||||
if (parse_a_n_plus_b (source, &a, &b))
|
||||
{
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_POSITION
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_POSITION,
|
||||
selector);
|
||||
selector->position.type = POSITION_BACKWARD;
|
||||
selector->position.a = a;
|
||||
selector->position.b = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
gtk_css_token_source_consume_whitespace (source);
|
||||
token = gtk_css_token_source_get_token (source);
|
||||
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_CLOSE_PARENS))
|
||||
{
|
||||
gtk_css_token_source_error (source, "Expected ')' at end of :nth-last-child()");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "not"))
|
||||
{
|
||||
if (negate)
|
||||
{
|
||||
gtk_css_token_source_error (source, "Nesting of :not() not allowed");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_source_consume_token (source);
|
||||
token = gtk_css_token_source_get_token (source);
|
||||
|
||||
if (gtk_css_token_is_delim (token, '*'))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_ANY, selector);
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_NOT_NAME, selector);
|
||||
selector->name.name = g_intern_string (token->string.string);
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_NOT_ID, selector);
|
||||
selector->id.name = g_intern_string (token->string.string);
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else if (gtk_css_token_is_delim (token, '.'))
|
||||
{
|
||||
selector = token_parse_selector_class (source, selector, TRUE);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_COLON))
|
||||
{
|
||||
selector = token_parse_selector_pseudo_class (source, selector, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_source_error (source, "Invalid contents of :not() selector");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
selector = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gtk_css_token_source_consume_whitespace (source);
|
||||
token = gtk_css_token_source_get_token (source);
|
||||
if (gtk_css_token_is (token, GTK_CSS_TOKEN_CLOSE_PARENS))
|
||||
{
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_source_error (source, "Invalid contents of :not() selector");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
selector = NULL;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "dir"))
|
||||
{
|
||||
gtk_css_token_source_consume_token (source);
|
||||
gtk_css_token_source_consume_whitespace (source);
|
||||
token = gtk_css_token_source_get_token (source);
|
||||
if (gtk_css_token_is_ident (token, "ltr"))
|
||||
{
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_STATE
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_STATE,
|
||||
selector);
|
||||
selector->state.state = GTK_STATE_FLAG_DIR_LTR;
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "rtl"))
|
||||
{
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_STATE
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_STATE,
|
||||
selector);
|
||||
selector->state.state = GTK_STATE_FLAG_DIR_LTR;
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_source_error (source, "Expected :dir(ltr) or :dir(rtl)");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
selector = NULL;
|
||||
return NULL;
|
||||
}
|
||||
gtk_css_token_source_consume_whitespace (source);
|
||||
token = gtk_css_token_source_get_token (source);
|
||||
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_CLOSE_PARENS))
|
||||
{
|
||||
gtk_css_token_source_error (source, "Expected ')' at end of :dir()");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "drop"))
|
||||
{
|
||||
gtk_css_token_source_consume_token (source);
|
||||
gtk_css_token_source_consume_whitespace (source);
|
||||
token = gtk_css_token_source_get_token (source);
|
||||
if (gtk_css_token_is_ident (token, "active"))
|
||||
{
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_PSEUDOCLASS_STATE
|
||||
: >K_CSS_SELECTOR_PSEUDOCLASS_STATE,
|
||||
selector);
|
||||
selector->state.state = GTK_STATE_FLAG_DROP_ACTIVE;
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_source_error (source, "Expected :drop(active)");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
selector = NULL;
|
||||
return NULL;
|
||||
}
|
||||
gtk_css_token_source_consume_whitespace (source);
|
||||
token = gtk_css_token_source_get_token (source);
|
||||
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_CLOSE_PARENS))
|
||||
{
|
||||
gtk_css_token_source_error (source, "Expected ')' at end of :drop()");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_source_unknown (source, "Unknown pseudoclass");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_source_error (source, "Unknown pseudoclass");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return selector;
|
||||
}
|
||||
|
||||
GtkCssSelector *
|
||||
token_parse_simple_selector (GtkCssTokenSource *source,
|
||||
GtkCssSelector *selector)
|
||||
{
|
||||
gboolean parsed_something = FALSE;
|
||||
const GtkCssToken *token;
|
||||
|
||||
do {
|
||||
token = gtk_css_token_source_get_token (source);
|
||||
|
||||
if (!parsed_something && gtk_css_token_is_delim (token, '*'))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_ANY, selector);
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else if (!parsed_something && gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_NAME, selector);
|
||||
selector->name.name = g_intern_string (token->string.string);
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_ID, selector);
|
||||
selector->id.name = g_intern_string (token->string.string);
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else if (gtk_css_token_is_delim (token, '.'))
|
||||
{
|
||||
selector = token_parse_selector_class (source, selector, FALSE);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_COLON))
|
||||
{
|
||||
selector = token_parse_selector_pseudo_class (source, selector, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!parsed_something)
|
||||
{
|
||||
gtk_css_token_source_error (source, "Expected a valid selector");
|
||||
if (selector)
|
||||
_gtk_css_selector_free (selector);
|
||||
selector = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
parsed_something = TRUE;
|
||||
}
|
||||
while (TRUE);
|
||||
|
||||
return selector;
|
||||
}
|
||||
|
||||
GtkCssSelector *
|
||||
gtk_css_selector_token_parse (GtkCssTokenSource *source)
|
||||
{
|
||||
GtkCssSelector *selector = NULL;
|
||||
const GtkCssToken *token;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
gboolean seen_whitespace = FALSE;
|
||||
|
||||
selector = token_parse_simple_selector (source, selector);
|
||||
if (selector == NULL)
|
||||
{
|
||||
gtk_css_token_source_consume_all (source);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
seen_whitespace = gtk_css_token_source_consume_whitespace (source);
|
||||
token = gtk_css_token_source_get_token (source);
|
||||
|
||||
if (gtk_css_token_is_delim (token, '+'))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_ADJACENT, selector);
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else if (gtk_css_token_is_delim (token, '~'))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_SIBLING, selector);
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else if (gtk_css_token_is_delim (token, '>'))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_CHILD, selector);
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (seen_whitespace)
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_DESCENDANT, selector);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_source_error (source, "Expected a valid selector");
|
||||
_gtk_css_selector_free (selector);
|
||||
gtk_css_token_source_consume_all (source);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gtk_css_token_source_consume_whitespace (source);
|
||||
}
|
||||
|
||||
return selector;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_css_selector_free (GtkCssSelector *selector)
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "gtk/gtkcssmatcherprivate.h"
|
||||
#include "gtk/gtkcssparserprivate.h"
|
||||
#include "gtk/gtkcsstokensourceprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -28,6 +29,7 @@ typedef struct _GtkCssSelectorTree GtkCssSelectorTree;
|
||||
typedef struct _GtkCssSelectorTreeBuilder GtkCssSelectorTreeBuilder;
|
||||
|
||||
GtkCssSelector * _gtk_css_selector_parse (GtkCssParser *parser);
|
||||
GtkCssSelector * gtk_css_selector_token_parse (GtkCssTokenSource *parser);
|
||||
void _gtk_css_selector_free (GtkCssSelector *selector);
|
||||
|
||||
char * _gtk_css_selector_to_string (const GtkCssSelector *selector);
|
||||
|
||||
66
gtk/gtkcssstyledeclaration.c
Normal file
66
gtk/gtkcssstyledeclaration.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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 "gtkcssstyledeclarationprivate.h"
|
||||
|
||||
#include "gtkcssselectorprivate.h"
|
||||
#include "gtkcssstylesheetprivate.h"
|
||||
|
||||
typedef struct _GtkCssStyleDeclarationPrivate GtkCssStyleDeclarationPrivate;
|
||||
struct _GtkCssStyleDeclarationPrivate {
|
||||
GPtrArray *declarations;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkCssStyleDeclaration, gtk_css_style_declaration, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gtk_css_style_declaration_finalize (GObject *object)
|
||||
{
|
||||
GtkCssStyleDeclaration *style_declaration = GTK_CSS_STYLE_DECLARATION (object);
|
||||
GtkCssStyleDeclarationPrivate *priv = gtk_css_style_declaration_get_instance_private (style_declaration);
|
||||
|
||||
g_ptr_array_unref (priv->declarations);
|
||||
|
||||
G_OBJECT_CLASS (gtk_css_style_declaration_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_style_declaration_class_init (GtkCssStyleDeclarationClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gtk_css_style_declaration_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_style_declaration_init (GtkCssStyleDeclaration *style_declaration)
|
||||
{
|
||||
GtkCssStyleDeclarationPrivate *priv = gtk_css_style_declaration_get_instance_private (style_declaration);
|
||||
|
||||
priv->declarations = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
}
|
||||
|
||||
GtkCssStyleDeclaration *
|
||||
gtk_css_style_declaration_new (GtkCssRule *parent_rule)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_CSS_STYLE_DECLARATION, NULL);
|
||||
}
|
||||
|
||||
61
gtk/gtkcssstyledeclarationprivate.h
Normal file
61
gtk/gtkcssstyledeclarationprivate.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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_STYLE_DECLARATION_PRIVATE_H__
|
||||
#define __GTK_CSS_STYLE_DECLARATION_PRIVATE_H__
|
||||
|
||||
#include "gtk/gtkcssruleprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_CSS_STYLE_DECLARATION (gtk_css_style_declaration_get_type ())
|
||||
#define GTK_CSS_STYLE_DECLARATION(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_STYLE_DECLARATION, GtkCssStyleDeclaration))
|
||||
#define GTK_CSS_STYLE_DECLARATION_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_STYLE_DECLARATION, GtkCssStyleDeclarationClass))
|
||||
#define GTK_IS_CSS_STYLE_DECLARATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_STYLE_DECLARATION))
|
||||
#define GTK_IS_CSS_STYLE_DECLARATION_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_STYLE_DECLARATION))
|
||||
#define GTK_CSS_STYLE_DECLARATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_STYLE_DECLARATION, GtkCssStyleDeclarationClass))
|
||||
|
||||
typedef struct _GtkCssStyleDeclaration GtkCssStyleDeclaration;
|
||||
typedef struct _GtkCssStyleDeclarationClass GtkCssStyleDeclarationClass;
|
||||
|
||||
struct _GtkCssStyleDeclaration
|
||||
{
|
||||
GObject parent;
|
||||
};
|
||||
|
||||
struct _GtkCssStyleDeclarationClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_css_style_declaration_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkCssStyleDeclaration *gtk_css_style_declaration_new (GtkCssRule *parent_rule);
|
||||
|
||||
void gtk_css_style_declaration_print_css_text (GtkCssStyleDeclaration *declaration,
|
||||
GString *string);
|
||||
char * gtk_css_style_declaration_get_css_text (GtkCssStyleDeclaration *declaration);
|
||||
|
||||
/* GtkCssStyleDeclaration DOM */
|
||||
gsize gtk_css_style_declaration_get_length (GtkCssStyleDeclaration *declaration);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_STYLE_DECLARATION_PRIVATE_H__ */
|
||||
124
gtk/gtkcssstylerule.c
Normal file
124
gtk/gtkcssstylerule.c
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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 "gtkcssstyleruleprivate.h"
|
||||
|
||||
#include "gtkcssselectorprivate.h"
|
||||
#include "gtkcssstylesheetprivate.h"
|
||||
|
||||
typedef struct _GtkCssStyleRulePrivate GtkCssStyleRulePrivate;
|
||||
struct _GtkCssStyleRulePrivate {
|
||||
GPtrArray *selectors;
|
||||
//GtkCssStyleDeclaration *declaration;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkCssStyleRule, gtk_css_style_rule, GTK_TYPE_CSS_RULE)
|
||||
|
||||
static void
|
||||
gtk_css_style_rule_finalize (GObject *object)
|
||||
{
|
||||
GtkCssStyleRule *style_rule = GTK_CSS_STYLE_RULE (object);
|
||||
GtkCssStyleRulePrivate *priv = gtk_css_style_rule_get_instance_private (style_rule);
|
||||
|
||||
g_ptr_array_unref (priv->selectors);
|
||||
|
||||
G_OBJECT_CLASS (gtk_css_style_rule_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_style_rule_class_init (GtkCssStyleRuleClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gtk_css_style_rule_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_style_rule_init (GtkCssStyleRule *style_rule)
|
||||
{
|
||||
GtkCssStyleRulePrivate *priv = gtk_css_style_rule_get_instance_private (style_rule);
|
||||
|
||||
priv->selectors = g_ptr_array_new_with_free_func ((GDestroyNotify) _gtk_css_selector_free);
|
||||
}
|
||||
|
||||
static GtkCssRule *
|
||||
gtk_css_style_rule_new (GtkCssRule *parent_rule,
|
||||
GtkCssStyleSheet *parent_style_sheet)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_CSS_STYLE_RULE, NULL);
|
||||
}
|
||||
|
||||
static GtkCssStyleRule *
|
||||
gtk_css_style_rule_parse_selectors (GtkCssStyleRule *rule,
|
||||
GtkCssTokenSource *source)
|
||||
{
|
||||
GtkCssStyleRulePrivate *priv = gtk_css_style_rule_get_instance_private (rule);
|
||||
GtkCssTokenSource *child_source;
|
||||
GtkCssSelector *selector;
|
||||
const GtkCssToken *token;
|
||||
|
||||
for (token = gtk_css_token_source_get_token (source);
|
||||
!gtk_css_token_is (token, GTK_CSS_TOKEN_EOF);
|
||||
token = gtk_css_token_source_get_token (source))
|
||||
{
|
||||
gtk_css_token_source_consume_whitespace (source);
|
||||
child_source = gtk_css_token_source_new_for_part (source, GTK_CSS_TOKEN_COMMA);
|
||||
selector = gtk_css_selector_token_parse (child_source);
|
||||
gtk_css_token_source_unref (child_source);
|
||||
if (selector == NULL)
|
||||
{
|
||||
g_object_unref (rule);
|
||||
return NULL;
|
||||
}
|
||||
g_ptr_array_add (priv->selectors, selector);
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
|
||||
return rule;
|
||||
}
|
||||
|
||||
GtkCssRule *
|
||||
gtk_css_style_rule_new_parse (GtkCssTokenSource *source,
|
||||
GtkCssRule *parent_rule,
|
||||
GtkCssStyleSheet *parent_style_sheet)
|
||||
{
|
||||
GtkCssTokenSource *child_source;
|
||||
GtkCssStyleRule *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_STYLE_RULE (gtk_css_style_rule_new (parent_rule, parent_style_sheet));
|
||||
|
||||
child_source = gtk_css_token_source_new_for_part (source, GTK_CSS_TOKEN_OPEN_CURLY);
|
||||
rule = gtk_css_style_rule_parse_selectors (rule, child_source);
|
||||
gtk_css_token_source_unref (child_source);
|
||||
|
||||
gtk_css_token_source_consume_token (source);
|
||||
child_source = gtk_css_token_source_new_for_part (source, GTK_CSS_TOKEN_CLOSE_CURLY);
|
||||
gtk_css_token_source_consume_all (child_source);
|
||||
gtk_css_token_source_unref (child_source);
|
||||
gtk_css_token_source_consume_token (source);
|
||||
|
||||
return GTK_CSS_RULE (rule);
|
||||
}
|
||||
|
||||
56
gtk/gtkcssstyleruleprivate.h
Normal file
56
gtk/gtkcssstyleruleprivate.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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_STYLE_RULE_PRIVATE_H__
|
||||
#define __GTK_CSS_STYLE_RULE_PRIVATE_H__
|
||||
|
||||
#include "gtk/gtkcssruleprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_CSS_STYLE_RULE (gtk_css_style_rule_get_type ())
|
||||
#define GTK_CSS_STYLE_RULE(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_STYLE_RULE, GtkCssStyleRule))
|
||||
#define GTK_CSS_STYLE_RULE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_STYLE_RULE, GtkCssStyleRuleClass))
|
||||
#define GTK_IS_CSS_STYLE_RULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_STYLE_RULE))
|
||||
#define GTK_IS_CSS_STYLE_RULE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_STYLE_RULE))
|
||||
#define GTK_CSS_STYLE_RULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_STYLE_RULE, GtkCssStyleRuleClass))
|
||||
|
||||
typedef struct _GtkCssStyleRule GtkCssStyleRule;
|
||||
typedef struct _GtkCssStyleRuleClass GtkCssStyleRuleClass;
|
||||
|
||||
struct _GtkCssStyleRule
|
||||
{
|
||||
GtkCssRule parent;
|
||||
};
|
||||
|
||||
struct _GtkCssStyleRuleClass
|
||||
{
|
||||
GtkCssRuleClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_css_style_rule_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkCssRule * gtk_css_style_rule_new_parse (GtkCssTokenSource *source,
|
||||
GtkCssRule *parent_rule,
|
||||
GtkCssStyleSheet *parent_style_sheet);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_STYLE_RULE_PRIVATE_H__ */
|
||||
114
gtk/gtkcssstylesheet.c
Normal file
114
gtk/gtkcssstylesheet.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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 "gtkcssstylesheetprivate.h"
|
||||
|
||||
typedef struct _GtkCssStyleSheetPrivate GtkCssStyleSheetPrivate;
|
||||
struct _GtkCssStyleSheetPrivate {
|
||||
GtkCssRule *parent_rule;
|
||||
GtkCssRuleList *css_rules;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkCssStyleSheet, gtk_css_style_sheet, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gtk_css_style_sheet_finalize (GObject *object)
|
||||
{
|
||||
GtkCssStyleSheet *style_sheet = GTK_CSS_STYLE_SHEET (object);
|
||||
GtkCssStyleSheetPrivate *priv = gtk_css_style_sheet_get_instance_private (style_sheet);
|
||||
|
||||
g_object_unref (priv->css_rules);
|
||||
|
||||
G_OBJECT_CLASS (gtk_css_style_sheet_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_style_sheet_class_init (GtkCssStyleSheetClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gtk_css_style_sheet_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_style_sheet_init (GtkCssStyleSheet *style_sheet)
|
||||
{
|
||||
GtkCssStyleSheetPrivate *priv = gtk_css_style_sheet_get_instance_private (style_sheet);
|
||||
|
||||
priv->css_rules = gtk_css_rule_list_new ();
|
||||
}
|
||||
|
||||
GtkCssStyleSheet *
|
||||
gtk_css_style_sheet_new (void)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_CSS_STYLE_SHEET, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_style_sheet_parse (GtkCssStyleSheet *style_sheet,
|
||||
GtkCssTokenSource *source)
|
||||
{
|
||||
GtkCssStyleSheetPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_CSS_STYLE_SHEET (style_sheet));
|
||||
g_return_if_fail (source != NULL);
|
||||
|
||||
priv = gtk_css_style_sheet_get_instance_private (style_sheet);
|
||||
|
||||
gtk_css_rule_list_parse (priv->css_rules, source, NULL, style_sheet);
|
||||
}
|
||||
|
||||
GtkCssStyleSheet *
|
||||
gtk_css_style_sheet_get_parent_style_sheet (GtkCssStyleSheet *style_sheet)
|
||||
{
|
||||
GtkCssStyleSheetPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CSS_STYLE_SHEET (style_sheet), NULL);
|
||||
|
||||
priv = gtk_css_style_sheet_get_instance_private (style_sheet);
|
||||
|
||||
return gtk_css_rule_get_parent_style_sheet (priv->parent_rule);
|
||||
}
|
||||
|
||||
GtkCssRule *
|
||||
gtk_css_style_sheet_get_parent_rule (GtkCssStyleSheet *style_sheet)
|
||||
{
|
||||
GtkCssStyleSheetPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CSS_STYLE_SHEET (style_sheet), NULL);
|
||||
|
||||
priv = gtk_css_style_sheet_get_instance_private (style_sheet);
|
||||
|
||||
return priv->parent_rule;
|
||||
}
|
||||
|
||||
GtkCssRuleList *
|
||||
gtk_css_style_sheet_get_css_rules (GtkCssStyleSheet *style_sheet)
|
||||
{
|
||||
GtkCssStyleSheetPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CSS_STYLE_SHEET (style_sheet), NULL);
|
||||
|
||||
priv = gtk_css_style_sheet_get_instance_private (style_sheet);
|
||||
|
||||
return priv->css_rules;
|
||||
}
|
||||
|
||||
67
gtk/gtkcssstylesheetprivate.h
Normal file
67
gtk/gtkcssstylesheetprivate.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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_STYLE_SHEET_PRIVATE_H__
|
||||
#define __GTK_CSS_STYLE_SHEET_PRIVATE_H__
|
||||
|
||||
#include "gtk/gtkcssruleprivate.h"
|
||||
#include "gtk/gtkcssrulelistprivate.h"
|
||||
#include "gtk/gtkcsstokensourceprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_CSS_STYLE_SHEET (gtk_css_style_sheet_get_type ())
|
||||
#define GTK_CSS_STYLE_SHEET(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_STYLE_SHEET, GtkCssStyleSheet))
|
||||
#define GTK_CSS_STYLE_SHEET_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_STYLE_SHEET, GtkCssStyleSheetClass))
|
||||
#define GTK_IS_CSS_STYLE_SHEET(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_STYLE_SHEET))
|
||||
#define GTK_IS_CSS_STYLE_SHEET_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_STYLE_SHEET))
|
||||
#define GTK_CSS_STYLE_SHEET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_STYLE_SHEET, GtkCssStyleSheetClass))
|
||||
|
||||
/* declared with GtkCssRule */
|
||||
/* typedef struct _GtkCssStyleSheet GtkCssStyleSheet; */
|
||||
typedef struct _GtkCssStyleSheetClass GtkCssStyleSheetClass;
|
||||
|
||||
struct _GtkCssStyleSheet
|
||||
{
|
||||
GObject parent;
|
||||
};
|
||||
|
||||
struct _GtkCssStyleSheetClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_css_style_sheet_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkCssStyleSheet * gtk_css_style_sheet_new (void);
|
||||
|
||||
void gtk_css_style_sheet_parse (GtkCssStyleSheet *style_sheet,
|
||||
GtkCssTokenSource *source);
|
||||
|
||||
/* StyleSheet interface */
|
||||
GtkCssStyleSheet * gtk_css_style_sheet_get_parent_style_sheet (GtkCssStyleSheet *style_sheet);
|
||||
|
||||
/* CSSStyleSheet interface */
|
||||
GtkCssRule * gtk_css_style_sheet_get_parent_rule (GtkCssStyleSheet *style_sheet);
|
||||
GtkCssRuleList * gtk_css_style_sheet_get_css_rules (GtkCssStyleSheet *style_sheet);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_STYLE_SHEET_PRIVATE_H__ */
|
||||
369
gtk/gtkcsstokensource.c
Normal file
369
gtk/gtkcsstokensource.c
Normal file
@@ -0,0 +1,369 @@
|
||||
/*
|
||||
* 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 "gtkcsstokensourceprivate.h"
|
||||
|
||||
#include "gtkcssprovider.h"
|
||||
|
||||
typedef struct _GtkCssTokenSourceTokenizer GtkCssTokenSourceTokenizer;
|
||||
struct _GtkCssTokenSourceTokenizer {
|
||||
GtkCssTokenSource parent;
|
||||
GtkCssTokenizer *tokenizer;
|
||||
GtkCssToken current_token;
|
||||
};
|
||||
|
||||
static void
|
||||
gtk_css_token_source_tokenizer_finalize (GtkCssTokenSource *source)
|
||||
{
|
||||
GtkCssTokenSourceTokenizer *tok = (GtkCssTokenSourceTokenizer *) source;
|
||||
|
||||
gtk_css_token_clear (&tok->current_token);
|
||||
gtk_css_tokenizer_unref (tok->tokenizer);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_token_source_tokenizer_consume_token (GtkCssTokenSource *source)
|
||||
{
|
||||
GtkCssTokenSourceTokenizer *tok = (GtkCssTokenSourceTokenizer *) source;
|
||||
|
||||
gtk_css_token_clear (&tok->current_token);
|
||||
}
|
||||
|
||||
static const GtkCssToken *
|
||||
gtk_css_token_source_tokenizer_get_token (GtkCssTokenSource *source)
|
||||
{
|
||||
GtkCssTokenSourceTokenizer *tok = (GtkCssTokenSourceTokenizer *) source;
|
||||
|
||||
if (gtk_css_token_is (&tok->current_token, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
do {
|
||||
gtk_css_tokenizer_read_token (tok->tokenizer, &tok->current_token);
|
||||
} while (gtk_css_token_is (&tok->current_token, GTK_CSS_TOKEN_COMMENT));
|
||||
|
||||
#if 0
|
||||
if (!gtk_css_token_is (&tok->current_token, GTK_CSS_TOKEN_EOF)) {
|
||||
char *s = gtk_css_token_to_string (&tok->current_token);
|
||||
g_print ("%3zu:%02zu %2d %s\n",
|
||||
gtk_css_tokenizer_get_line (tok->tokenizer), gtk_css_tokenizer_get_line_char (tok->tokenizer),
|
||||
tok->current_token.type, s);
|
||||
g_free (s);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return &tok->current_token;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_token_source_tokenizer_error (GtkCssTokenSource *source,
|
||||
const GError *error)
|
||||
{
|
||||
GtkCssTokenSourceTokenizer *tok = (GtkCssTokenSourceTokenizer *) source;
|
||||
|
||||
/* XXX */
|
||||
g_print ("ERROR: %zu:%zu: %s\n",
|
||||
gtk_css_tokenizer_get_line (tok->tokenizer),
|
||||
gtk_css_tokenizer_get_line_char (tok->tokenizer),
|
||||
error->message);
|
||||
}
|
||||
|
||||
const GtkCssTokenSourceClass GTK_CSS_TOKEN_SOURCE_TOKENIZER = {
|
||||
gtk_css_token_source_tokenizer_finalize,
|
||||
gtk_css_token_source_tokenizer_consume_token,
|
||||
gtk_css_token_source_tokenizer_get_token,
|
||||
gtk_css_token_source_tokenizer_error,
|
||||
};
|
||||
|
||||
GtkCssTokenSource *
|
||||
gtk_css_token_source_new_for_tokenizer (GtkCssTokenizer *tokenizer)
|
||||
{
|
||||
GtkCssTokenSourceTokenizer *source;
|
||||
|
||||
g_return_val_if_fail (tokenizer != NULL, NULL);
|
||||
|
||||
source = gtk_css_token_source_new (GtkCssTokenSourceTokenizer, >K_CSS_TOKEN_SOURCE_TOKENIZER);
|
||||
source->tokenizer = gtk_css_tokenizer_ref (tokenizer);
|
||||
|
||||
return &source->parent;
|
||||
}
|
||||
|
||||
typedef struct _GtkCssTokenSourcePart GtkCssTokenSourcePart;
|
||||
struct _GtkCssTokenSourcePart {
|
||||
GtkCssTokenSource parent;
|
||||
GtkCssTokenSource *source;
|
||||
GtkCssTokenType end_type;
|
||||
};
|
||||
|
||||
static void
|
||||
gtk_css_token_source_part_finalize (GtkCssTokenSource *source)
|
||||
{
|
||||
GtkCssTokenSourcePart *part = (GtkCssTokenSourcePart *) source;
|
||||
|
||||
gtk_css_token_source_unref (part->source);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_token_source_part_consume_token (GtkCssTokenSource *source)
|
||||
{
|
||||
GtkCssTokenSourcePart *part = (GtkCssTokenSourcePart *) source;
|
||||
const GtkCssToken *token;
|
||||
|
||||
if (!gtk_css_token_get_pending_block (source))
|
||||
{
|
||||
token = gtk_css_token_source_get_token (part->source);
|
||||
if (gtk_css_token_is (token, part->end_type))
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_css_token_source_consume_token (part->source);
|
||||
}
|
||||
|
||||
static const GtkCssToken *
|
||||
gtk_css_token_source_part_get_token (GtkCssTokenSource *source)
|
||||
{
|
||||
GtkCssTokenSourcePart *part = (GtkCssTokenSourcePart *) source;
|
||||
static const GtkCssToken eof_token = { GTK_CSS_TOKEN_EOF };
|
||||
const GtkCssToken *token;
|
||||
|
||||
token = gtk_css_token_source_get_token (part->source);
|
||||
if (!gtk_css_token_get_pending_block (source) &&
|
||||
gtk_css_token_is (token, part->end_type))
|
||||
return &eof_token;
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_token_source_part_error (GtkCssTokenSource *source,
|
||||
const GError *error)
|
||||
{
|
||||
GtkCssTokenSourcePart *part = (GtkCssTokenSourcePart *) source;
|
||||
|
||||
gtk_css_token_source_emit_error (part->source, error);
|
||||
}
|
||||
|
||||
const GtkCssTokenSourceClass GTK_CSS_TOKEN_SOURCE_PART = {
|
||||
gtk_css_token_source_part_finalize,
|
||||
gtk_css_token_source_part_consume_token,
|
||||
gtk_css_token_source_part_get_token,
|
||||
gtk_css_token_source_part_error,
|
||||
};
|
||||
|
||||
GtkCssTokenSource *
|
||||
gtk_css_token_source_new_for_part (GtkCssTokenSource *source,
|
||||
GtkCssTokenType end_type)
|
||||
{
|
||||
GtkCssTokenSourcePart *part;
|
||||
|
||||
g_return_val_if_fail (source != NULL, NULL);
|
||||
g_return_val_if_fail (end_type != GTK_CSS_TOKEN_EOF, NULL);
|
||||
|
||||
part = gtk_css_token_source_new (GtkCssTokenSourcePart, >K_CSS_TOKEN_SOURCE_PART);
|
||||
part->source = gtk_css_token_source_ref (source);
|
||||
part->end_type = end_type;
|
||||
|
||||
return &part->parent;
|
||||
}
|
||||
|
||||
GtkCssTokenSource *
|
||||
gtk_css_token_source_alloc (gsize struct_size,
|
||||
const GtkCssTokenSourceClass *klass)
|
||||
{
|
||||
GtkCssTokenSource *source;
|
||||
|
||||
source = g_malloc0 (struct_size);
|
||||
source->klass = klass;
|
||||
source->ref_count = 1;
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
GtkCssTokenSource *
|
||||
gtk_css_token_source_ref (GtkCssTokenSource *source)
|
||||
{
|
||||
source->ref_count++;
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_token_source_unref (GtkCssTokenSource *source)
|
||||
{
|
||||
source->ref_count--;
|
||||
if (source->ref_count > 0)
|
||||
return;
|
||||
|
||||
source->klass->finalize (source);
|
||||
|
||||
g_free (source);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gtk_css_token_source_consume_token (GtkCssTokenSource *source)
|
||||
{
|
||||
gtk_css_token_source_consume_token_as (source, source->consumer);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_token_source_consume_token_as (GtkCssTokenSource *source,
|
||||
GObject *consumer)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
|
||||
if (source->blocks)
|
||||
{
|
||||
token = gtk_css_token_source_get_token (source);
|
||||
if (gtk_css_token_is (token, GPOINTER_TO_UINT (source->blocks->data)))
|
||||
source->blocks = g_slist_remove (source->blocks, source->blocks->data);
|
||||
}
|
||||
|
||||
source->klass->consume_token (source);
|
||||
|
||||
token = gtk_css_token_source_get_token (source);
|
||||
switch (token->type)
|
||||
{
|
||||
case GTK_CSS_TOKEN_FUNCTION:
|
||||
case GTK_CSS_TOKEN_OPEN_PARENS:
|
||||
source->blocks = g_slist_prepend (source->blocks, GUINT_TO_POINTER (GTK_CSS_TOKEN_CLOSE_PARENS));
|
||||
break;
|
||||
case GTK_CSS_TOKEN_OPEN_SQUARE:
|
||||
source->blocks = g_slist_prepend (source->blocks, GUINT_TO_POINTER (GTK_CSS_TOKEN_CLOSE_SQUARE));
|
||||
break;
|
||||
case GTK_CSS_TOKEN_OPEN_CURLY:
|
||||
source->blocks = g_slist_prepend (source->blocks, GUINT_TO_POINTER (GTK_CSS_TOKEN_CLOSE_CURLY));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
source->klass->consume_token (source, consumer);
|
||||
|
||||
if (source->blocks)
|
||||
{
|
||||
if (token_type == GPOINTER_TO_UINT (source->blocks->data))
|
||||
source->blocks = g_slist_remove (source->blocks, source->blocks->data);
|
||||
}
|
||||
}
|
||||
|
||||
const GtkCssToken *
|
||||
gtk_css_token_source_get_token (GtkCssTokenSource *source)
|
||||
{
|
||||
return source->klass->get_token (source);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_token_source_consume_all (GtkCssTokenSource *source)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
|
||||
for (token = gtk_css_token_source_get_token (source);
|
||||
!gtk_css_token_is (token, GTK_CSS_TOKEN_EOF);
|
||||
token = gtk_css_token_source_get_token (source))
|
||||
{
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_css_token_source_consume_whitespace (GtkCssTokenSource *source)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
gboolean seen_whitespace = FALSE;
|
||||
|
||||
for (token = gtk_css_token_source_get_token (source);
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_WHITESPACE);
|
||||
token = gtk_css_token_source_get_token (source))
|
||||
{
|
||||
seen_whitespace = TRUE;
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
|
||||
return seen_whitespace;
|
||||
}
|
||||
|
||||
GtkCssTokenType
|
||||
gtk_css_token_get_pending_block (GtkCssTokenSource *source)
|
||||
{
|
||||
if (!source->blocks)
|
||||
return GTK_CSS_TOKEN_EOF;
|
||||
|
||||
return GPOINTER_TO_UINT(source->blocks->data);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_token_source_emit_error (GtkCssTokenSource *source,
|
||||
const GError *error)
|
||||
{
|
||||
source->klass->error (source, error);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_token_source_error (GtkCssTokenSource *source,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
GError *error;
|
||||
|
||||
va_start (args, format);
|
||||
error = g_error_new_valist (GTK_CSS_PROVIDER_ERROR,
|
||||
GTK_CSS_PROVIDER_ERROR_SYNTAX,
|
||||
format, args);
|
||||
gtk_css_token_source_emit_error (source, error);
|
||||
g_error_free (error);
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_token_source_unknown (GtkCssTokenSource *source,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
GError *error;
|
||||
|
||||
va_start (args, format);
|
||||
error = g_error_new_valist (GTK_CSS_PROVIDER_ERROR,
|
||||
GTK_CSS_PROVIDER_ERROR_UNKNOWN_VALUE,
|
||||
format, args);
|
||||
gtk_css_token_source_emit_error (source, error);
|
||||
g_error_free (error);
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_token_source_deprecated (GtkCssTokenSource *source,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
GError *error;
|
||||
|
||||
va_start (args, format);
|
||||
error = g_error_new_valist (GTK_CSS_PROVIDER_ERROR,
|
||||
GTK_CSS_PROVIDER_ERROR_DEPRECATED,
|
||||
format, args);
|
||||
gtk_css_token_source_emit_error (source, error);
|
||||
g_error_free (error);
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
81
gtk/gtkcsstokensourceprivate.h
Normal file
81
gtk/gtkcsstokensourceprivate.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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_TOKEN_SOURCE_PRIVATE_H__
|
||||
#define __GTK_CSS_TOKEN_SOURCE_PRIVATE_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include "gtk/gtkcsstokenizerprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkCssTokenSource GtkCssTokenSource;
|
||||
typedef struct _GtkCssTokenSourceClass GtkCssTokenSourceClass;
|
||||
|
||||
struct _GtkCssTokenSource
|
||||
{
|
||||
const GtkCssTokenSourceClass *klass;
|
||||
gint ref_count;
|
||||
GSList *blocks; /* of GPOINTER_TO_UINT(GtkCssTokenType) */
|
||||
};
|
||||
|
||||
struct _GtkCssTokenSourceClass
|
||||
{
|
||||
void (* finalize) (GtkCssTokenSource *source);
|
||||
void (* consume_token) (GtkCssTokenSource *source);
|
||||
const GtkCssToken * (* get_token) (GtkCssTokenSource *source);
|
||||
void (* error) (GtkCssTokenSource *source,
|
||||
const GError *error);
|
||||
};
|
||||
|
||||
GtkCssTokenSource * gtk_css_token_source_new_for_tokenizer (GtkCssTokenizer *tokenizer);
|
||||
GtkCssTokenSource * gtk_css_token_source_new_for_part (GtkCssTokenSource *source,
|
||||
GtkCssTokenType end_type);
|
||||
|
||||
GtkCssTokenSource * gtk_css_token_source_ref (GtkCssTokenSource *source);
|
||||
void gtk_css_token_source_unref (GtkCssTokenSource *source);
|
||||
|
||||
#define gtk_css_token_source_new(type,klass) ((type *) gtk_css_token_source_alloc (sizeof (type), (klass)))
|
||||
GtkCssTokenSource * gtk_css_token_source_alloc (gsize struct_size,
|
||||
const GtkCssTokenSourceClass *klass);
|
||||
|
||||
void gtk_css_token_source_consume_token (GtkCssTokenSource *source);
|
||||
const GtkCssToken * gtk_css_token_source_get_token (GtkCssTokenSource *source);
|
||||
|
||||
GtkCssTokenType gtk_css_token_get_pending_block (GtkCssTokenSource *source);
|
||||
|
||||
void gtk_css_token_source_consume_all (GtkCssTokenSource *source);
|
||||
gboolean gtk_css_token_source_consume_whitespace (GtkCssTokenSource *source);
|
||||
|
||||
void gtk_css_token_source_emit_error (GtkCssTokenSource *source,
|
||||
const GError *error);
|
||||
void gtk_css_token_source_error (GtkCssTokenSource *source,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF(2, 3);
|
||||
void gtk_css_token_source_unknown (GtkCssTokenSource *source,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF(2, 3);
|
||||
void gtk_css_token_source_deprecated (GtkCssTokenSource *source,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF(2, 3);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_TOKEN_SOURCE_PRIVATE_H__ */
|
||||
Reference in New Issue
Block a user