css: Add gtk_style_property_token_parse()
Slowly move the token parser into CSS value parsing.
This commit is contained in:
@@ -43,6 +43,14 @@ gtk_css_custom_property_parse_value (GtkStyleProperty *property,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_custom_property_token_parse (GtkStyleProperty *property,
|
||||
GtkCssTokenSource *source)
|
||||
{
|
||||
gtk_css_token_source_unknown (source, "Custom CSS properties are no longer supported.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_custom_property_query (GtkStyleProperty *property,
|
||||
GValue *value,
|
||||
@@ -81,6 +89,7 @@ _gtk_css_custom_property_class_init (GtkCssCustomPropertyClass *klass)
|
||||
GtkStylePropertyClass *property_class = GTK_STYLE_PROPERTY_CLASS (klass);
|
||||
|
||||
property_class->parse_value = gtk_css_custom_property_parse_value;
|
||||
property_class->token_parse = gtk_css_custom_property_token_parse;
|
||||
property_class->query = gtk_css_custom_property_query;
|
||||
property_class->assign = gtk_css_custom_property_assign;
|
||||
}
|
||||
|
||||
@@ -26,9 +26,8 @@
|
||||
typedef struct _GtkCssDeclarationPrivate GtkCssDeclarationPrivate;
|
||||
struct _GtkCssDeclarationPrivate {
|
||||
GtkCssStyleDeclaration *style;
|
||||
char *name;
|
||||
GtkStyleProperty *prop;
|
||||
char *value;
|
||||
GtkCssValue *value;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkCssDeclaration, gtk_css_declaration, G_TYPE_OBJECT)
|
||||
@@ -39,8 +38,8 @@ gtk_css_declaration_finalize (GObject *object)
|
||||
GtkCssDeclaration *declaration = GTK_CSS_DECLARATION (object);
|
||||
GtkCssDeclarationPrivate *priv = gtk_css_declaration_get_instance_private (declaration);
|
||||
|
||||
g_free (priv->name);
|
||||
g_free (priv->value);
|
||||
if (priv->value)
|
||||
_gtk_css_value_unref (priv->value);
|
||||
|
||||
G_OBJECT_CLASS (gtk_css_declaration_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -58,24 +57,6 @@ gtk_css_declaration_init (GtkCssDeclaration *declaration)
|
||||
{
|
||||
}
|
||||
|
||||
GtkCssDeclaration *
|
||||
gtk_css_declaration_new (GtkCssStyleDeclaration *style,
|
||||
const char *name,
|
||||
const char *value)
|
||||
{
|
||||
GtkCssDeclarationPrivate *priv;
|
||||
GtkCssDeclaration *result;
|
||||
|
||||
result = g_object_new (GTK_TYPE_CSS_DECLARATION, NULL);
|
||||
priv = gtk_css_declaration_get_instance_private (result);
|
||||
|
||||
priv->style = style;
|
||||
priv->name = g_strdup (name);
|
||||
priv->value = g_strdup (value);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GtkCssDeclaration *
|
||||
gtk_css_declaration_new_parse (GtkCssStyleDeclaration *style,
|
||||
GtkCssTokenSource *source)
|
||||
@@ -83,6 +64,7 @@ gtk_css_declaration_new_parse (GtkCssStyleDeclaration *style,
|
||||
GtkCssDeclarationPrivate *priv;
|
||||
const GtkCssToken *token;
|
||||
GtkCssDeclaration *decl;
|
||||
char *name;
|
||||
|
||||
decl = g_object_new (GTK_TYPE_CSS_DECLARATION, NULL);
|
||||
priv = gtk_css_declaration_get_instance_private (decl);
|
||||
@@ -99,25 +81,40 @@ gtk_css_declaration_new_parse (GtkCssStyleDeclaration *style,
|
||||
g_object_unref (decl);
|
||||
return NULL;
|
||||
}
|
||||
priv->name = g_strdup (token->string.string);
|
||||
priv->prop = _gtk_style_property_lookup (priv->name);
|
||||
name = g_utf8_strdown (token->string.string, -1);
|
||||
priv->prop = _gtk_style_property_lookup (name);
|
||||
if (priv->prop == NULL)
|
||||
gtk_css_token_source_unknown (source, "Unknown property name '%s'", priv->name);
|
||||
else if (!g_str_equal (priv->name, _gtk_style_property_get_name (priv->prop)))
|
||||
{
|
||||
gtk_css_token_source_unknown (source, "Unknown property name '%s'", token->string.string);
|
||||
gtk_css_token_source_consume_all (source);
|
||||
g_object_unref (decl);
|
||||
g_free (name);
|
||||
return NULL;
|
||||
}
|
||||
else if (!g_str_equal (name, _gtk_style_property_get_name (priv->prop)))
|
||||
gtk_css_token_source_deprecated (source,
|
||||
"The '%s' property has been renamed to '%s'",
|
||||
priv->name, _gtk_style_property_get_name (priv->prop));
|
||||
name, _gtk_style_property_get_name (priv->prop));
|
||||
gtk_css_token_source_consume_token (source);
|
||||
gtk_css_token_source_consume_whitespace (source);
|
||||
g_free (name);
|
||||
|
||||
token = gtk_css_token_source_get_token (source);
|
||||
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_COLON))
|
||||
{
|
||||
gtk_css_token_source_error (source, "No colon following property name");
|
||||
gtk_css_token_source_consume_all (source);
|
||||
g_object_unref (decl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
priv->value = gtk_css_token_source_consume_to_string (source);
|
||||
gtk_css_token_source_consume_token (source);
|
||||
|
||||
priv->value = gtk_style_property_token_parse (priv->prop, source);
|
||||
if (priv->value == NULL)
|
||||
{
|
||||
g_object_unref (decl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
@@ -75,6 +75,7 @@ do_the_tokenizer (const char *data)
|
||||
|
||||
gtk_css_tokenizer_unref (tokenizer);
|
||||
#else
|
||||
#if 0
|
||||
GtkCssStyleSheet *sheet;
|
||||
GtkCssTokenSource *source;
|
||||
GtkCssTokenizer *tokenizer;
|
||||
@@ -91,6 +92,7 @@ do_the_tokenizer (const char *data)
|
||||
gtk_css_tokenizer_unref (tokenizer);
|
||||
g_bytes_unref (bytes);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
GtkCssParser *
|
||||
|
||||
@@ -156,6 +156,112 @@ gtk_css_shorthand_property_parse_value (GtkStyleProperty *property,
|
||||
return result;
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_shorthand_property_token_parse (GtkStyleProperty *property,
|
||||
GtkCssTokenSource *source)
|
||||
{
|
||||
GtkCssShorthandProperty *shorthand = GTK_CSS_SHORTHAND_PROPERTY (property);
|
||||
const GtkCssToken *token;
|
||||
GtkCssValue **data;
|
||||
GtkCssValue *result;
|
||||
guint i;
|
||||
|
||||
data = g_new0 (GtkCssValue *, shorthand->subproperties->len);
|
||||
|
||||
token = gtk_css_token_source_get_token (source);
|
||||
if (gtk_css_token_is_ident (token, "initial"))
|
||||
{
|
||||
/* the initial value can be explicitly specified with the
|
||||
* ‘initial’ keyword which all properties accept.
|
||||
*/
|
||||
for (i = 0; i < shorthand->subproperties->len; i++)
|
||||
{
|
||||
data[i] = _gtk_css_initial_value_new ();
|
||||
}
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "inherit"))
|
||||
{
|
||||
/* All properties accept the ‘inherit’ value which
|
||||
* explicitly specifies that the value will be determined
|
||||
* by inheritance. The ‘inherit’ value can be used to
|
||||
* strengthen inherited values in the cascade, and it can
|
||||
* also be used on properties that are not normally inherited.
|
||||
*/
|
||||
for (i = 0; i < shorthand->subproperties->len; i++)
|
||||
{
|
||||
data[i] = _gtk_css_inherit_value_new ();
|
||||
}
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "unset"))
|
||||
{
|
||||
/* If the cascaded value of a property is the unset keyword,
|
||||
* then if it is an inherited property, this is treated as
|
||||
* inherit, and if it is not, this is treated as initial.
|
||||
*/
|
||||
for (i = 0; i < shorthand->subproperties->len; i++)
|
||||
{
|
||||
data[i] = _gtk_css_unset_value_new ();
|
||||
}
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else if (!shorthand->token_parse (shorthand, data, source))
|
||||
{
|
||||
for (i = 0; i < shorthand->subproperties->len; i++)
|
||||
{
|
||||
if (data[i] != NULL)
|
||||
_gtk_css_value_unref (data[i]);
|
||||
}
|
||||
g_free (data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* All values that aren't set by the parse func are set to their
|
||||
* default values here.
|
||||
* XXX: Is the default always initial or can it be inherit? */
|
||||
for (i = 0; i < shorthand->subproperties->len; i++)
|
||||
{
|
||||
if (data[i] == NULL)
|
||||
data[i] = _gtk_css_initial_value_new ();
|
||||
}
|
||||
|
||||
result = _gtk_css_array_value_new_from_array (data, shorthand->subproperties->len);
|
||||
g_free (data);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
forward_error_to_source (GtkCssParser *parser,
|
||||
const GError *error,
|
||||
gpointer source)
|
||||
{
|
||||
/* XXX: This is bad because it doesn't emit the error on the right token */
|
||||
gtk_css_token_source_emit_error (source, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_shorthand_token_parse_default (GtkCssShorthandProperty *shorthand,
|
||||
GtkCssValue **values,
|
||||
GtkCssTokenSource *source)
|
||||
{
|
||||
GtkCssParser *parser;
|
||||
char *str;
|
||||
gboolean result;
|
||||
|
||||
str = gtk_css_token_source_consume_to_string (source);
|
||||
parser = _gtk_css_parser_new (str,
|
||||
NULL,
|
||||
forward_error_to_source,
|
||||
source);
|
||||
result = shorthand->parse (shorthand, values, parser);
|
||||
_gtk_css_parser_free (parser);
|
||||
g_free (str);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_css_shorthand_property_class_init (GtkCssShorthandPropertyClass *klass)
|
||||
{
|
||||
@@ -175,12 +281,15 @@ _gtk_css_shorthand_property_class_init (GtkCssShorthandPropertyClass *klass)
|
||||
property_class->assign = _gtk_css_shorthand_property_assign;
|
||||
property_class->query = _gtk_css_shorthand_property_query;
|
||||
property_class->parse_value = gtk_css_shorthand_property_parse_value;
|
||||
property_class->token_parse = gtk_css_shorthand_property_token_parse;
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_css_shorthand_property_init (GtkCssShorthandProperty *shorthand)
|
||||
{
|
||||
shorthand->subproperties = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
|
||||
shorthand->token_parse = gtk_css_shorthand_token_parse_default;
|
||||
}
|
||||
|
||||
GtkCssStyleProperty *
|
||||
|
||||
@@ -41,6 +41,9 @@ typedef struct _GtkCssShorthandPropertyClass GtkCssShorthandPropertyClass;
|
||||
typedef gboolean (* GtkCssShorthandPropertyParseFunc) (GtkCssShorthandProperty *shorthand,
|
||||
GtkCssValue **values,
|
||||
GtkCssParser *parser);
|
||||
typedef gboolean (* GtkCssShorthandPropertyTokenParseFunc) (GtkCssShorthandProperty *shorthand,
|
||||
GtkCssValue **values,
|
||||
GtkCssTokenSource *source);
|
||||
typedef void (* GtkCssShorthandPropertyAssignFunc) (GtkCssShorthandProperty *shorthand,
|
||||
GtkStyleProperties *props,
|
||||
GtkStateFlags state,
|
||||
@@ -57,6 +60,7 @@ struct _GtkCssShorthandProperty
|
||||
GPtrArray *subproperties;
|
||||
|
||||
GtkCssShorthandPropertyParseFunc parse;
|
||||
GtkCssShorthandPropertyTokenParseFunc token_parse;
|
||||
GtkCssShorthandPropertyAssignFunc assign;
|
||||
GtkCssShorthandPropertyQueryFunc query;
|
||||
};
|
||||
|
||||
@@ -192,6 +192,80 @@ gtk_css_style_property_parse_value (GtkStyleProperty *property,
|
||||
return (* style_property->parse_value) (style_property, parser);
|
||||
}
|
||||
|
||||
static void
|
||||
forward_error_to_source (GtkCssParser *parser,
|
||||
const GError *error,
|
||||
gpointer source)
|
||||
{
|
||||
/* XXX: This is bad because it doesn't emit the error on the right token */
|
||||
gtk_css_token_source_emit_error (source, error);
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_style_property_token_parse_default (GtkCssStyleProperty *property,
|
||||
GtkCssTokenSource *source)
|
||||
{
|
||||
GtkCssParser *parser;
|
||||
GtkCssValue *value;
|
||||
char *str;
|
||||
|
||||
str = gtk_css_token_source_consume_to_string (source);
|
||||
parser = _gtk_css_parser_new (str,
|
||||
NULL,
|
||||
forward_error_to_source,
|
||||
source);
|
||||
value = property->parse_value (property, parser);
|
||||
_gtk_css_parser_free (parser);
|
||||
g_free (str);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_style_property_token_parse (GtkStyleProperty *property,
|
||||
GtkCssTokenSource *source)
|
||||
{
|
||||
GtkCssStyleProperty *style_property = GTK_CSS_STYLE_PROPERTY (property);
|
||||
const GtkCssToken *token;
|
||||
GtkCssValue *value;
|
||||
|
||||
token = gtk_css_token_source_get_token (source);
|
||||
if (gtk_css_token_is_ident (token, "initial"))
|
||||
{
|
||||
/* the initial value can be explicitly specified with the
|
||||
* ‘initial’ keyword which all properties accept.
|
||||
*/
|
||||
value = _gtk_css_initial_value_new ();
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "inherit"))
|
||||
{
|
||||
/* All properties accept the ‘inherit’ value which
|
||||
* explicitly specifies that the value will be determined
|
||||
* by inheritance. The ‘inherit’ value can be used to
|
||||
* strengthen inherited values in the cascade, and it can
|
||||
* also be used on properties that are not normally inherited.
|
||||
*/
|
||||
value = _gtk_css_inherit_value_new ();
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "unset"))
|
||||
{
|
||||
/* If the cascaded value of a property is the unset keyword,
|
||||
* then if it is an inherited property, this is treated as
|
||||
* inherit, and if it is not, this is treated as initial.
|
||||
*/
|
||||
value = _gtk_css_unset_value_new ();
|
||||
gtk_css_token_source_consume_token (source);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = (* style_property->token_parse) (style_property, source);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_css_style_property_class_init (GtkCssStylePropertyClass *klass)
|
||||
{
|
||||
@@ -242,6 +316,7 @@ _gtk_css_style_property_class_init (GtkCssStylePropertyClass *klass)
|
||||
property_class->assign = _gtk_css_style_property_assign;
|
||||
property_class->query = _gtk_css_style_property_query;
|
||||
property_class->parse_value = gtk_css_style_property_parse_value;
|
||||
property_class->token_parse = gtk_css_style_property_token_parse;
|
||||
|
||||
klass->style_properties = g_ptr_array_new ();
|
||||
|
||||
@@ -260,6 +335,7 @@ static void
|
||||
_gtk_css_style_property_init (GtkCssStyleProperty *property)
|
||||
{
|
||||
property->parse_value = gtk_css_style_property_real_parse_value;
|
||||
property->token_parse = gtk_css_style_property_token_parse_default;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,13 +34,15 @@ G_BEGIN_DECLS
|
||||
typedef struct _GtkCssStyleProperty GtkCssStyleProperty;
|
||||
typedef struct _GtkCssStylePropertyClass GtkCssStylePropertyClass;
|
||||
|
||||
typedef GtkCssValue * (* GtkCssStylePropertyParseFunc) (GtkCssStyleProperty *property,
|
||||
GtkCssParser *parser);
|
||||
typedef void (* GtkCssStylePropertyQueryFunc) (GtkCssStyleProperty *property,
|
||||
const GtkCssValue *cssvalue,
|
||||
GValue *value);
|
||||
typedef GtkCssValue * (* GtkCssStylePropertyAssignFunc) (GtkCssStyleProperty *property,
|
||||
const GValue *value);
|
||||
typedef GtkCssValue * (* GtkCssStylePropertyParseFunc) (GtkCssStyleProperty *property,
|
||||
GtkCssParser *parser);
|
||||
typedef GtkCssValue * (* GtkCssStylePropertyTokenParseFunc) (GtkCssStyleProperty *property,
|
||||
GtkCssTokenSource *source);
|
||||
typedef void (* GtkCssStylePropertyQueryFunc) (GtkCssStyleProperty *property,
|
||||
const GtkCssValue *cssvalue,
|
||||
GValue *value);
|
||||
typedef GtkCssValue * (* GtkCssStylePropertyAssignFunc) (GtkCssStyleProperty *property,
|
||||
const GValue *value);
|
||||
struct _GtkCssStyleProperty
|
||||
{
|
||||
GtkStyleProperty parent;
|
||||
@@ -52,6 +54,7 @@ struct _GtkCssStyleProperty
|
||||
guint animated :1;
|
||||
|
||||
GtkCssStylePropertyParseFunc parse_value;
|
||||
GtkCssStylePropertyTokenParseFunc token_parse;
|
||||
GtkCssStylePropertyQueryFunc query_value;
|
||||
GtkCssStylePropertyAssignFunc assign_value;
|
||||
};
|
||||
|
||||
@@ -158,6 +158,56 @@ _gtk_style_property_parse_value (GtkStyleProperty *property,
|
||||
return klass->parse_value (property, parser);
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_style_property_parse_value:
|
||||
* @property: the property
|
||||
* @parser: the parser to parse from
|
||||
*
|
||||
* Tries to parse the given @property from the given @parser into
|
||||
* @value. The type that @value will be assigned is dependant on
|
||||
* the parser and no assumptions must be made about it. If the
|
||||
* parsing fails, %FALSE will be returned and @value will be
|
||||
* left uninitialized.
|
||||
*
|
||||
* Only if @property is a #GtkCssShorthandProperty, the @value will
|
||||
* always be a #GtkCssValue whose values can be queried with
|
||||
* _gtk_css_array_value_get_nth().
|
||||
*
|
||||
* Returns: %NULL on failure or the parsed #GtkCssValue
|
||||
**/
|
||||
GtkCssValue *
|
||||
gtk_style_property_token_parse (GtkStyleProperty *property,
|
||||
GtkCssTokenSource *source)
|
||||
{
|
||||
GtkStylePropertyClass *klass;
|
||||
GtkCssValue *value;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_STYLE_PROPERTY (property), NULL);
|
||||
g_return_val_if_fail (source != NULL, NULL);
|
||||
|
||||
klass = GTK_STYLE_PROPERTY_GET_CLASS (property);
|
||||
|
||||
gtk_css_token_source_consume_whitespace (source);
|
||||
|
||||
value = klass->token_parse (property, source);
|
||||
|
||||
if (value == NULL)
|
||||
return NULL;
|
||||
|
||||
gtk_css_token_source_consume_whitespace (source);
|
||||
|
||||
if (!gtk_css_token_is (gtk_css_token_source_get_token (source),
|
||||
GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
gtk_css_token_source_error (source, "Junk at end of value");
|
||||
gtk_css_token_source_consume_all (source);
|
||||
_gtk_css_value_unref (value);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_style_property_assign:
|
||||
* @property: the property
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define __GTK_STYLEPROPERTY_PRIVATE_H__
|
||||
|
||||
#include "gtkcssparserprivate.h"
|
||||
#include "gtkcsstokensourceprivate.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
#include "gtkcssvalueprivate.h"
|
||||
|
||||
@@ -57,8 +58,10 @@ struct _GtkStylePropertyClass
|
||||
GValue *value,
|
||||
GtkStyleQueryFunc query_func,
|
||||
gpointer query_data);
|
||||
GtkCssValue * (* parse_value) (GtkStyleProperty * property,
|
||||
GtkCssValue * (* parse_value) (GtkStyleProperty *property,
|
||||
GtkCssParser *parser);
|
||||
GtkCssValue * (* token_parse) (GtkStyleProperty *property,
|
||||
GtkCssTokenSource *source);
|
||||
|
||||
GHashTable *properties;
|
||||
};
|
||||
@@ -76,6 +79,8 @@ const char * _gtk_style_property_get_name (GtkStyleProperty
|
||||
|
||||
GtkCssValue * _gtk_style_property_parse_value (GtkStyleProperty * property,
|
||||
GtkCssParser *parser);
|
||||
GtkCssValue * gtk_style_property_token_parse (GtkStyleProperty *property,
|
||||
GtkCssTokenSource *source);
|
||||
|
||||
GType _gtk_style_property_get_value_type(GtkStyleProperty * property);
|
||||
void _gtk_style_property_query (GtkStyleProperty * property,
|
||||
|
||||
Reference in New Issue
Block a user